Time Measurement Measuring pushbutton pulse width • Capture Mode of the Capture/Compare/PWM module is used for time measurement. TMR1 16bit value transferred to 16-bit capture register on edge detect. PICF16873 RC2/CCP1 Pulse Width 1. Capture TMR1 value on falling edge (Tf) 2. Capture TMR1 value on rising edge (Tr) 3. Pulse width = Tr - Tf Rising or falling edge detect, with interrupt flag set. V 0.1 1 swdet.c (configuration) V 0.1 configure for falling edge set edge_type = 0 (falling) so ISR knows what edge has happened. /* set up capture */ bitset(TRISC,2); /* set CCP1 input */ /*capture every falling edge 0100 */ bitclr(CCP1CON, 3); bitset(CCP1CON, 2); Setup falling edge capture bitclr(CCP1CON, 1); bitclr(CCP1CON, 0); 2 swdet.c (main loop) wait for interrupt // enable interrupts // CCP1IF = 0; clear capture interrupt flag bitclr(PIR1,2); // enable capture interrupt CCP1IE = 1; bitset(PIE1, 2) ; Interrupt // enable peripheral interrupts, PEIE enables bitset(INTCON,6); (CCP1, PEIE, //enable global interrupts, GIE GIE) bitset(INTCON,7); V 0.1 Use interrupt to save timer values. configure for rising edge set edge_type = 1 (rising) so ISR knows what edge has happened. wait for interrupt print pulse width 3 V 0.1 4 Get 16-bit capture value (CCPR1H:CCPR1L) swdet.c (main loop) 0 (falling) for(;;) { CCP1CON = 0; /* turn off when changing modes */ CCP1CON = 0x4; /* capture every falling edge */ edge_type = 0; /* looking for falling edge */| capture_flag = 0; while(!capture_flag); capture_flag = 0; CCP1CON = 0; /* turn off when changing modes */ CCP1CON = 0x5; /* capture every rising edge */ edge_type = 1; /* looking for rising edge*/ while(!capture_flag); printf ("Switch pressed, timer ticks: %u",delta); pcrlf(); 1 (rising) edge_type? delta_time = current_time – last_time save timer value interrupt service capture_flag = 1 return } V 0.1 5 V 0.1 6 1 Interrupt Service Timer1 Overflow unsigned int last_capture, this_capture; timer_isr(void){ // CCP1IF = 0; clear capture interrupt flag bitclr(PIR1,2); pack 2 bytes this_capture = CCPR1H << 8 ; this_capture = this_capture | CCPR1L ; into one if (edge_type == 0) { integer. last_capture = this_capture; } else { /* compute delta */ if (this_capture > last_capture) { delta = this_capture - last_capture; } else { /* this is timer overflow case */ delta = this_capture + ~last_capture + 1; } this_capture, last_capture unsigned } capture_flag = 1; integers so can represent 0 to 65535 } V 0.1 7 Timer1 is free running, captured at any time 0x0000 0x0000 Second capture (B) First capture (A) First capture (A) Second capture (B) 0xFFFF 0xFFFF overflow case (A > B) no overflow case (B > A) delta = B + (0 – A) 2’s complement =B–A = B + (~A + 1) V 0.1 8 delta = B - A Timer1 Scaling Implementing a Clock/Calendar Use 32.768KHz crystal on T1OS0/T1OS1 pins, this crystal frequency good for accurate time keeping 32.768KHz = 32768 Hz Æ when 16-bit counter rolls over, then exactly 2 seconds Æ when counter = 0x8000, exactly 1 sec No error in time keeping, good for long term clock/calendar function. Only options are 1,2,4,8. However, can be clocked by an source independent of main oscillator. V 0.1 9 V 0.1 Intensity Based Infrared How to block Ambient Light? Vdd Rout (dc volt) emitter Vref receiver + Vout amplifier Vdd ~ ~ Vout = Vdd, IR present (Rout > Vref) Vout = 0v, IR absent (Rout < Vref) voltage Increase in ambient light raises DC bias Vref voltage time Transmitter Problem: value for Vref changes depending on ambient light! Vref time V 0.1 10 Receiver capacitor blocks DC Open/Close switch at particular frequency Transmitter DC voltage here depends only how fast transmitter is switched switch opening/closing Waveform 11 V 0.1 12 2 Integrated IR Receiver IR Waveform Waveform produced by receiver when stimulated by a universal remote control depends on function and manufacturer. Actual IR receiver a bit more complicated # of bits depends on IR remote function Start All of this is in here V 0.1 Out 1 23 13 Gnd Space-Width Encoding Examples T Bit Value 2T T 3T ‘0’ 2T Bit Value T T 2T ‘0’ T Using ‘swdet.c’ as a starting point, decode the first two bytes of a frame and print these two bytes out to the screen via Hyperterm. Choose a particular prescale for Timer1 to give you enough fidelity on Timer1 to distinguish ‘1’,’0’ periods. ‘0’ ‘1’ T 14 Use the scope and determine the periods of ‘start’, ‘0’, and ‘1’ (assume a ‘0’ the short period, a ‘1’ is the long period). Sony code: ‘0’ period = 2T, ‘1’ period= 3T Bit Time Length of start period, ’0’ period, ‘1’ period will vary with function. ‘0’, ‘1’ waveforms may be inverted. Called spaceV 0.1 width modulation. You will be assigned a function on the Universal Remote. T ‘1’ Stop ‘1’ Lab #12: Decoding IR Waveform REC-80 code, Panasonic: ‘0’ period = 3T, ‘1’ period = 4T Bit Time ‘0’ T Your particular function may have LOTs of bits in a frame, just decode the first two bytes (16 bits). If your function does NOT have at least 16 bits, then get the TA to assign you a different IR remote function (or find one, and show this to the TA). ‘0’ From: “A Primer on Remote Control Technology”, Innotech V 0.1 Systems, Inc. 15 V 0.1 16 Biphase Encoding Example Waveform In a previous example, ‘1’ and ‘0’ were distinguished by having different periods. ‘0’ ‘0’ ‘0’ ‘1’ ‘0’ ‘1’ ‘1’ assume LSB first ‘1’ ‘0’ ‘1’ ‘0’ ‘0’ ‘1’ ‘1’ ‘0’ ‘0’ Second Byte First Byte 11101000 = 0xE8 Some Remote function/manufacturer use biphase encoding; ‘1’ and ‘0’ have same period, but use different transition in middle of the period (low-to-high or high-to-low). ‘0’ ‘0’ ‘0’ ‘1’ ‘0’ ‘1’ ‘1’ ‘1’ 00110010 = 0x32 Print first two bytes of frame to screen. transition low-to-high is a ‘1’ transition high-to-low is a ‘0’ V 0.1 17 V 0.1 18 3 Experiment 12 Notes Ensure that your assigned IR Remote function does NOT use biphase encoding (must use space-width encoding). Simply measure the time between falling edges – the first period will be the start period, the periods after that will be either ‘1’ or ‘0’. Compute the number of timer tics for a ‘1’ or ‘0’, and compare what is measured. Use some slack, if you compute 2000 timer ticks for a ‘0’, and 4000 for a ‘1’, then distinguish a ‘1’ as being greater than 3000 tics. You must compute an appropriate prescale for timer1 so that your timer tics will have necessary fidelity to distinguish between ‘0’ and ‘1’. V 0.1 19 4