Trying out and trying to understand Timer0 HFINTOSC interrupts.
When making it fire fast (HFINTOSC/64) it seems to go into a wall and the output of the subroutine does not fire any quicker. I'm guessing it has to do with either the interrupt-call or resetting things?
Is it GCbasic having to to a bunch of stuff on and after each reset or is it hardware related?
Prescaler divisions:
PRE0_256 fires each 16us
PRE0_128 fires each 8us
PRE0_64 fires each 8us
PRE0_32 fires each 7us
Interrupt flag reset TMR0IF = 0 has no effect, so I'm guessing gcbasic handles it in some other way.
For my current project PRE0_128 is enough, so not much of a thing at this time other than trying to understand, but Is there a more efficitent way?
#CHIP 16F15376,32
#OPTION EXPLICIT
DIR PORTA.7 out
'1.InitTimer0 source (osc or ext), prescaler, clocksource, postscaler
'2.SetTimer ( 0, byte_value, value), or
' SetTimer ( 0, word_value (where the high byte sets the timer), value)
'3.StartTimer 0
' (optionally use ClearTimer 0)
InitTimer0 OSC, PRE0_256 + TMR0_HFINTOSC, POST0_1 '32MHz/256/1=125KHz
Settimer (0, 0x0100)'125/2 = 62,5KHz
StartTimer 0
On Interrupt Timer0Overflow call MyISR
Do
Loop
Sub MyISR
PORTA.7 = !PORTA.7
PORTA.7 = !PORTA.7
'TMR0IF = 0
End Sub
Last edit: Roger Jönsson 2025-03-08
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For the Timer0 it is a 16bit timer. So, the program needs to have added.
'Firstly tell the compiler to use a 16bit timer for this program
#DEFINE TMR0_16BIT
There are some demos for this chip - see C:\GCstudio\gcbasic\demos\Vendor_Boards\MPLAB_Xpress_Board_PIC16F15376\09_Interrupt_using_Timer0_to_LED.gcb and all the files in the same folder.
You are correct. TMR0IF is handled by GCBASIC. See PICInfo ( Interrupt Tab ) for the enable and event bits that are managed by GCBASIC.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried the 16-bit timer yesterday without any improvement on these quick repetitions. Also (if I understand it correctly) I have to set the 16-bit SETtimer value (FFFF = shortest time) after the code in the subroutine called by the interrupt (at least I couldn't make it run the code inside otherwise) so I guess it skips out of that subroutine immediately and prepares for a new interrupt) and so the longer the length of the code in the subroutine the more it hurts the cycle time.
At the moment I am generating more than one square wave simultaneously (loops with counters adding 1 for each interrupt) and it works beautifully in the 8bit mode and the frequencies stays the same with more generator loops added. I have no idea how the flag reset (tex) is done, but it doesn't seem to come in conflict with my tone/voice generators generated.
In 16 bit mode (the only way I got it to work, setting the timer after the "voices" generated at the end of the subroutine), the more "voices" added the lower the cycle time. I couldn't get the interrupt cycle time much faster than in 8-bit mode unless the subroutine called was practically empty.
I will have a look at the demos and see if there is something useful.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
May be I do not understand. What time frequency are you requiring? This is a fact I do not know.9
I think the sub routine you are referring to is the interrupt handler, If yes, then, you will have STEPS_TO_DETERMINE_IT_IS_THE_CORRECT_ISR + YOUR_ISR. This is the latency.
If TEX is TMR0IF then this is completed automatically in the ASM. See the generated ASM file for this logic,
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It's about few KHz output tops from the code in the interrupt handler subroutine. I don't really require much faster at this time, but a faster cycle time yeilds better frequency resolution (more counter laps to set the required frequency) so I tested the limits. The steady stream of interupts is like a master clock for the tone generators I described. I stumbled on the fact that it stalled at 8us figuring that there was place for many instructions during that time and just wondered why it stalled. -Well all is relative. :)
So what I am doing is producing more than one square wave with independent frequencies simultantously and I can run some other code in between interrupts. I haven't decided what to use it for yet. -A one chip music box maybe? Controlling a big bank of PWM servos? Not quite sure yet, but it is like multitasking so it may yeild something useful.
Here I make two independent stable frequency squarewaves which I turn on and off "by remote" in the eternal do-loop, by starting and stopping the timer. For fun I mixed the tow squarewaves together so I can hear both with a small speaker connected to RA3.
#CHIP 16F15376,32
#OPTION EXPLICIT
DIR PORTA.7 out
DIR PORTA.6 out
DIR PORTA.5 out
DIR PORTA.3 out
dim ton1 as Byte
dim ton2 as Byte
dim mixer as byte
InitTimer0 OSC, PRE0_256 + TMR0_HFINTOSC, POST0_1 ''32MHz/256/1=125KHz
Settimer (0, 0x0100) '125/2 = 62,5KHz
StartTimer 0
On Interrupt Timer0Overflow call MyISR
Do 'beep, beep, beep....
StopTimer 0
wait 500 ms
InitTimer0 OSC, PRE0_256 + TMR0_HFINTOSC, POST0_1 ''32MHz/256/1=125KHz
Settimer (0, 0x0100) '125/2 = 62,5KHz
StartTimer 0
On Interrupt Timer0Overflow call MyISR
wait 500 ms
Loop
Sub MyISR 'Play two (or more) simultaneous squarewaves.
PORTA.7 = 1 'output to monitor how often the interrupt fires
PORTA.7 = 0
ton1 = ton1 + 1
if ton1 = 127 then 'time between polarity shifts = about 246Hz
PORTA.6 = !PORTA.6
ton1 = 0
end if
ton2 = ton2 + 1
if ton2 = 100 then '= about 312Hz squarewave output on PORTA.5
PORTA.5 = !PORTA.5
ton2 = 0
end if
mixer = mixer + 1
if mixer = 1 then 'multiplexes between the tones
PORTA.3 = PORTA.6
end if
if mixer = 2 then
PORTA.3 = PORTA.5
mixer = 0 'resets/nulls the mixer counter on last ton
end if
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I installed the GCStudio IDE complete package couple of months ago and got it updated a week or so ago. I looked at both gcbasic.sourceforge.io and gcbasic.com but I could not find a demos package, but I now did found the files in Denomstration_sources behind "Learn From Code" at gcbasic.com.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Trying out and trying to understand Timer0 HFINTOSC interrupts.
When making it fire fast (HFINTOSC/64) it seems to go into a wall and the output of the subroutine does not fire any quicker. I'm guessing it has to do with either the interrupt-call or resetting things?
Is it GCbasic having to to a bunch of stuff on and after each reset or is it hardware related?
Prescaler divisions:
PRE0_256 fires each 16us
PRE0_128 fires each 8us
PRE0_64 fires each 8us
PRE0_32 fires each 7us
Interrupt flag reset TMR0IF = 0 has no effect, so I'm guessing gcbasic handles it in some other way.
For my current project PRE0_128 is enough, so not much of a thing at this time other than trying to understand, but Is there a more efficitent way?
Last edit: Roger Jönsson 2025-03-08
For the Timer0 it is a 16bit timer. So, the program needs to have added.
There are some demos for this chip - see C:\GCstudio\gcbasic\demos\Vendor_Boards\MPLAB_Xpress_Board_PIC16F15376\09_Interrupt_using_Timer0_to_LED.gcb and all the files in the same folder.
You are correct. TMR0IF is handled by GCBASIC. See PICInfo ( Interrupt Tab ) for the enable and event bits that are managed by GCBASIC.
I tried the 16-bit timer yesterday without any improvement on these quick repetitions. Also (if I understand it correctly) I have to set the 16-bit SETtimer value (FFFF = shortest time) after the code in the subroutine called by the interrupt (at least I couldn't make it run the code inside otherwise) so I guess it skips out of that subroutine immediately and prepares for a new interrupt) and so the longer the length of the code in the subroutine the more it hurts the cycle time.
At the moment I am generating more than one square wave simultaneously (loops with counters adding 1 for each interrupt) and it works beautifully in the 8bit mode and the frequencies stays the same with more generator loops added. I have no idea how the flag reset (tex) is done, but it doesn't seem to come in conflict with my tone/voice generators generated.
In 16 bit mode (the only way I got it to work, setting the timer after the "voices" generated at the end of the subroutine), the more "voices" added the lower the cycle time. I couldn't get the interrupt cycle time much faster than in 8-bit mode unless the subroutine called was practically empty.
I will have a look at the demos and see if there is something useful.
May be I do not understand. What time frequency are you requiring? This is a fact I do not know.9
I think the sub routine you are referring to is the interrupt handler, If yes, then, you will have STEPS_TO_DETERMINE_IT_IS_THE_CORRECT_ISR + YOUR_ISR. This is the latency.
If TEX is TMR0IF then this is completed automatically in the ASM. See the generated ASM file for this logic,
It's about few KHz output tops from the code in the interrupt handler subroutine. I don't really require much faster at this time, but a faster cycle time yeilds better frequency resolution (more counter laps to set the required frequency) so I tested the limits. The steady stream of interupts is like a master clock for the tone generators I described. I stumbled on the fact that it stalled at 8us figuring that there was place for many instructions during that time and just wondered why it stalled. -Well all is relative. :)
So what I am doing is producing more than one square wave with independent frequencies simultantously and I can run some other code in between interrupts. I haven't decided what to use it for yet. -A one chip music box maybe? Controlling a big bank of PWM servos? Not quite sure yet, but it is like multitasking so it may yeild something useful.
Here I make two independent stable frequency squarewaves which I turn on and off "by remote" in the eternal do-loop, by starting and stopping the timer. For fun I mixed the tow squarewaves together so I can hear both with a small speaker connected to RA3.
There is no Vendor_Boards folder inside my C:\GCstudio\gcbasic\demos
just two GCB Files, a read me and "this_is_useful_list_of_tools_for_the_ide"
Have you installed the Demos? You can download from GCSTUDIO front page.
I installed the GCStudio IDE complete package couple of months ago and got it updated a week or so ago. I looked at both gcbasic.sourceforge.io and gcbasic.com but I could not find a demos package, but I now did found the files in Denomstration_sources behind "Learn From Code" at gcbasic.com.
Here is the link from GCSTUDIO,
Last edit: Anobium 2025-03-10
Sigh.
:)
-Thanks!