GeorgeAD
Newbie level 4
Hello folks,
Being bored with databases and data warehouses I decided to poke around in an area I always liked.
picked up a starter pickit3 with the up mentioned MCU, quickly blinked a LED, then decided I really enjoy this whole stuff and started digging deeper. I am having some difficulties however controlling the blinking LED with a Timer interrupt. I came across https://www.edaboard.com/showthread...-timer0-to-generate-a-1-ms-or-1-sec-interrupt
First and foremost that formula calculating what value should I assign to the TMR0 bit saved my bacon and created some questions.
I came up with the following code
first question would be do I correctly set up Timer0 ?
second question would be if my oscilator is properly set at 8 Mhz ? -> reason I chose 8 MHz is to have Timer0
'work' at 2 Mhz, according the datasheet Timer0 uses Fosc / 4.
I'd appreciate any comment if the settings bits are fine.
Now to the real struggle based on the above mentioned thread configuring Timer0 shouldn't be that hard.
First question, do I understand this correctly: the value assigned to TMR0 bit, is sort of representation of the cycles needed to reach certain time, the interrupt flag of the timer0 is set up when Timer0 performs enough cycles hitting the value in TMR0. knowing that the value in TMR0 represents lets say 5 ms ?
Looking at my interrupt handling routing, I'd like to get half a second delay.
Oscilator works at 4Mhz, the clock works at 1 Mhz with prescaller set to 1:128 - by the way I am still having huge difficulties understanding what is that prescaller for.
So 1MHz is approx. 1 uSec, my timer should increment once every 1 usec
Now I want 50ms delay or 0.05 seconds
50ms/1uSec = 50000 cycles ? -> is that correct ?
Now knowing Timer0 overflows at 0xFFFF, the value I have to assign to TMR0 is 0xFFFF-0xC350 = 3CAF or for normal people 15535 is that correct ?
So if I put a variable to increment on every interrupt occurrence can I deduce that 2 interrupts should provide me 0.1 seconds delay, and 10 will provide me half a second ?
This my function should light up the LED for half a second ?
Thank you in advance to whoever decides to look into this, my ultimate goal is to build myself a robot (optionally to bring me beer)
George
Being bored with databases and data warehouses I decided to poke around in an area I always liked.
picked up a starter pickit3 with the up mentioned MCU, quickly blinked a LED, then decided I really enjoy this whole stuff and started digging deeper. I am having some difficulties however controlling the blinking LED with a Timer interrupt. I came across https://www.edaboard.com/showthread...-timer0-to-generate-a-1-ms-or-1-sec-interrupt
First and foremost that formula calculating what value should I assign to the TMR0 bit saved my bacon and created some questions.
I came up with the following code
Code:
#include <xc.h>
#define _XTAL_FREQ 20000000 //Specify the XTAL crystall FREQ
#pragma config FOSC = INTOSC // Configure PIC to use internal oscilator
int count = 0;
void timer_isr()
{
if(TMR0IF == 1) { // TMR0 overflowed
TMR0IF = 0; // Clear timer interrupt flag
TMR0 = 0; //This value represents the in ms that will last the interrupt.
count++; // stores how many interrupts occurred for instance if you need 30 ms seconds interrupt
// TMR0IF has to
}
if (count == 211)
{
PORTAbits.RA0 = 1; // LED on
count=0;
}
}
/***** MAIN PROGRAM *****/
void main()
{
OSCCONbits.IRCF0 = 0; // 8 MHz oscilator config
OSCCONbits.IRCF1 = 1; // 8 MHz oscilator config
OSCCONbits.IRCF2 = 1; // 8 MHz oscilator config
OSCCONbits.IRCF3 = 1; // 8 MHz oscilator config
/** TIMER0 setup **/
OPTION_REGbits.TMR0CS = 0; // 8bit Timer mode selected
OPTION_REGbits.TMR0SE = 0; // Setting low2high edge
OPTION_REGbits.PSA = 0; // Select prescaler
OPTION_REGbits.PS0 = 1; // Setting prescaler Rate
OPTION_REGbits.PS1 = 1; // Setting prescaler Rate
OPTION_REGbits.PS2 = 0; // Setting prescaler Rate
INTCONbits.TMR0IE = 1; //Enable timer interrupt bit in PIE1 register
INTCONbits.GIE=1; //Enable Global Interrupt
INTCONbits.PEIE=1; // Emable peripherial Interrupt
TRISA = 0; // Setting PORTA as an output.
PORTAbits.RA0 = 0; //LED off
//*** Main loop
while(1)
{
timer_isr();
}
}
first question would be do I correctly set up Timer0 ?
Code:
OPTION_REGbits.TMR0CS = 0; // 8bit Timer mode selected
OPTION_REGbits.TMR0SE = 0; // Setting low2high edge
OPTION_REGbits.PSA = 0; // Select prescaler
OPTION_REGbits.PS0 = 1; // Setting prescaler Rate
OPTION_REGbits.PS1 = 1; // Setting prescaler Rate
OPTION_REGbits.PS2 = 1; // Setting prescaler Rate
second question would be if my oscilator is properly set at 8 Mhz ? -> reason I chose 8 MHz is to have Timer0
'work' at 2 Mhz, according the datasheet Timer0 uses Fosc / 4.
I'd appreciate any comment if the settings bits are fine.
Now to the real struggle based on the above mentioned thread configuring Timer0 shouldn't be that hard.
First question, do I understand this correctly: the value assigned to TMR0 bit, is sort of representation of the cycles needed to reach certain time, the interrupt flag of the timer0 is set up when Timer0 performs enough cycles hitting the value in TMR0. knowing that the value in TMR0 represents lets say 5 ms ?
Looking at my interrupt handling routing, I'd like to get half a second delay.
Oscilator works at 4Mhz, the clock works at 1 Mhz with prescaller set to 1:128 - by the way I am still having huge difficulties understanding what is that prescaller for.
So 1MHz is approx. 1 uSec, my timer should increment once every 1 usec
Now I want 50ms delay or 0.05 seconds
50ms/1uSec = 50000 cycles ? -> is that correct ?
Now knowing Timer0 overflows at 0xFFFF, the value I have to assign to TMR0 is 0xFFFF-0xC350 = 3CAF or for normal people 15535 is that correct ?
So if I put a variable to increment on every interrupt occurrence can I deduce that 2 interrupts should provide me 0.1 seconds delay, and 10 will provide me half a second ?
This my function should light up the LED for half a second ?
Code:
void timer_isr()
{
if(TMR0IF == 1) { // TMR0 overflowed
TMR0IF = 0; // Clear timer interrupt flag
TMR0 = 15535; //This value represents the in ms that will last the interrupt.
count++; // stores how many interrupts occurred for instance if you need 30 ms seconds interrupt
// TMR0IF has to
}
if (count == 10)
{
PORTAbits.RA0 = 1; // LED on
count=0;
}
}
Thank you in advance to whoever decides to look into this, my ultimate goal is to build myself a robot (optionally to bring me beer)
George