240 likes | 492 Views
EMK310 Test Revision Mr Bastian Suntken. This lecture. Sigma-delta ADC Timer 0 Timer 2 Look up tables PIR interface controller General Questions. Sigma-Delta ADC. Diagram. Difference amp. Comparator. INPUT. LPF. Digital Filter. SH / 1bit DAC. CLK. Sigma-Delta ADC.
E N D
This lecture • Sigma-delta ADC • Timer 0 • Timer 2 • Look up tables • PIR interface controller • General Questions
Sigma-Delta ADC • Diagram Difference amp Comparator INPUT LPF Digital Filter SH / 1bit DAC CLK
Sigma-Delta ADC • The difference amplifier is used to subtract the value of the feedback from the input value. • The LPF then “integrates” the output of the difference amplifier with the aim averaging it out to a zero voltage. • The Comparator compares the LPF output to ground, and if there were to many pulses fed back the result will be positive and the comparator will give a zero output, whereas if there were 2 few pulses the result will be a voltage high. • SH circuit is used to feed back the DAC value at a specified bit period. • Digital filter is used to filter out the ADC noise (sometimes increase the bit resolution) and to convert the bit stream to a x-bit binary code.
ADC / Digital filter MATLAB ADC time simulation for 10mV.
ADC / Digital filter Spectrum of the ADC output for 10mV.
ADC / Digital filter MATLAB decimation time simulation for 10mV.
ADC / Digital filter Spectrum of the decimator output for 10mV
Timers • How to calculate a delay time: • Determine fosc (can be altered by changing the OSSCON register) • Determine instruction frequency finst = fosc /4 • Determine the frequency your delay will take: tdelay= 1/fdelay • Calculate the number of instruction cycles you need for the delay: x=number of cycles = finst/fdelay • If x is bigger than 8 bits a prescaler or second value is needed to get a bigger delay, then one would use ftimer = finst / (prescaler*postscaler) see datasheet for details. • x=number of cycles = ftimer/fdelay • With timer 0 for example a flag is set when the timer overflows from FFh – 00h, i.e. an overflow occurs which causes an interrupt. Thus if we want x number of timer events to occur we must load the timer with a value of FFh minus (-) x. This is applicable if we cannot set the value at which an interrupt should occur.
Delay1 equ 0x20 ; Define two file registers for the Delay2 equ 0x21 ; delay loop org 00h Setup bsf STATUS,RP0 ; select Register Page 1 bcf OSCCON,IRCF2 ; Set oscillator frequency to 500 kHz bsf OSCCON,IRCF1 bsf OSCCON,IRCF0 bsf OSCCON,SCS ; internal oscillator used for system clock movlw b'11010000' ; PS<2:0> = 001 = 1:4 prescaler ; PSA<3> = 0 prescaler assigned to timer 0 (and not Watchdog timer) ; T0CS<5> = 0 Use internal instruction cycle clock movwf OPTION_REG bcf STATUS,RP0 ; back to Register Page 0 Main clrf TMR0 ; Start the counter ; Timer 0 is written so count is inhibited for next 2 instruction cycles. call Delay_loop ; Execute the delay loop movfw TMR0 goto $ ; this line stops the program counter from incrementing, i.e. it will keep on executing this line forever. end Timer 0 example (look on web 4 complete code)
Timer 2 example • list p=16f917 • #include "C:\Program Files\Microchip\MPASM Suite\p16f917.inc" • __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF) • Count equ 0x20 • DelayFlag equ 0x21 • org 00h • goto Setup • org 04h • goto ISR • Setup • clrf Count ; Initialise Count • movlw b'00000001' ; Timer 2 prescaler 1:4 • movwf T2CON • bsf STATUS,RP0 ; select Register Page 1 • movlw d'2' ; 4 * 2 = 8 instruction cycles between interrupts • movwf PR2 ; Pre-load value • bcf OSCCON,IRCF2 ; Set oscillator frequency to 500 kHz • bsf OSCCON,IRCF1 • bsf OSCCON,IRCF0 • bsf PIE1,TMR2IE ; timer2 interrupt enable • bcf STATUS,RP0 ; back to Register Page 0 • bsf INTCON,PEIE ; Peripheral interrupt enable • bsf INTCON,GIE ; global interrupt enable
Timer 2 example • Main • clrf DelayFlag • call Delay • goto $ ; this line stops the program counter from incrementing, i.e. it will keep on executing this line forever. • ;------------------------------------- • ; Delay loop • ;------------------------------------- • Delay • bsf T2CON,TMR2ON ; Start the counter • Go btfsc DelayFlag,0 • goto Exit • goto Go ; Loop till timer 2 interrupt occurs • Exit • bcf T2CON,TMR2ON ; Switch off timer 2 • bsf STATUS, RP0 ; Bank 1 • bcf PIE1,TMR2IE ; Disable TMR2 interrupt • bcf STATUS,RP0 ; Bank 0 • return • ISR • bcf INTCON,GIE • movlw 01h • addwf Count,1 • movlw d'12' ; Count 12 timer 2 interrupts • subwf Count,0 ; Answer in W reg • btfsc STATUS,Z ; set flag if Z is one • bsf DelayFlag,0 ; 12 interrupts occurred • bcf PIR1,TMR2IF ; clear timer 2 interrupt flag • retfie • end
Lookup tables • Lookup tables work on the principle of pointing the program counter to a specific location in memory. From that location the desired value is returned. • In your subroutine test for some condition and load the position of the wanted data into the working register. Then call the lookup table. • The first line in the lookup table adds the value from the working register to the program counter, thus causing the microcontroller to execute the code at the specific location in the table.
Lookup tables • DataTable addwf PCL ; add W value to PCL • retlw b'00111111' ; 0 • retlw b'00000110' ; 1 • retlw b'01011011' ; 2 • retlw b'01001111' ; 3 • retlw b'01100110' ; 4 • retlw b'01101101' ; 5 • retlw b'01111101' ; 6 • retlw b'00000111' ; 7 • retlw b'01111111' ; 8 • retlw b'01101111' ; 9
PIR controller IC • http://www.mos.co.za/mos-products/m2012a/
Questions • .
Thank you! Good luck (fun) 4 your test!