pic18f assembly example 4 – sample Analog Channel on timer interrupt
;------------------------------------------------------------------------------------------------------------------------------; This assembly code sets up a timer interrupt to be triggered every millisecond on the pic18f4620. ; This assembly code uses a timer interrupt to read an analog channel every 1ms. ; When the interrupt service routine is called an ADC on channel 0 is performed. ; In the main part of the code the value associated with analog channel 0 is monitored in a continuous loop. If the value ; is high then LATD2 is set high otherwise LATD2 is set low ; ; by David Dorran (https://dadorran.wordpress.com) May 2014 ;------------------------------------------------------------------------------------------------------------------------------ ; TRY TO DO THE FOLLOWING IN ORDER TO DEVELOP YOUR PROGRAMMING SKILLS: ; 1. Change the sampling rate from 1kHz to 1Hz ;configure the assembler directive 'list' so as to set processor to 18f4620 and set the radix used for data expressions to decimal (can be HEX|DEC|OCT) list p=18f4620, r=DEC #include <p18f4620.inc> ; configure the micro so that the watchdog timer is off, low-voltage programming is off, master clear is off and the clock works off the internal oscillator config WDT=OFF, LVP=OFF, MCLRE=OFF, OSC=INTIO67 ;The org directive tells the compiler where to position the code in memory org 0x0000 ;The following code will be programmed in reset address location i.e. The micro jumps to 0x0000 on a reset goto Main ;Jump to Main immediately after a reset ;NOTE: When an interrupt is triggered the micro jumps to 0x0008 for high priority and 0x0018 for low priority. org 0x0008 goto hi_isr ;once an high priority interrupt is triggered jump to hi_isr org 0x0018 goto low_isr ;once an low priority interrupt is triggered jump to low_isr ;-------------------------------------------------------------------------- ; Main Program ------------------------------------------------------------- ;-------------------------------------------------------------------------- org 0x0100 Main goto pin_config ; configure the timers, ADC, IO pins, interrupts etc. main_loop ; This loop runs forever waiting for interrupts to be triggered ; if the analog input is greater than Vss/2 then turn on LATD2 else turn it off BTFSC ADRESH, 7 ; ADRESH stores the 8 most significant bits after a 10 bit ADC conversion. Just check the most significant bit to see if the value is 'large' or 'small' goto set_LATD2 goto reset_LATD2 set_LATD2 BSF LATD, 2 goto main_loop reset_LATD2 BCF LATD, 2 goto main_loop ;---------------------------------------------------------------------------------------------------------- ;-------configure pins, ADC,timers and interrupts on the pic18f4620 ----------------------------------- ;---------------------------------------------------------------------------------------------------------- pin_config ; configure LATD0-LATD3 as outputs and RD4-RD7 as inputs movlw 0xf0 movwf TRISD clrf LATD ; turn off all LATD output pins BSF LATD,1 ; turn on LATD1 ; Set clock frequency (section 2 of the PIC18F4620 Data Sheet) ; Set Fosc = 8MHz, which gives Tcy = 0.5us movlw B'01110000' movwf OSCCON ; all channels set up for ADC - no particular reason why movlw B'00000001' movwf ADCON1 ; set tad so that capacitor on ADC can fully charge - see pg129 movlw B'00100010' movwf ADCON2 clrf ADCON0; select analog channel 0; BSF ADCON0,ADON; //enable ADC BCF INTCON, GIE ;Disable global interrupts BCF T0CON, TMR0ON; turn off timer 0 BSF INTCON, TMR0IE; Enable TIMER0 interupt ;set up 1:2 prescaler so that TMR0 SFR is incremented every 2 Tcy i.e. 1us BCF T0CON,0 BCF T0CON,1 bCF T0CON,2 BCF T0CON, T0CS; use internal instruction cycle clock BCF T0CON, T08BIT; use 16 bit mode BCF T0CON, PSA; turn on prescaler ; setup so that timer0 overflow is triggered quickly ; after the first trigger then set it up so that it is triggered at the rate you want movlw 0xFF movwf TMR0L movlw 0xFF movwf TMR0H BSF INTCON2, TMR0IP; ; Set the timer0 interrupt up as high priority BSF INTCON, GIE ;Enable global interrupts BSF T0CON, TMR0ON; turn on timer 0 goto main_loop ;---------------------------------------------------------------------------------------------------------- ;-----High Priority Interrupt Service Routine ------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- org 0x0200 hi_isr BTFSS INTCON, TMR0IF goto end_int BCF INTCON, TMR0IF; reset interrupt ;An interrupt has been set up to be generated whenever TMR0 goes from FFFFh to 0000h i.e. on overflow. ;Would like the timer overflow flag triggered every 1ms so will set timer to 0xffff - 1000 = 0xFC17 movlw 0x17 movwf TMR0L movlw 0xFC movwf TMR0H BSF ADCON0,GO; start ADC conversion ; wait for hardware to reset GO bit - indicating ADRES SFR is ready to read adc_not_ready BTFSC ADCON0, GO goto adc_not_ready end_int retfie ;return and reset interrupts ;---------------------------------------------------------------------------------------------------------- ;-----Low Priority Interrupt Service Routine ------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- org 0x0300 low_isr nop retfie ;return and reset interrupts end ; End of ASM code
Categories: pic18f, Uncategorized
Comments (0)
Trackbacks (0)
Leave a comment
Trackback