V 0.11 Time Measurement Capture Mode of the Capture/Compare/PWM module is used for time measurement....
-
Upload
domenic-little -
Category
Documents
-
view
220 -
download
0
Transcript of V 0.11 Time Measurement Capture Mode of the Capture/Compare/PWM module is used for time measurement....
V 0.1 1
Time Measurement
• Capture Mode of the Capture/Compare/PWM module is used for time measurement.
TMR1 or TMR3 16-bit value transferred to 16-bit capture register on edge detect.
Rising or falling edge detect, with interrupt flag set.
V 0.1 2
Measuring pushbutton pulse width
RC2/CCP1
PIC18
Pulse Width
1. Capture TMR1 value on falling edge (Tf) in CCPR1
2. Capture TMR1 value on rising edge (Tr) in CCPR1
3. Pulse width = Tr – Tf (Elapsed Timer1 Tics)
Use interrupt to save timer values.
V 0.1 3
Computing Pulse Width
In overflow case, the value can be greater > 16 bits so need to use a LONG type to hold TimerDelta value.
© Charles River Media
V 0.1 4
ISR for capturing pulse width.
tmr1_ov variable keeps track of timer1 overflows.
After falling edge, reconfigure for rising edge capture.
After rising edge, compute delta timer tics
V 0.1 5
V 0.1 6
After pulse width is captured, the capture_flag semaphore is set and the
V 0.1 7
#define FOSCQ 29491200#define PRESCALE 2.0#define TMR1TIC 1.0/(FOSCQ/4.0)*PRESCALEdouble pulse_width_float;long pulse_width;main(void){ serial_init(95,1); // 19200 in HSPLL mode ptr = (char *) &this_capture; // initialize timer 1 // prescale by 2 T1CKPS1 = 0; T1CKPS0 = 1; T1OSCEN = 0; // disable the oscillator TMR1CS = 0; //use internal clock FOSC/4 T1SYNC = 0; // set CCP1 as input bitset(TRISC,2); // enable interrupts IPEN = 0; PEIE = 1; GIE = 1;
swdetov.c (configuration)
Initialize Timer1
CCP1 used as input pin.
V 0.1 8
swdet.c (main loop)
wait for capture
configure for falling edge, enable CCP1 interrupt, and timer1 interrupt
print pulse width
V 0.1 9
for (;;) { // loop forever err_flag = 0; CCP1CON = 0; //turn off when changing modes CCP1CON = 0x4; // capture every falling edge edge_type = 0; // looking for falling edge capture_flag = 0; TMR1IF = 0; // clear timer 1 interrupt flag TMR1IE = 1; // allow timer 1 interrupts TMR1ON = 1; // enable timer 1 while(!capture_flag) { asm("clrwdt"); //wait forever for button press } 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) { asm("clrwdt"); // wait for rising edge
}
swdet.c (main loop)First (falling) edge capture
Second (rising) edge capture
V 0.1 10
swdet.c (main loop, cont.) // continued from code on previous slide
if (err_flag) { // multiple overflows printf("**Timer 1 overflowed more than once! **"); pcrlf(); } else { // scale to microseconds pulse_width_float = (delta * ONE_TIC)*1.0e6; pulse_width = (long) pulse_width_float;
printf ("Switch pressed, timer ticks: %ld, pwidth: %ld (us)", delta,pulse_width); pcrlf(); } }
based on Fosc, pre-scale
// pre=8, crystal = 7.3728 MHz HSPLL#define ONE_TIC 1.08492e-6
V 0.1 11
last_capture = timer valueoverflow = -1
CCP1F = 0;Get 16-bit capture value (CCPR1H:CCPR1L)
interrupt service
edge_type?
yes
overflow?
1 (rising)
delta_time = (0 – last_capture) + this_capture;
overflow++;clear TMR1IF
TMR1IF?
0 (falling)
noCCP1IF?
-1
delta = this_capture – last_capture
Timer1 overflow
disable TMR1interrupt
return from interrupt
no overflow during button press
V 0.1 12
Timer1 Overflow
0x0000
0xFFFF
First capture (A)
Second capture (B)
Timer1 is free running, captured at any time
no overflow case (B > A)delta = B - A
0x0000
0xFFFF
First capture (A)
Second capture (B)
overflow casedelta = (0 – A) + B
Note that B can occur after ‘A’, so value can be > 0xFFFF, so need a ‘long’ for delta value!!!
V 0.1 13
Interrupt Servicevolatile unsigned int last_capture, this_capture;volatile long delta;volatile signed char tmr1_ov, err_flag;timer_isr(void){ if (TMR1IF) { tmr1_ov++; // increment timer1 overflow TMR1IF = 0; } if (CCP1IF) { CCP1IF = 0; //clear capture interrupt flag this_capture = (CCPR1H << 8) | CCPR1L ; if (edge_type == 0) { last_capture = this_capture; tmr1_ov = -1; // clear timer 1 overflow count } else {
pack 2 bytes into one integer.
First edge
V 0.1 14
Interrupt Service (cont.) } else { if (tmr1_ov == -1) { // no overflow delta = this_capture - last_capture ; } else { // overflowed once delta = 0 - last_capture; delta = delta + this_capture; } } /* disable timer1 interrupt */ TMR1ON = 0; // disable timer 1 TMR1IE = 0; // disable timer 1 interrupts TMR1IF = 0; // clear flag just in case } capture_flag = 1; }}
2nd edge
no overflow case
overflow case
V 0.1 15
Timer1 Scaling
Precaling options are 1,2,4,8. However, can be clocked by an source independent of main oscillator.
V 0.1 16
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.
V 0.1 17
Intensity Based Infrared
emitter receiver
Rout (dc volt)
Vref
Vdd
Vout
Vout = Vdd, IR present (Rout > Vref)
Vout = 0v, IR absent (Rout < Vref)
+
Problem: value for Vref changes depending on ambient light!
time
time
Increase in ambient light raises DC bias
Vref
Vref
volt
age
volt
age
V 0.1 18
How to block Ambient Light?
Vdd
Transmitter
~~
Receiver
amplifier
capacitor blocks DC
Open/Close switch at particular frequency
DC voltage here depends only how fast transmitter is switched
Transmitter
Waveform
switch opening/closing
V 0.1 19
Integrated IR Receiver
Actual IR receiver a bit more complicated
All of this is in here
1 23Out Gnd
V 0.1 20
IR WaveformWaveform produced by receiver when stimulated by a universal remote control depends on function and manufacturer.
Start ‘0’ ‘1’
# of bits depends on IR remote function
Stop
Length of start period, ’0’ period, ‘1’ period will vary with function. ‘0’, ‘1’ waveforms may be inverted. Called space-width modulation.
V 0.1 21
Space-Width Encoding Examples
T 2T T 3T T 2T
‘0’ ‘1’ ‘0’
Bit Time
Bit Value
REC-80 code, Panasonic: ‘0’ period = 3T, ‘1’ period = 4T
T T 2T T T
‘0’ ‘1’ ‘0’
Bit Time
Bit Value
T
Sony code: ‘0’ period = 2T, ‘1’ period= 3T
From: “A Primer on Remote Control Technology”, Innotech Systems, Inc.
V 0.1 22
Lab #12: Decoding IR Waveform
You will be assigned a function on the Universal Remote.
Use the scope and determine the periods of ‘start’, ‘0’, and ‘1’ (assume a ‘0’ the short period, a ‘1’ is the long period).
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.
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).
V 0.1 23
Example Waveform
‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’‘1’ ‘1’ ‘1’ ‘1’ ‘1’ ‘1’ ‘1’ ‘0’ ‘0’
assume LSB first
First Byte Second Byte
11101000 = 0xE8 00110010 = 0x32
Print first two bytes of frame to screen.
V 0.1 24
Biphase Encoding
In a previous example, ‘1’ and ‘0’ were distinguished by having different periods.
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’ ‘0’ ‘1’ ‘1’ ‘1’ ‘1’
transition high-to-low is a ‘0’ transition low-to-high is a ‘1’
V 0.1 25
Experiment 12 NotesEnsure 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’.