![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Arizona Chris
Joined: 20 Dec 2014 Posts: 69 Location: Arizona
|
Timer 1 wont quite reach full count ? |
Posted: Sat Jan 24, 2015 2:11 pm |
|
|
Hello All,
We are currently writing the code for our next robot project, and working on the sonar. I wanted to get more familiar with using the timers and wrote some small programs to test them to see if the numbers I calculated came out. I had no problem with timer0, it would count all the way to 255, but for some reason I cannot get timer 1 to go past about 65510. I wrote a simple program to produce a square wave I can look at and measure on the oscilloscope, and so far all the numbers are coming out perfectly. The WDT is off, which is what I first thought was somehow resetting the timer before it reached the count I was looking for. Nope. Any ideas?
What happens when I run the program with numbers higher than this limit is that the output goes high upon turn on, and never goes low. Its stuck in the loop perhaps because it never reaches numbers like 65535.
Im using a 16F877A chip at 10mhz. Here is the meat of the simple timer test code I am using:
Code: | //Include Files:
#include <16F877A.h>
//Directives and Defines:
#device ADC=10 //Set ADC when used to 10 bit = 0 - 1023
#fuses NOPROTECT,HS,NOWDT //xtal is used
#use delay(crystal=10MHz) //xtal speed
#use fast_io(ALL) //must define tris below in main when using this
//for LCD:
#use rs232(baud=9600, xmit=Pin_B1, bits=8, parity=N, INVERT, stream=SERIAL)
//****************************************************************************
//-- Main Program
//****************************************************************************
void main(void) {
// Set TRIS I/O directions, define analog inputs, compartors:
set_tris_A(0b11111);
set_tris_B(0b11111000);
set_tris_C(0b11111111);
set_tris_D(0b11111111);
set_tris_E(111);
//MAIN PROGRAM:
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 ); //Internal clock = Fosc/4 = 2.5mhz
//Only one 8bit prescaler (1,2,4,8)
//Calculations:
//Timer ticks = 1/(clock) * prescaler
// = 1/(2500000) * 1 count=128 255 512 1024 2048 4096 8192 16384 32768 65510MAX
// = .0000004 Sec * 1 = .4uS 50uS .1mS .2mS .4mS .8mS 1.6mS 3.2mS 6.4mS 12.8mS 25.6mS
// = .0000004 Sec * 2 = .8us
// = .0000004 Sec * 4 = 1.6mS
// = .0000004 Sec * 8 = 3.2mS .21S
int16 time;
time = 65510; //WHY THIS AS MAX AND NOT 65535??
while (true) {
output_high(Pin_B0); //turn on LED
SET_TIMER1(0); //reset to zero on timer counter. (counts to )
while(get_timer1() < time); //wait until timer reaches time
output_low(Pin_B0); //after timeout turn off led
SET_TIMER1(0); //reset to zero on timer counter. (counts to )
while(get_timer1() < time); //wait until timer reaches time
}
} |
So who or what is stealing my counter bits???? ;)
Chris |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19370
|
|
Posted: Sat Jan 24, 2015 3:31 pm |
|
|
You should be able to go to 65534.
However it'll never go >65535. The next count after 65535, is 0.
Just tested with 65534, and it merrily works. |
|
![](templates/subSilver/images/spacer.gif) |
Arizona Chris
Joined: 20 Dec 2014 Posts: 69 Location: Arizona
|
limit |
Posted: Sat Jan 24, 2015 4:35 pm |
|
|
Yes I know that, if it runs fine on your setup then I have a problem with my micro or a bug in the compiler. I can sneak up on it one bit at a time, and when I cross that threshold - it never escapes the loop. 65510.
Ill try this with timer2. See if acts the same way!
Chris |
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Sat Jan 24, 2015 5:37 pm |
|
|
Quote: | Yes I know that, if it runs fine on your setup then I have a problem with my micro or a bug in the compiler. |
That's why we ask for the compiler version up front.
What version are you using? _________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Sat Jan 24, 2015 7:27 pm |
|
|
Ttelmah wrote: | You should be able to go to 65534.
However it'll never go >65535. The next count after 65535, is 0.
Just tested with 65534, and it merrily works. |
That's what I thought until I figured out the hard way for the PIC24 series...
Why do they have to inverse it !!! ![Mad](images/smiles/icon_mad.gif) _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19370
|
Re: limit |
Posted: Sun Jan 25, 2015 12:33 am |
|
|
Arizona Chris wrote: | Yes I know that, if it runs fine on your setup then I have a problem with my micro or a bug in the compiler. I can sneak up on it one bit at a time, and when I cross that threshold - it never escapes the loop. 65510.
Ill try this with timer2. See if acts the same way!
Chris |
Of course it won't......
Timer2, is only an 8bit timer on this processor. Timer1, is the only 16bit timer.
As posted, the code will work with 65534. However it won't, if you have more code in your wait loop. Remember that the counter is incrementing every 8 instructions. The wait loop itself has to perform a 16 bit comparison, logic test, and jump. Add even one more instruction and you risk 'missing' the count. I suspect your real code is not what you have posted. |
|
![](templates/subSilver/images/spacer.gif) |
Arizona Chris
Joined: 20 Dec 2014 Posts: 69 Location: Arizona
|
count |
Posted: Sun Jan 25, 2015 3:06 pm |
|
|
Yes Ttelmah, you probably hit the nail on the head here. The problem is all the math it takes to do the 16 bit compare and while loop takes a long time and I'm missing the last few counts. For my application - sonar timing - this will never be an issue and the timer works perfectly for this application. Anyway If I wanted to use full scale all the time on the counter, I would simply look at the rollover flag interrupt bit and use that. For sonar, Ill time the pulse, subtract the calculation time and have an exact measurement to compute the distance. Oh so easy now!
A little bit about myself so you see where I'm coming from. I have been an embedded microcontroller engineer for about 14 years now, and we have traditionally used Pic Basic Pro at work to do our software. it fine for the relatively simple teleoperated robotics computations we use in our robotic heads for cameras. You can see my work at most NFL and superbowl events as the goal post cameras on each endzone. I designed and did all the code for those and many more like them.
But at home, my interest is Autonomous robotics. Pic basic failed badly here, and the awful math functions and lack of capability really limited what I can do How wonderful it has been to learn this version of embedded C! My life has changed. Awesome math functions, floating point, simple commands for timers, pwm and serial. Where has this been all my life?!
Anyway I started learning C late last year, and I know Its going to take me like 6 months to get good at it. I hope you all will tolerate my really dumb questions for the next few months...
Thanks to everyone for your help on this amazing forum. Your awesome.
Chris |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19370
|
|
Posted: Sun Jan 25, 2015 3:15 pm |
|
|
As a separate comment, you do realise that this is what the CCP's are really good at?.
You can setup the CCP, to automatically record a timer count, when it receives a signal..... Absolutely perfect for what you are doing. CCP_CAPTURE_(FE for falling edge, and RE for rising edge). On the edge seen on it's input, it records the timer value.
As a further comment, remember the blanking period you _will_ need at the start. The transmit pulse will always be picked up, and will tend to swamp the receiver. You normally need to have a minimum period during which you don't search, at the very start. Remember also you could use the timer 'overflowing' as a 'nothing seen' indicator.
One of the best 'test targets' for air sonar, is a tennis ball. It is so furry, and with the curved surface, it is hard to detect. It makes a great test of how well the system is working. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|