Garyl
Full Member level 5
- Joined
- Mar 28, 2017
- Messages
- 253
- Helped
- 6
- Reputation
- 12
- Reaction score
- 7
- Trophy points
- 18
- Activity points
- 2,633
Hey,
There is something I don't understand in behaviour in my code. Can someone explain me whats wrong?
Basically, I have a 16 bit timer0 for PIC18F4550.
I set it to count impulses.
At the start I define:
And I start timer with those values, so it counts up to 65536.
And in the interrupt I reset it back to 15536:
So, basically... timer starts at 15536, goes up to 65536, and resets back to 15536 - right?
Actually, something else happens... sometimes (after stopping timer) the:
prints number LOWER than 15536.
I have tested it with Proteus, in most cases it works, but sometimes it prints things like:
"nowval 15377 (should be over 15536)".
My question is HOW - how could value of TMR0H/TMR0L go lower than 15536?
Where is the mistake in my understading?
PS: My whole code in case that's needed:
There is something I don't understand in behaviour in my code. Can someone explain me whats wrong?
Basically, I have a 16 bit timer0 for PIC18F4550.
I set it to count impulses.
At the start I define:
Code:
// 65536-50000=15536
// dec 15536 is hex 3CB0
#define START_VAL_TMR0H 0x3C
#define START_VAL_TMR0L 0xB0
(...)
Code:
TMR0H = START_VAL_TMR0H; // Initial count
TMR0L = START_VAL_TMR0L;
And in the interrupt I reset it back to 15536:
Code:
void interrupt(void) {
// UART1_Write_Text("int\n");
// http://www.enmcu.com/software/timer0calculatorandcodegeneration
// Reset the timer count
TMR0H=START_VAL_TMR0H;
TMR0L=START_VAL_TMR0L;
myCounter++;
// Reset interrupt flag
INTCON.TMR0IF = 0;
// Do some work here
}
So, basically... timer starts at 15536, goes up to 65536, and resets back to 15536 - right?
Actually, something else happens... sometimes (after stopping timer) the:
Code:
nowval = ((TMR0H)<< 8 ) + (TMR0L);
sprintf(buff,"nowval %ld (should be over 15536)\r\n",nowval);
prints number LOWER than 15536.
I have tested it with Proteus, in most cases it works, but sometimes it prints things like:
"nowval 15377 (should be over 15536)".
My question is HOW - how could value of TMR0H/TMR0L go lower than 15536?
Where is the mistake in my understading?
PS: My whole code in case that's needed:
Code:
void init_timers();
// dec 10 000 is hex 0x2710
// dec 1 000 is hex 0x03E8
// 65536-10000=55536
// dec 55 536 is hex D8F0
// 65536-1000=64536
// dec 64536 is hex FC18
// 65536-100=65436
// dec 65436 is hex FF9C
// 65536-50000=15536
// dec 15536 is hex 3CB0
#define START_VAL_TMR0H 0x3C
#define START_VAL_TMR0L 0xB0
int myCounter;
void main() {
char res[64];
int p10000, p1000, p100, p10, p1;
int k, m;
long nowval;
int ph, pl
;
long b, before;
long a, c, d;
union {
struct {
unsigned char l ;
unsigned char h;
};
unsigned int i;
};
char buff[64];
UART1_Init(9600);
init_timers();
for (;;) {
TMR0H = START_VAL_TMR0H; // Initial count of 0xF830
TMR0L = START_VAL_TMR0L;
myCounter = 0;
T0CON.TMR0ON = 1; // Turn Timer0 on.
Delay_ms(1000);
T0CON.TMR0ON = 0; // Turn Timer0 off.
h = TMR0H;
l = TMR0L;
// myCounter is increased once per 50k changes
k = myCounter * 50;
sprintf(buff,"Freq (integer): %ikHz\r\n",k);
UART1_Write_Text(buff); // Interrupt rutine
// eh. 3500
p1000 = (k - (k % 1000)) / 1000;
k -= p1000 * 1000;
p100 = (k - (k % 100)) / 100;
k -= p100 * 100;
p10 = (k - (k % 10)) / 10;
k -= p10* 10;
p1 = k;
// p1000 = 1;
// p100 = 2;
// p10 = 3;
// p1 = 4;
res[0] = '0'+p1000;
res[1] = '0'+p100;
res[2] = '0'+p10;
res[3] = '0'+p1;
res[4] = 0;
sprintf(buff,"Freq (string): %s kHz\r\n",res);
// 15
// sprintf(buff,"Freq: %ikHz\r\n",k);
UART1_Write_Text(buff); // Interrupt rutine
// a = i;
nowval = ((TMR0H)<< 8 ) + (TMR0L);
sprintf(buff,"nowval %ld (should be over 15536)\r\n",nowval);
d = c - 15536;
b = d;
UART1_Write_Text(buff); // Interrupt rutine
a = ((TMR0H)<< 8 );
d = (TMR0L);
c = d + a;
before = c;
sprintf(buff,"before %ld (we sub 15536)\r\n",before);
d = c - 15536;
b = d;
UART1_Write_Text(buff); // Interrupt rutine
sprintf(buff,"b %ld\r\n",d);
UART1_Write_Text(buff); // Interrupt rutine
p10000 = (b - (b % 10000)) / 10000;
b -= p10000 * 10000;
p1000 = (b - (b % 1000)) / 1000;
b -= p1000 * 1000;
p100 = (b - (b % 100)) / 100;
b -= p100 * 100;
p10 = (b - (b % 10)) / 10;
b -= p10* 10;
p1 = b;
res[0] = '0'+p10000;
res[1] = '0'+p1000;
res[2] = '0'+p100;
res[3] = '0'+p10;
res[4] = '0'+p1;
res[5] = 0;
sprintf(buff,"Freq (string): %s Hz\r\n",res);
UART1_Write_Text(buff); // Interrupt rutine
// i = i - 55536;
// ph = TMR0H - START_VAL_TMR0H;
// pl = TMR0L - START_VAL_TMR0L;
/// i = b;
/// sprintf(buff,"ph: %i\r\n",ph);
/// UART1_Write_Text(buff); // Interrupt rutine
// sprintf(buff,"pl: %i\r\n",pl);
/// UART1_Write_Text(buff); // Interrupt rutine
sprintf(buff,"Rem: %ld\r\n",b);
UART1_Write_Text(buff); // Interrupt rutine
Delay_ms(100);
}
}
void init_timers() {
// Initialise Timer0 for a 1Khz interrupt
// 8Mhz clock & want 1Khz interrupt
// See http://www.enmcu.com/software/timer0calculatorandcodegeneration
// for values.
//
INTCON.GIE=1; //globle interrupt enable
INTCON.PEIE=1; //peripharel interrupt enable
INTCON.TMR0IF = 0x0; //Clear timer0 overflow interrupt flag
INTCON.TMR0IE = 1; //enable the timer0 by setting TRM0IE flag
T0CON.T08BIT = 0; // 16 Bit timer
T0CON.T0CS = 1; // 1 = Transition on T0CKI pin
T0CON.PSA = 0b1111; // Set scaler
}
// interrupt handler for the timer0 overflow
void interrupt(void) {
// UART1_Write_Text("int\n");
// http://www.enmcu.com/software/timer0calculatorandcodegeneration
// Reset the timer count
TMR0H=START_VAL_TMR0H;
TMR0L=START_VAL_TMR0L;
myCounter++;
// Reset interrupt flag
INTCON.TMR0IF = 0;
// Do some work here
}