With the timer running at CK/1, then does it not run at the CPU clock speed? That would mean that instructions that take a couple of cycles to execute will allow for a couple of cycles on the timer to pass. The sequence of steps you do in finding the 5 wave forms are very repeatable. The final transition on the fifth cycle to where you detect it and stop happens between where you last read the signal (and it is false) to where you read it and it is true. Then you stop the timer. The resolution that you will get is essentially the size of your last "while" statement check for the last transition of your waveform. That loop is a bit test and branch not equal or equal which is probably three cycles (and three counts on the timer). All the rest in front is essentially ignored and the instructions stopping the timer are a fixed constant relative to the granularity of the timer values. Optimization of -Os reduces space at the loss of efficient processing in the code. It may be that the last "while" statement is done in a manner that is less efficient in time than the other and you end up with 12 clocks. Check the assembly code of that last loop and that should correspond to the granularity of your timer value. If you want greater accuracy, either sample more waveforms (how about 15 since you have a multiple of three in your timer value), or use an external trigger to stop the counter (if possible). Does this seem reasonable? -Allan David VanHorn wrote: > Bear with me, this isn't simple. > > I have two sensors, each outputs a square wave. > I need to accurately measure the period of each, and determine the > difference in the two periods. > > Depending on how I set the optimization, I get different results. > > At -Os, I see values like 292, 304, 316. > The values are spaced by 12! > I won't ever see 305, 306, 307... > > If I recompile with -O0, the spacing between the values is different, > but still mostly three discrete steps in values with nothing in > between. > > I'm using an M644 at 20 MHz, T1 is running at CK/1 > > The basics are that I stop the clock to T1, and clear it.. Then I wait > till I see a low, then wait till I see a high, then I start the timer. > With the timer running, I wait till I see low, high, low high... till > five periods have passed, then I stop the clock to T1, and take the > data. > > Having done that, I do the same thing for the other sensor, then > subtract the second sensor from the first, which should give me some > small-ish value. The exact number isn't important, but what is > puzzling me is that the intermediate values are missing. Like somehow > I'm loosing low bits, but the delta is 12, which makes no sense from a > binary perspective. > > > > // Prep for aquisition > TCCR1B &= ~(1<<CS10); > // Stop T1 (should already BE stopped, > // but it's cheap insurance) > > TCNT1=0; > // Clear T1 > > // Sync to the A channel > while ( Sensor_Pin & (1<<ChannelA)); > // Wait for a low, so we know we're not seeing > // a high level yet > while (!(Sensor_Pin & (1<<ChannelA))); > // Wait for the high edge > > TCCR1B |=(1<<CS10);// START the clock to T1 > > // T1 is now counting the period width. > // That can be as little as 25us > // (5 periods * 5us * 20 MHz = 500 counts) > // or as much as 138 uS > // (5 periods * 23uS * 20 MHz = 2300 counts) > > while ( Sensor_Pin & (1<<ChannelA)); > // Wait for a low on PD2 > while (!(Sensor_Pin & (1<<ChannelA))); > // Wait for a high on PD2 > // One pulse has gone > while ( Sensor_Pin & (1<<ChannelA)); > while (!(Sensor_Pin & (1<<ChannelA))); > // Now two > while ( Sensor_Pin & (1<<ChannelA)); > while (!(Sensor_Pin & (1<<ChannelA))); > // Now three > while ( Sensor_Pin & (1<<ChannelA)); > while (!(Sensor_Pin & (1<<ChannelA))); > // Now four > while ( Sensor_Pin & (1<<ChannelA)); > while (!(Sensor_Pin & (1<<ChannelA))); > // Now five > > TCCR1B &= ~(1<<CS10); > // Stop T1 > A_Sensor_Raw = TCNT1; > // Grab the data > TCNT1=0; > // Clear T1 for the next measurement. > > // Sync to the B channel, and proceed as above > while ( Sensor_Pin & (1<<ChannelB)); > while (!(Sensor_Pin & (1<<ChannelB))); > TCCR1B |=(1<<CS10); > while ( Sensor_Pin & (1<<ChannelB)); > while (!(Sensor_Pin & (1<<ChannelB))); > while ( Sensor_Pin & (1<<ChannelB)); > while (!(Sensor_Pin & (1<<ChannelB))); > while ( Sensor_Pin & (1<<ChannelB)); > while (!(Sensor_Pin & (1<<ChannelB))); > while ( Sensor_Pin & (1<<ChannelB)); > while (!(Sensor_Pin & (1<<ChannelB))); > while ( Sensor_Pin & (1<<ChannelB)); > while (!(Sensor_Pin & (1<<ChannelB))); > TCCR1B &= ~(1<<CS10); > Temp2 = TCNT1; > TCNT1=0; > > //********** > // Condition according to sensor > // Scale to fit the histogram array > // Take the difference, and add half > A_Sensor_Raw = ((A_Sensor_Raw - Temp2) + (Sample_Bins/2)); > // If the value is out of range then wrap it > A_Sensor_Raw = (A_Sensor_Raw & 0x01FF); > > > Why do I not see output like 290,291,292... ? > >
Message
Re: [AVR-Chat] Optimization levels in WinAVR, wierd problem.
2009-05-01 by A & T Schrum
Attachments
- No local attachments were found for this message.