How do one arrive at 1.000s and 4.600s (with the 32MHz clock)?
BTW the second SETSMT1PERIOD should be SETSMT2PERIOD?
#Chip 16F18855, 32#option explicit#Include <SMT_Timers.h>#config CLKOUTEN_ON...SETSMT1PERIOD(4045000)' 1.000s period with the parameters of SMT_FOSC and SMTPres_1 within the clock variance of the interclock' a perfect internal clock would be 4000000SETSMT1PERIOD(9322401)' 4.600s period with the parameters of SMT_FOSC4 and SMTPres_8InitSMT1(SMT_FOSC,SMTPres_1)InitSMT2(SMT_FOSC4,SMTPres_8)...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If
InitSMT1(SMT_FOSC,SMTPres_1) and SETSMT1PERIOD ( 4045000 ) -> 1s period
How can
InitSMT2(SMT_FOSC4,SMTPres_8) and SETSMT2PERIOD ( 9322401 ) -> 4,6s period
The code was at some point changed from doing something else than just blinking LEDD2 and LEDD3?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Looking at the GCBASIC demos by BillR, the timer calculation is based on creating a 1-second interrupt interval using the SMT1 (Signal Measurement Timer) module.
'''--------------------------------------------------------------------------------------------------------------------------------'''ADebugProgramforSMTTimers.h'''WilliamR'#chip 16f18855, 32#option explicit#include<smt_timers.h>WAIT500MSDIRPortC.3OUT'LED'TuneinternalOSCforbestaccuracyso'that1,000,000timerticks=1,000,000usOSCTUNE=0b11111100'FOSC4=8MHz/8=1MHzInitSMT1(SMT_FOSC4,SMTPres_8)'1MHz'Period=1,000,000microseconds(1Second)SETSMT1PERIOD(1000391)'Finetunehereasnecessary'InterrupteverysecondandblinkLEDfor100msOnInterruptSMT1OverflowCallBlinkLED'Startthe24-bitSMT1timerSTARTSMT1'// After making changes, Chip must run for at least'// 1 minute after POR or Reset before an accuraate measurement'// can be taken. This Particular chip seems to slowing increase in'// speed over the first 30 sec to 1 minuteMAIN:Do'// waiting for interrupt...LoopENDMAIN:SubBlinkLEDSetPORTC.3OnWait100msSetPortC.3OffEndsub
OSCTUNE adjustment - The code sets OSCTUNE = 0b11111100 to fine-tune the oscillator frequency
Temperature/voltage drift - As noted in the comments, the chip's speed changes over the first 30-60 seconds after power-on
Summary
The timer is configured to tick at exactly 1 MHz (1 tick per microsecond), and the period value of 1,000,391 is empirically tuned to achieve an accurate 1-second interrupt interval despite internal oscillator variations. The developer likely measured the actual timing and adjusted this value until the LED blinked precisely once per second.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
'''--------------------------------------------------------------------------------------------------------------------------------'''ADebugProgramforSMTTimers.h'''WilliamR'#chip 16f18855, 32#option explicit#include<smt_timers.h>WAIT500MSDIRPortC.3OUT'LED'TuneinternalOSCforbestaccuracyso'that1,000,000timerticks=1,000,000usOSCTUNE=0b11111100InitSMT1(SMT_FOSC,SMTPres_1)'1MHz'Period=1,000,000microseconds(1Second)SETSMT1PERIOD(16000000)'Finetunehereasnecessary'InterrupteverysecondandblinkLEDfor100msOnInterruptSMT1OverflowCallBlinkLED'Startthe24-bitSMT1timerSTARTSMT1'// After making changes, Chip must run for at least'// 1 minute after POR or Reset before an accuraate measurement'// can be taken. This Particular chip seems to slowing increase in'// speed over the first 30 sec to 1 minuteMAIN:'''PickYourPoison'''SevenDifferentWaystoget1secondPeriodDo'1HZSETSMT1PERIOD(8000000)InitSMT1(SMT_FOSC4,SMTPres_1)ClearSMT1StartSMT1Wait10sStopSMT1Wait2s'Also1hzSETSMT1PERIOD(2000000)InitSMT1(SMT_FOSC4,SMTPres_4)CLEARSMT1StartSMT1Wait10sStopSMT1Wait2s'Also1HzSETSMT1PERIOD(1000000)InitSMT1(SMT_FOSC4,SMTPres_8)ClearSMT1StartSMT1Wait10sStopSMT1Wait2s'Also1HzSETSMT1PERIOD(4000000)InitSMT1(SMT_HFINTOSC,SMTPres_8)'16/2ClearSMT1StartSMT1Wait10sStopSMT1Wait2s'Also1HzSETSMT1PERIOD(500000)InitSMT1(SMT_MFINTOSC,SMTPres_1)ClearSMT1StartSMT1Wait10sStopSMT1Wait2s'Also1HzSETSMT1PERIOD(31500)InitSMT1(SMT_MFINTOSC_16,SMTPres_1)ClearSMT1StartSMT1Wait10sStopSMT1Wait2s'Also1HzSETSMT1PERIOD(31500)InitSMT1(SMT_LFINTOSC,SMTPres_1)ClearSMT1StartSMT1Wait10sStopSMT1Wait2sLoopENDMAIN:SubBlinkLEDSetPORTC.3OnWait100msSetPortC.3OffEndsub
This code demonstrates seven different timer configurations that all achieve the same 1-second period, using different clock sources and prescaler combinations. Here's the analysis:
Note: The 31.5 kHz assumed frequency accounts for typical LFINTOSC variation.
Summary
This is a test/calibration program showing multiple ways to achieve ~1 second timing:
- High-speed sources (FOSC, FOSC/4, HFINTOSC) use large period counts
- Low-speed sources (LFINTOSC, MFINTOSC) use smaller period counts
- The empirical tuning (e.g., 31,500 vs theoretical 31,250) compensates for internal oscillator inaccuracies
- The OSCTUNE setting adjusts the main oscillator for better accuracy
- Configuration #4 appears to have a calculation error (should be 2,000,000, not 4,000,000)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
While you replied I had hooked it up and got it working on 18F57Q84. I should have done that sooner and not kept staring at the code example...
And yes the code has probably been chopped up and changed. That is why the figures didn't make sense. I could remove #config CLKOUTEN_ON which added to the confusion as I saw no purpose. SMT_FOSC didn't work on this chip while changing to FOSC did.
This could be the sample clock that I have been looking for. High resolution and no startup procedure for each revolution (like the 16bit clock).
This works as expected (32000000/4000000/2=4Hz):
#Chip 18F57q84, 32
#option explicit
#Include <SMT_Timers.h>
Dir PORTA.0 OUT
SETSMT1PERIOD ( 4000000 ) ' 0.25s complete on-off period
InitSMT1(FOSC,SMTPres_1)
On Interrupt SMT1Overflow Call BlinkLED
StartSMT1
Do
'// Waiting for interrupts
LOOP
Sub BlinkLED
PORTA.0 = !PORTA.0
End SUB
Last edit: Roger Jönsson 2026-01-30
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In this example at: https://gcbasic.sourceforge.io/help/_smt_timers.html
How do one arrive at 1.000s and 4.600s (with the 32MHz clock)?
BTW the second SETSMT1PERIOD should be SETSMT2PERIOD?
Is the question 'how to do the SMT calcs'?
I will correct the Help.
Yes. While trying to figure it out I stalled at:
If
InitSMT1(SMT_FOSC,SMTPres_1) and SETSMT1PERIOD ( 4045000 ) -> 1s period
How can
InitSMT2(SMT_FOSC4,SMTPres_8) and SETSMT2PERIOD ( 9322401 ) -> 4,6s period
The code was at some point changed from doing something else than just blinking LEDD2 and LEDD3?
Bill Roth was the expert on SMT. He passed away last year. :-(
The most relevant application note / technical brief for it is TB3129 – "Signal Measurement Timer on PIC MCUs".
Direct PDF URL:
https://ww1.microchip.com/downloads/en/appnotes/90003129a.pdf
This document explains the SMT module's features, configuration, modes (like period/duty cycle measurement, time-of-flight, etc.), and code examples.
If you're looking for something more specific (e.g., auto-calibration using SMT in AN2030):
https://ww1.microchip.com/downloads/en/Appnotes/00002030A.pdf
Looking at the GCBASIC demos by BillR, the timer calculation is based on creating a 1-second interrupt interval using the SMT1 (Signal Measurement Timer) module.
Here's my breakdown:
Timer Calculation Basis
Clock Source Configuration:
- Main oscillator: 32 MHz (from
#chip 16f18855, 32)- Timer uses FOSC/4 = 32MHz / 4 = 8 MHz
- Prescaler divides by 8: 8 MHz / 8 = 1 MHz timer clock
Timer Tick Rate:
- At 1 MHz, each timer tick = 1 microsecond
- For a 1-second period, you'd theoretically need 1,000,000 ticks
The Key Value:
This sets the timer to count 1,000,391 ticks instead of 1,000,000. The extra 391 ticks (0.0391% adjustment) compensates for:
OSCTUNE = 0b11111100to fine-tune the oscillator frequencySummary
The timer is configured to tick at exactly 1 MHz (1 tick per microsecond), and the period value of 1,000,391 is empirically tuned to achieve an accurate 1-second interrupt interval despite internal oscillator variations. The developer likely measured the actual timing and adjusted this value until the LED blinked precisely once per second.
My analysis of Bill's other demo.
This code demonstrates seven different timer configurations that all achieve the same 1-second period, using different clock sources and prescaler combinations. Here's the analysis:
Initial Configuration (unused in main loop)
The Seven "1 Hz" Configurations
1. FOSC/4, Prescaler 1:1
2. FOSC/4, Prescaler 1:4
3. FOSC/4, Prescaler 1:8
4. HFINTOSC, Prescaler 1:8
Note: This appears to have an error - should be 2,000,000 for 1 second.
5. MFINTOSC, Prescaler 1:1
6. MFINTOSC/16, Prescaler 1:1
Note: Should be 31,250 for exactly 1 second; 31,500 is empirically tuned.
7. LFINTOSC, Prescaler 1:1
Note: The 31.5 kHz assumed frequency accounts for typical LFINTOSC variation.
Summary
This is a test/calibration program showing multiple ways to achieve ~1 second timing:
- High-speed sources (FOSC, FOSC/4, HFINTOSC) use large period counts
- Low-speed sources (LFINTOSC, MFINTOSC) use smaller period counts
- The empirical tuning (e.g., 31,500 vs theoretical 31,250) compensates for internal oscillator inaccuracies
- The OSCTUNE setting adjusts the main oscillator for better accuracy
- Configuration #4 appears to have a calculation error (should be 2,000,000, not 4,000,000)
Ouch! :(
-A moment of silence-
While you replied I had hooked it up and got it working on 18F57Q84. I should have done that sooner and not kept staring at the code example...
And yes the code has probably been chopped up and changed. That is why the figures didn't make sense. I could remove #config CLKOUTEN_ON which added to the confusion as I saw no purpose. SMT_FOSC didn't work on this chip while changing to FOSC did.
This could be the sample clock that I have been looking for. High resolution and no startup procedure for each revolution (like the 16bit clock).
This works as expected (32000000/4000000/2=4Hz):
Last edit: Roger Jönsson 2026-01-30
It is a great method!!
Yes, but I wish I had recorded it. I could have released it as a movie: "Staring at code".
I have seen that movie!! :-)