Home > pic18f, Uncategorized > pic18f assembly example 4 – sample Analog Channel on timer interrupt

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

;    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
;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 
    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
    BSF LATD, 2
    goto main_loop
    BCF LATD, 2
    goto main_loop   

    ;-------configure pins, ADC,timers and interrupts on the pic18f4620    -----------------------------------
    ; 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 
    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
    goto adc_not_ready
    retfie ;return and reset interrupts

    ;-----Low Priority Interrupt Service Routine  -------------------------------------------------------------
    org 0x0300 
    retfie ;return and reset interrupts

    end ; End of ASM code
Categories: pic18f, Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: