CBC-USNA-T77 shares this code
;********************************************************************** ; This program for the PIC16F874 solves the following program specification: ; 1. Have the processor generate an interrupt every 1 ms. ; 2. Toggle Port A <4> every 500 ms. ;********************************************************************** ; * ; Filename: easysamp.asm * ; Date: 06 March 2001 * ; File Version: 1 * ; * ; Author: CDR Charles B. Cameron, USN * ; Company: United States Naval Academy * ; * ; * ;********************************************************************** ; * ; Files required: * ; * ; p16f874.inc * ; * ;********************************************************************** ; * ; Notes: ; This program generates an interrupt every 1 ms. Upon interrupt ; it updates a counter. ; PORTA<4> is an output pin. It is toggled every 500 ms. ; ; It's assumed the processor is driven with a 4.000 MHz crystal ; oscillator and is to operate in HS mode. ;********************************************************************** list p=16f874 ; list directive to define processor #include <p16f874.inc> ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The labels following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ; The particular choice given above turns code protection off, watch dog timer off, ; brown-out reset disabled, power-up timer enabled, HS oscillator mode selected, ; flash program memory write disabled, low-voltage in-circuit serial programming ; disabled, and data EE memory code protrection off. Change these at will! ;***** VARIABLE DEFINITIONS w_temp EQU 0x20 ; variable used for context saving status_temp EQU 0x21 ; variable used for context saving cblock 0x22 ; define a series of variables. count1 ; The MSB of a 2-byte register counting ; the number of Timer 2 interrupts ; which have occurred. count0 ; The LSB of the same 2-byte register. flag500ms ; Contains a 0 unless 500 1-ms Timer 2 ; interrupts have been processed. endc ; Bits within PORTA ToggleBit equ 4 ; An output bit, toggled every 500 ms. PortAMask equ B'00000000' ; We'll make all of PORT A an output. ;********************************************************************** ORG 0x000 ; processor reset vector clrf PCLATH ; ensure page 0 is used goto main ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents swapf STATUS,W ; move status register into W register clrf STATUS ; select Bank 0 movwf status_temp ; save off contents of STATUS register ; There's no need to save PCLATH since ; we'll stick to Bank 0 of program memory. ; isr code can go here or be located as a call subroutine elsewhere btfsc PIR1,TMR2IF ; If Timer 2 caused the interrupt, handle it. call Timer2 swapf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ; ********************************************* ; Timer 2 Interrupt handler. ; Timer 2 has overflowed ; Timer2 ; Increment the LSB of the 1-ms counter. incf count0,F ; If it rolls over, increment the MSB. btfsc STATUS,Z incf count1,F ; See if the count has reached 500. ; If so, set the toggle flag for the main processor ; to take action. movlw 1 ; Is the MSB of the count 1? subwf count1,W btfss STATUS,Z ; If count1 is not 1, we haven't reached 500. goto EndTimer2Interrupt ; Is the LSB = 500 - 256 = 244? movlw D'500' - D'256' subwf count0,W btfss STATUS,Z ; If not, we still haven't reached 500. goto EndTimer2Interrupt ; If we get here, it's because we have processed 500 1-ms Timer 2 Interrupts. ; Set the flag500ms variable to a non-zero value. movlw H'FF' movwf flag500ms ; Reinitialize count1 and count0 clrf count1 clrf count0 EndTimer2Interrupt BCF PIR1,TMR2IF ; Clear flag and continue. return main ; *********************************************************************************** ; START OF CODE to initialize the processor ; The initialization code goes here since we'll end up here shortly after a reset. ; *********************************************************************************** ; *********************************************************************************** ; Most Bank 0 initializations are done here and they come first. ; *********************************************************************************** bcf STATUS,RP0 ; Select Bank 0 bcf STATUS,RP1 clrf PORTA ; Initialize Port A by clearing the output latches. clrf count1 ; Re-initialize count1 and count0. clrf count0 clrf flag500ms ; Turn off the flag which, when set, says 500 ms has elapsed. ; *********************************************************************************** ; Most Bank 1 initializations come next. ; *********************************************************************************** bsf STATUS,RP0 ; Select Bank 1 movlw PortAMask ; Initialize direction pins for Port A using TRISA. movwf TRISA movlw B'00000110' ; Don't use any pins of Port A for A/D conversions movwf ADCON1 bcf STATUS,RP0 ; Revert to Bank 0 ; *********************************************************************************** ; START OF CODE to initialize Timer 2 ; These come next only because it's convenient to group them together, not because ; it's a necessity. ; Set up Timer 2 to generate interrupts every 1 ms. Since we're assuming an instruction ; cycle consumes 1 us, we need to cause an interrupt every 1000 instruction cycles. ; We'll set the prescaler to 4, the PR2 register to 25, and the postscaler to 10. This ; will generate interrupts every 4 x 25 x 10 = 1000 instruction cycles. ; *********************************************************************************** CLRF TMR2 ; Clear Timer2 register BSF STATUS, RP0 ; Bank1 bsf INTCON,PEIE ; Enable peripheral interrupts CLRF PIE1 ; Mask all peripheral interrupts except bsf PIE1,TMR2IE ; the timer 2 interrupts. BCF STATUS, RP0 ; Bank0 CLRF PIR1 ; Clear peripheral interrupts Flags movlw B'01001001' ; Set Postscale = 10, Prescale = 4, Timer 2 = off. movwf T2CON BSF STATUS, RP0 ; Bank1 movlw D'25'-1 ; Set the PR2 register for Timer 2 to divide by 25. movwf PR2 BCF STATUS, RP0 ; Bank0 bsf INTCON,GIE ; Global interrupt enable. BSF T2CON,TMR2ON ; Timer2 starts to increment ; *********************************************************************************** ; END OF CODE to initialize Timer 2 ; *********************************************************************************** ; *********************************************************************************** ; main() ; This is the main program. It does only one thing: check to see if it's time to ; toggle PORTA<togglebit> and do so if it is time. Otherwise it's busily engaged ; in using up all the instruction cycles not required by the interrupt handlers. loop movf flag500ms,W ; Has the flag500ms been set? btfsc STATUS,Z goto loop ; Not yet. Keep looking. ; Yes, it's time to toggle PORTA<ToggleBit> and reset flag500ms. movlw ToggleBit xorwf PORTA,f clrf flag500ms goto loop ; Now wait for the next occurence. ; *********************************************************************************** END ; directive 'end of program''
Questions:
file: /Techref/microchip/intsample.htm, 10KB, , updated: 2007/11/10 18:39, local time: 2024/12/25 09:11,
3.149.242.223:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/Techref/microchip/intsample.htm"> Easy Interrupt sample</A> |
Did you find what you needed? |