pic18f assembly example 5 – Sample ADC and pass through to DAC
;----------------------------------------------------------------------------------------------------------------------------- ; This assembly code sets up a timer interrupt to be triggered every millisecond on the pic18f4620. ; When the interrupt service routine is called an ADC on channel 0 is performed and this value is sent a DAC (MCP4921) via a SPI protocol. ; ; Test cicruit used is same as at http://eleceng.dit.ie/daq_lite/build.html ; ; 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 ;----------------------------------------------------------------------------------------------------------------------------- ;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) ;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. This is where the micro jumps to on 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 a high priority interrupt is triggered jump to hi_isr org 0x0018 goto low_isr ;once a low priority interrupt is triggered jump to low_isr ;-------------------------------------------------------------------------- ; Main Program ------------------------------------------------------------- ;-------------------------------------------------------------------------- org 0x0100 ; the following code is placed at address 0x0100 in program memory (Flash memory) Main y equ 0x20 ; y refers to a register at address 0x20 call micro_config ; configure pins,timers, ADC etc. main_loop nop ; Just wait for a timer interrupt to be triggered 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 movff ADRESH, y goto spi_write ;write contents of y to SPI device end_int retfie ;return and reset interrupts ;---------------------------------------------------------------------------------------------------------- ;-------configure pins, ADC,timers and interrupts on the pic18f4620 ----------------------------------- ;---------------------------------------------------------------------------------------------------------- micro_config ; configure LATD0-LATD3 as outputs and RD4-RD7 as inputs movlw 0xf0 movwf TRISD clrf LATD ; turn off all LATD output pins ; SPI configuration ------------------------------------------------------------ clrf TRISC ;bcf TRISC,3 ; pin 3 on PORTC used as SPI clock and should be configured as an output to operate in master mode ;bcf TRISC,5 ; pin 5 on PORTC used for SPI serial data out (SDO) and should be configured as an output movlw B'10110000' ; set up SPI control register see pg 163 for details movwf SSPCON1; bsf SSPSTAT,CKE; data transmitted on rising edge ; END SPI config ---------------------------------------------------------- ; 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 initially ; after the first trigger then set it up so that it is triggered at the rate you want in the high_isr routine 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 return ;---------------------------------------------------------------------------------------------------------- ;-----WRITE contents in y to DAC (MCP4921) using SPI ------------------------------------------------------ ;---------------------------------------------------------------------------------------------------------- spi_write ;two bytes of data sent to spi daq (a 12-bit dac). First nibble of first byte is dac config settings; second nibble is ; the most significant 4 bits of 12bit numerical value. The second byte contains the 8 least signifcant bits of the 12-bit value bcf LATD, LATD1; // Select SPI DAC chip movf SSPBUF, W ;WREG reg = contents of SSPBUF (this clears BF) which will be set again after the data is transmitted ; load SSPBUFF with spi dac config data to be sent to SPI device ; First nibble of first byte sent to dac is dac config settings; second nibble is ; the most significant 4 bits of 12bit numerical value swapf y, f movlw 0x0f andwf y, W ; W no holds 4 most signicant bits in lower nibble iorlw 0x70 ; these are configuration bits for spi dac movwf SSPBUF spi_wait1 btfss SSPSTAT, BF ;Has data been received (transmit complete)? goto spi_wait1 ;No movf SSPBUF, W ;WREG reg = contents of SSPBUF (this clears BF) which will be set again after the data is transmitted ; load SSPBUFF with y data to be sent to SPI device movlw 0xf0 andwf y, W ; movwf SSPBUF spi_wait2 btfss SSPSTAT, BF ;Has data been received (transmit complete)? goto spi_wait2 ;No bsf LATD, LATD1; // Select SPI DAC chip goto end_int ;---------------------------------------------------------------------------------------------------------- ;-----Low Priority Interrupt Service Routine ------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------- org 0x0300 low_isr nop ; put whatever you would like to do on low priority interrupt here retfie ;return and reset interrupts end ; End of ASM code
Categories: pic18f, Uncategorized
Comments (0)
Trackbacks (0)
Leave a comment
Trackback