View previous topic :: View next topic |
Author |
Message |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
timer basics |
Posted: Thu Sep 01, 2016 2:47 am |
|
|
Gents, Good day ; )
I know it was million times on the agenda but I need clarification please:
PIC 18F4620 - clock 40MHz. Oscillator 10Mhz (x4 = 40Mhz).
1 timer cycle is FOSC/4. Correct? Or 1 timer cycle = 1 FOSC cycle?
pre-scaler set to 1:1
Then by reading whatever I can find it would work out that 1/(FOSC/4) = tick
So single timer tick would be 0.0000001s
Timer0 is 8bit which is irrelevant here as I am after single tick time.
So I did an experiment and program timer0 to advance 16 bit variable then measured it and calculated its time from physical RTC advancing. It worked out to me that single tick is 40us long. But by above calculation it should be 10us.
Is there any simple way to tell how it is going to work out, I am confused very much. Thnx 4 helping. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Thu Sep 01, 2016 4:05 am |
|
|
Check the fuses, I think PLL is not enabled so you get 40us instead of 10us
Best wishes
Joe |
|
![](templates/subSilver/images/spacer.gif) |
Faderick
Joined: 01 Sep 2016 Posts: 1
|
ss |
Posted: Thu Sep 01, 2016 5:31 am |
|
|
Great !!! I love it. You can be make it easy. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 01, 2016 10:30 am |
|
|
Quote: | So single timer tick would be 0.0000001s
But by above calculation it should be 10us. |
The first number 1/10 of a usec. That's 0.1 us, or 100 ns.
Quote: |
So I did an experiment and program timer0 to advance 16 bit variable
then measured it and calculated its time from physical RTC advancing. |
Post the test program for your experiment. |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Mon Sep 05, 2016 2:22 am |
|
|
Sorry, been busy. I have cleaned it a bit so is not messy...
655350 timer cycles is 26s so it works out 40us per timer cycle/tick if I am not wrong.
Code: |
*************************************************************************
* *
* Architecture: Midrange PIC *
* Processor: 18F4620 *
* Compiler: CCSC 4.046 *
* *
************************************************************************/
// PROCESSOR ======================
#include <18F4620.h>
// ================================
// FUSES ==========================
#include "fusesdefinitions.c"
// ================================
// DEVICE =========================
#device ADC=10
//#DEVICE HIGH_INTS=TRUE
// ================================
// DEFINE =========================
#define AD5242_WRT_ADDR 0x58
#define AD5242_RD_ADDR 0x59
#include "hardwaredefinitions.c"
#define BUSSPEED 115200
// ================================
// USE ============================
#use delay (clock=40M)
#use rs232(baud=BUSSPEED,xmit=TX,rcv=RX,parity=n,bits=8,stop=1,RESTART_WDT,ENABLE=TX_ON,ERRORS,TIMEOUT=15)
#use i2c(master, sda=I2CSDA, scl=I2CSCL, FORCE_HW, SMBUS, FAST=100000)
#use fixed_io(D_outputs=LCD_DB4,LCD_DB5,LCD_DB6,LCD_DB7,BCK_LIGHT,STATUSLED)
#use fixed_io(A_outputs=) //
#use fixed_io(B_outputs=LCD_RS,LCD_RW,LCD_E) //LCD_RS,LCD_RW,LCD_E
#use fixed_io(C_outputs=TX_ON,TX,SLOT17,SLOT18) //
// ================================
// INCLUDE ========================
#include <ctype.h>
#include <stddef.h>
#include <string.h>
#include "setsystem.c"
#include "variables.c"
#include "i2c.c"
#include "rtc.c"
#include "timer.c"
#include <\BTLD\bootloader.h>
// ================================
// SYSTEM =========================
#INT_RDA //HIGH
void comms_rda(VOID)
{
byte c;
c = getc();
}
// ================================
// MAIN PROGRAM ===================
#zero_ram
void main()
{
setsystem ();
WHILE (true)
{
restart_wdt ();
if (print_time == 1)
{
get_time ();
printf ("\rDATE/TIME: %02d-%02d-%02d %02d:%02d:%02d %u\r\n", day, mth, year, hr, min, sec, dow);
print_time = 0;
}
} //WHILE
} //VOID
//===================================
|
Code: |
// "timer.c"
// TIMER 0 ==========================
#INT_TIMER0
//65535 x 10 = 655350 = ~26s//
void timer0_isr(VOID)
{
timer8++;
timer16++;
IF (timer16 == 0)
{
output_high (STATUSLED);
}
IF (timer16 == 0xFFFF)
{
timer16_1++;
}
IF (timer16_1 == 0x10)
{
output_low (STATUSLED);
print_time = 1;
timer16_1 = 0; }
}
//===================================
#INT_TIMER1
// TIMER 1 ==========================
void timer1_isr(VOID)
{
}
//===================================
|
Code: |
// setsystem.c
// SET UP THE SYSTEM ================
void setsystem(VOID)
{
setup_wdt (WDT_ON);
output_FLOAT (I2CSCL);
output_FLOAT (I2CSDA);
disable_interrupts (GLOBAL);
setup_timer_0 (RTCC_INTERNAL|RTCC_8_BIT|T0_DIV_1);
setup_timer_1 (T1_INTERNAL|T1_DIV_BY_1);
set_timer1 (0);
set_timer0 (0);
setup_adc (ADC_OFF);
setup_comparator (NC_NC_NC_NC);
enable_interrupts (INT_rda);
enable_interrupts (INT_RTCC);
enable_interrupts (INT_TIMER1);
enable_interrupts (GLOBAL);
}
|
Code: |
// FUSES ============================
#FUSES H4
#FUSES MCLR
#FUSES BROWNOUT
#FUSES NODEBUG
#FUSES PROTECT
#FUSES CPB
#FUSES CPD
#FUSES NOEBTRB
#FUSES NOEBTR
#FUSES WDT4096
#FUSES WDT
#FUSES PUT
#FUSES NOXINST
//=================================== |
_________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Sep 05, 2016 3:09 am |
|
|
That is not even remotely a tidy version.
However glaring fault. 0x10 != 10..... |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Mon Sep 05, 2016 3:13 am |
|
|
; ) that is striking correct. 0x10 is not 10. I agree, I shall retest. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Sep 05, 2016 4:12 am |
|
|
Code: |
#include <18F4620.h>
#FUSES H4
#FUSES MCLR
#FUSES BROWNOUT
#FUSES NODEBUG
#FUSES NOPROTECT
#FUSES NOEBTRB
#FUSES NOEBTR
#FUSES WDT4096
#FUSES NOWDT
#FUSES PUT
#FUSES NOXINST
#use delay (clock=40M)
#define STATUS_LED PIN_D5
#INT_TIMER1
void timer1_isr(void)
{
output_toggle(STATUS_LED);
}
void main(void)
{
setup_timer_1 (T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while (TRUE)
delay_cycles(1);
}
|
Stuck this into a 4620.
D5 toggles about every 6.5mSec on the scope.
40000000/(4*65536) = 152*/sec = 6.5mSec
Comments:
4.046, is before the V4 compilers were generally considered to be working. I used 4.070, which is the earliest V4 compiler I've kept.
Don't use 'PROTECT' when developing code. Doing so forces a full chip erase and uses chip lives pointlessly.
'How to write a simple program to test one thing'...... |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Mon Sep 05, 2016 5:06 am |
|
|
Two comments
1) for a SW RTC, look at the working program in the Code Library here. Works on any PIC at any speed and is accurate. Though with any SW RTC you MUST design/build proper battery backup to ensure power is NEVER lost...
2) do not use the WDT until the product is ready to be shipped to customer. Only then cut the code and test it. There is no reason to enable it during the development/test phase and can actually cause problems unless you handle it properly. In over 2o years, I've only needed WDT on 2 or 3 products, even then it was not really needed but a spec the client insisted upon.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Tue Sep 06, 2016 12:50 am |
|
|
Thnx Guys, great help. Sorry 4.046 is a typo, should be 5.046. _________________ Help "d" others and then you shell receive some help from "d" others.
Last edited by Linuxbuilders on Tue Sep 06, 2016 1:50 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Tue Sep 06, 2016 1:50 am |
|
|
So corrected my program, and it works out //65535 x 10 = 655350 = 17s//
So I need 38550 ticks to do 1s. So one tick is 25.94033722438392us.
Verified with RTC and it is correct. 38550 ticks falls on every 1s spot on.
I guess here hardware will play a role, and 10MHz oscillators and caps will drive the processor with some small error and this is where the error is visible.
Thnx for helping, much appreciated. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue Sep 06, 2016 2:49 am |
|
|
Take a step back and do the old 1 second 'flash an LED' program.
It really does sound as if your chip is not running off the clock you think it is. A crystal would normally be better than one part in 10000 (even a poor one), and you are out by a factor of nearly three. I suspect you are actually running off something like the 16MHz internal oscillator, not the 40Mhz you think you are.
The basic 'flash an led' program should be your first port of call, when any form of timing problem is seen. |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Tue Sep 06, 2016 2:54 am |
|
|
How would this be possible? How can I run of 16MHz if the chip is set to 40?
I'll put it on oscilloscope and check over a weekend. Manufacturing had wrong caps on it initially and had to resolder/fix the whole run, I would not be surprised they have put some wrong caps and I did not check... I will report after I find what is going on. It is interesting to find that OSC will run with wrong caps but will offset its FREQ to the value out of the blue so to speak. Thnx _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue Sep 06, 2016 3:10 am |
|
|
More likely the oscillator is not actually running. The chip has a feature 'fail safe clock monitor', that if the main oscillator does not start, it'll attempt to use the internal source. |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Tue Sep 06, 2016 3:18 am |
|
|
So this is correct, I do delay 1000ms on a main loop and measure it. It takes over 3 seconds to do one second.
This chip is using H4 to gain 40MHz out of 10MHz crystal.
Would it be possible that this particular chip clocks timers as per physical OSC not as H4? I will dig this in datasheet later on. Now time to sleep. Good night. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
|