#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();
}
}
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
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;
}
}
void timer_isr()
{
[B]if(TMR0IF == 1)[/B]
...
void main()
{
...
while(1)
{
[B]timer_isr();[/B]
while(1)
{
timer_isr();
}
void timer_isr()
{
if(TMR0IF == 1){ // TMR0 overflowed
TMR0IF = 0; // Clear timer interrupt flag
TMR0IE = 1;
TMR0 = 0; //This value represents the in ms that will last the interrupt.
PORTAbits.RA0 = 0;
}
}
// code starts here...
void main()
{
....
//Timer0 Registers Prescaler= 256 - TMR0 Preset = 0 - Freq = 30.52 Hz - Period = 0.032768 seconds
OPTION_REG.T0CS = 0; // bit 5 TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
OPTION_REG.T0SE = 0; // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
OPTION_REG.PSA = 0; // bit 3 Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
OPTION_REG.PS2 = 1; // bits 2-0 PS2:PS0: Prescaler Rate Select bits
OPTION_REG.PS1 = 1;
OPTION_REG.PS0 = 1;
TMR0 = 0; // preset for timer register -----------------------------> why do they put this here >?
// Interrupt Registers
INTCON = 0; // clear the interrpt control register
INTCON.TMR0IE = 1; // bit5 TMR0 Overflow Interrupt Enable bit...1 = Enables the TMR0 interrupt
INTCON.TMR0IF = 0; // bit2 clear timer 0 interrupt flag
INTCON.GIE = 1; // bit7 global interrupt enable
while(1) //endless loop
{
}
}
So this can´t be 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 ?
the comment is not correct. In the ISR you will always read tmr0 to be 0 (unless you insert a long delay in the ISR), because it just has overflown from 255 to 0 (and this overflow started the ISR)TMR0 = 0; //This value represents the in ms that will last the interrupt.
#include <xc.h>
void __interrupt () my_isr_routine (void) {
// Timer0 Interrupt - Freq = 318.88 Hz - Period = 0.003136 seconds
if (INTCONbits.TMR0IF == 1) // timer 0 interrupt flag
{
PORTAbits.RA0 = 1; // Toggle PORTB bit0 LED
INTCONbits.TMR0IF = 0; // clear the flag
INTCONbits.TMR0IE = 1; // reenable the interrupt
TMR0 = 10; // reset the timer preset count
}
}
// code starts here...
void main()
{
// setup portb to show the interrupts by blibking LEDs
TRISA = 0x00; // PORT is all output...to show the interrupts
PORTA = 0; // start with all outputs low
//Timer0 Registers Prescaler= 32 - TMR0 Preset = 60 - Freq = 318.88 Hz - Period = 0.003136 seconds
OPTION_REG.T0CS = 0; // bit 5 TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
OPTION_REG.T0SE = 0; // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
OPTION_REG.PSA = 0; // bit 3 Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
OPTION_REG.PS2 = 1; // bits 2-0 PS2:PS0: Prescaler Rate Select bits
OPTION_REG.PS1 = 0;
OPTION_REG.PS0 = 0;
TMR0 = 60; // preset for timer register
// Interrupt Registers
INTCON = 0; // clear the interrpt control register
INTCONbits.TMR0IE = 1; // bit5 TMR0 Overflow Interrupt Enable bit...1 = Enables the TMR0 interrupt
INTCONbits.TMR0IF = 0; // bit2 clear timer 0 interrupt flag
INTCONbits.GIE = 1; // bit7 global interrupt enable
while(1) //endless loop
{
}
}
XOR with it self = switching OFF2. XOR it with itself.
So far so good. But you want it to blink. Blink means: OFF - wait - ON - Wait ....repeatedly.As for the bits, in the main body I am setting low only the bit the LED is attached to in PORTAbitsRA0, and I am leaving it off, in the ISR I am setting that same bit to high, isn't this how it is done ?
There is no "interrupt gone". The interrupt is a flag and it just makes the ISR to run. Once ... unless you don´t restart the timer.As for the toggle, my idea is in the main body of the program the LED is off, upon interrupt, it is on then after interrupt 'gone' LED is off again.
The "timer" is hardware, not software.With the explanation of betwixt, I understood why do we set value to TMR0 - basically we want TMR0 to cycle up to that value.
TMR0IF is just the INTERRUPT-FLAG. For sure it needs to be cleared to enable a now trigger of the ISR. But it won´t set the TMR0 to the desired value to get the desired delay. (251 in my example)I do not know if the timer restarts automatically I thought setting up TMR0IF to low resets it no ?
Just to be clear: with the IF bit set (and also the IE bit set of course) the ISR will be called. You *should* clear the IF flag in the ISR to make sure that the next time it is set by the hardware, the ISR will be called again.TMR0IF is just the INTERRUPT-FLAG. For sure it needs to be cleared to enable a now trigger of the ISR. But it won´t set the TMR0 to the desired value to get the desired delay. (251 in my example)
You shouldn't re-enable the interrupt inside the ISR because on PIC16 series processors the ISR is not re-entrant. That means you can't interrupt the ISR itself with a second one. However, before entering the ISR, the PIC hardware disables the GIE bit to prevent it trying and it re-enables it when it leaves the ISR. For normal use you don't have to re-enable it yourself. Note that the GIE stops interrupts being processed but it doesn't stop interrupts being noted. If an interrupt flag is set while you are inside an ISR it will be actioned as soon as the ISR exits. If interrupts have to be prioritized (in PICs that only have one interrupt level) you have to do it by arranging the order you check the interrupt flags inside the ISR code.
Brian.
if (INTCONbits.TMR0IF == 1) // timer 0 interrupt flag
{
PORTAbits.RA0 = 1; // ON PORTA bit0 LED
TMR0 = 60; // reset the timer preset count
INTCONbits.TMR0IF = 0;
}
#include <xc.h>
#define _XTAL_FREQ 20000000 //Specify the XTAL crystall FREQ
#pragma config FOSC = INTOSC // Configure PIC to use internal oscilator
void __interrupt () isr_routine (void) {
// Timer0 Interrupt - Freq = 30.52 Hz - Period = 0.032768 seconds
if (INTCONbits.TMR0IF == 1) // timer 0 interrupt flag
{
PORTAbits.RA0 = 1; // ON PORTA bit0 LED
TMR0 = 100; // reset the timer preset count
INTCONbits.TMR0IF = 0;
}
}
// code starts here...
void main()
{
// Oscilator set at 8 MHz oscilator config
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF3 = 0;
//Timer0 Registers Prescaler= 8 - TMR0 Preset = 100 - Freq = 1602.56 Hz - Period = 0.000624 seconds
OPTION_REGbits.T0CS = 0; // bit 5 TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
OPTION_REGbits.T0SE = 0; // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
OPTION_REGbits.PSA = 0; // bit 3 Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
OPTION_REGbits.PS2 = 0; // bits 2-0 PS2:PS0: Prescaler Rate Select bits
OPTION_REGbits.PS1 = 1;
OPTION_REGbits.PS0 = 0;
TMR0 = 100; // preset for timer register
// Interrupt Registers
INTCON = 0; // clear the interrpt control register
INTCONbits.TMR0IE = 1; // bit5 TMR0 Overflow Interrupt Enable bit...1 = Enables the TMR0 interrupt
INTCONbits.TMR0IF = 0; // bit2 clear timer 0 interrupt flag
INTCONbits.GIE = 1; // bit7 global interrupt enable
TRISA = 0x00; // PORT is all output...to show the interrupts
PORTAbits.RA0 = 0; // start with all outputs low
while(1) //endless loop
{
}
}
Let´s imagine the counter frequency is 1kHz. then it takes 1ms to count one step. 0 (1ms later) -> 1 (1ms later) -> 2 (1ms later) -> 3 (1ms later) -> 4 (1ms later) -> 5...
So it takes 256 counts then an overflow happens .. and the ISR runs.
Now let´s imagine you don´t want the ISR run every 256ms but every 5ms.
Then:
*Init: it to (256-5 =) 251
* (1ms later) -> 252
* (1ms later) -> 253
* (1ms later) -> 254
* (1ms later) -> 255
* (1ms later) -> 0 --> ISR trigger. Within the ISR set it to (256-5)= 251
* (1ms later) -> 252
* (1ms later) -> 253
* (1ms later) -> 254
* (1ms later) -> 255
* (1ms later) -> 0 --> ISR trigger. Within the ISR set it to (256-5)= 251
* (1ms later) -> 252
* (1ms later) -> 253
* (1ms later) -> 254
.. and so on
Klaus
No. Definitely not.If I understand you right you imply here must be 1 more line either above or under line PORTAbits.RA0 = 1; putting that bit to 0 correct ?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?