|
|
View previous topic :: View next topic |
Author |
Message |
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
(SOLVED) #USE_TIMER... get_ticks() |
Posted: Wed Dec 09, 2015 8:50 pm |
|
|
I am using a PIC18F67J60 with the following directives...
#use delay(crystal=25MHz,restart_wdt)
#use timer(tick=100us,bits=32,NOISR)
The compiler does not generate a warning with regard to tick timing, however, timing appears to be wrong by an approximate factor of 2... I have no idea why... Any help/suggestions would be appreciated...
Last edited by uslimey on Wed Dec 16, 2015 6:47 am; edited 2 times in total |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
Re: #USE_TIMER... get_ticks() |
Posted: Wed Dec 09, 2015 10:25 pm |
|
|
uslimey wrote: | I am using a PIC18F67J60 with the following directives...
#use delay(crystal=25MHz,restart_wdt)
#use timer(tick=100us,bits=32,NOISR)
The compiler does not generate a warning with regard to tick timing, however, timing appears to be wrong by an approximate factor of 2... I have no idea why... Any help/suggestions would be appreciated... |
The PIC18Fx7J60 family contains embedded Ethernet controllers. The CPU is typically configured with a 25MHz crystal to suit the Ethernet controller which is then typically scaled up to 41.667MHz (weird value but that is just the way it is).
I suspect you really want to tell the compiler the clock is 41.6667MHz.
If you are intending to use the WDT to recover from the PIC disappearing into La La land then adding restart WDT inside the delay function will almost always guarantee the WDT will be useless for you. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
|
Posted: Mon Dec 14, 2015 9:16 pm |
|
|
So I think the #use delay 25Mhz is correct because the baud rate for my serial ports is scaled correctly...
You were right about the compiler warnings... But the problem is still not solved...
When I set, #use timer(tick=1ms,bits=32,NOISR) timing is now wrong by a factor of 20, instead of a factor of 2.
It would appear that the TICKS_PER_SECOND constant which is generated by the compiler is incorrect...
I subsequently tried, #use timer(tick=1ms,bits=32, define=tickPerSecond,NOISR)... I thought that perhaps the TICKS_PER_SECOND was being overwritten by the Ethernet Stack Ticks... Anyway the results of this were even more confusing.... get_ticks()/ticksPerSecond resulted in a count that appeared to increment at a rate of 10's of thousands per second.
Long story short, I'm stumped. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19503
|
|
Posted: Tue Dec 15, 2015 2:32 am |
|
|
First thing is read what things say!...
Look at the manual for #use timer.
You are using it without a timer number, so it says the default is timer1.
Then look at the include file header for the Ethernet. You will find it tells you what timers the Ethernet requires/uses. Result 'of course' it is not going to work.
No warning, since the Ethernet code, just sets the timers up assuming them to be unused. The #use timer call has already setup timer1, but the later code does not know this has been done.....
Since you are using a PIC that has other timers, just tell #use timer, to use another. Timer3 typically, since this has similar features to timer1. |
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
|
Posted: Tue Dec 15, 2015 5:06 am |
|
|
Ok I will try that, however, I did search the Ethernet Stack for timers.... TICK.C is the only module using timers and compilation is conditional. TMR1 is not used with PIC18 devices... See below...
Code: |
#if defined(__18CXX)
// Use Timer0 for 8 bit processors
// Initialize the time
TMR0H = 0;
TMR0L = 0;
// Set up the timer interrupt
INTCON2bits.TMR0IP = 0; // Low priority
INTCONbits.TMR0IF = 0;
INTCONbits.TMR0IE = 1; // Enable interrupt
// Timer0 on, 16-bit, internal timer, 1:256 prescalar
T0CON = 0x87;
#else
// Use Timer 1 for 16-bit and 32-bit processors
// 1:256 prescale
T1CONbits.TCKPS = 3; |
|
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
|
Posted: Tue Dec 15, 2015 7:17 am |
|
|
Ok, I tried:
#use timer(timer=3,tick=1ms,bits=32, NOISR)
It makes no difference which timer I choose, the behavior is exactly the same... The compiler does not appear to be assigning the correct value to TICKS_PER_SECOND
Even more confusing is that if you define the ticks per second name in the use timer declaration the result becomes even more bizarre...
Pertaining to USE TIMER, The manual says:
"DEFINE=id --- Creates a define named id which specifies the number of ticks that will occur in one second. Default define name if not specified is TICKS_PER_SECOND. Define name must start with an ASCII letter 'A' to 'Z', an ASCII letter 'a' to 'z' or an ASCII underscore ('_')."
So wondering whether TICKS_PER_SECOND was being overwritten the Stack, I tried:
#use timer(timer=3,tick=1ms,bits=32, define=ticksPerSecond,NOISR)
Now instead of get_ticks()/TICKS_PER_SECOND resulting in a count that took 20 seconds to increment, get_ticks()/ticksPerSecond returns a number that is inordinately huge and increments at an inordinately rapid rate(~500,000,000 counts per second)...
So no closer to a solution...[/i] |
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
|
Posted: Tue Dec 15, 2015 8:00 am |
|
|
Ok, I am now convinced that the compiler is broken...
TICKS_PER_SECOND is always 24414 regardless of the tick timer setting... |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
Posted: Tue Dec 15, 2015 10:13 am |
|
|
25MHz / 4 (standard PIC18 clock divider) / 256 (Timer clock divider) = 24,414.0625
This is at best 40.96us per tick. Try lowering your tick value to say 10us or 1us and see if TICKS_PER_SECOND changes
#use timer(timer=3,tick=10us,bits=32,NOISR)
#use timer(timer=3,tick=1us,bits=32,NOISR)
You might be hitting a hardware limitation based on the chip settings you provided. |
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
SOLUTION... |
Posted: Tue Dec 15, 2015 1:21 pm |
|
|
TICKS_PER_SECOND is also defined by the Stack... The stack defines it as an integer, which overwrites the TICKS_PER_SECOND value derived from the CCS tick timer. This explains why the TICKS_PER_SECOND never changed.
Ok, so adding the DEFINE=TPS to the #USE TIMER directive told the CCS tick timer to use TPS instead of the default TICKS_PER_SECOND. This however, yielded even bigger errors, because unlike the Stack definition, the CCS compiler uses a float for the TICKS_PER_SECOND not an integer. The problem here is that the result of get_tick()/TPS is actually a float... Not a big deal unless you are trying to convert it to string using the %Lu formatter.
SO...
sprintf(retData, "%Lu",get_ticks()/TPS); // Format as Long Unsigned Int returned a massive number,
WHEREAS...
sprintf(retData, "%f",get_ticks()/TPS); //format as float returned sensible values. |
|
|
|
|
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
|