View previous topic :: View next topic |
Author |
Message |
b77ng
Joined: 22 Jan 2014 Posts: 7
|
Apparently trivial TMR0 interrupt gives me the headaches |
Posted: Wed Jan 22, 2014 4:01 pm |
|
|
Hi everyone, first post here
This is not my first PIC app, I've managed to successfully get much more complex ones to work but this time I'm stuck.
It's a 16F84A that needs to toggle an output at a variable rate controlled by two (up/down) switches. TMR0 has 256 prescaler and interrupt activated. Inside the interrupt routine I'm writing 255 to TMR0 (so that it overflows again after 'PRESCALER' Tcy's) and toggling the output, then exit.
Looks like the output is toggling eratically as soon as I change the rate by using the switches. There's no specific scenario that triggers the erratic behavior, the actual moment it goes to lunch seems random.
Inside main I'm not touching the interrupt enable flags or anything, no delay functions used either.
And the damned thing runs out of ROM if I try to add debug code!
Any ideas?
Code: |
//Global variables:
unsigned int32 tick_cnt = 0, old_blink_time = 0;
int1 led_status = 0;
unsigned int16 blink_half_period = 0;
.
.
// This is inside main
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
enable_interrupts(INT_RTCC);
set_timer0(255);
enable_interrupts(GLOBAL);
.
.
#int_RTCC
RTCC_isr()
{
tick_cnt++;
set_timer0(255); // Will overflow after 'PRE' instruction cycles
if (tick_cnt - old_blink_time >= blink_half_period) {
old_blink_time = tick_cnt;
if (led_status == 1) {
output_bit(STRB_LED, LED_OFF);
led_status = 0;
}
else {
output_bit(STRB_LED, LED_ON);
led_status = 1;
}
}
}
|
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Jan 22, 2014 4:29 pm |
|
|
Post a SHORT but complete compilable code which shows the problem.
Then we are not having to second guess at what's going on.
We need to be able to copy and paste so we can check for ourselves.
Mike |
|
|
b77ng
Joined: 22 Jan 2014 Posts: 7
|
|
Posted: Thu Jan 23, 2014 7:04 am |
|
|
Hi
When I posted the topic I was tired and overly frustrated by the problem, I was really convinced that I narrowed it down to a TMR0 issue.
Meanwhile it looks like it's a problem with the calculation of the blink period. I managed to shrink the code so that I can now add debug helpers. I guess the title is no longer relevant. I'll come back with a full report anyway.
EDIT: found it! Stupid C data type conversion rule, that's what happens if you don't code for years on end.
Code: | blink_half_period = (30000000 / (rpm_bcd[0] * 1000 + rpm_bcd[1] * 100 + rpm_bcd[2] * 10 + rpm_bcd[3])) >> 9; |
rpm_bcd[] is an unsigned int8 array, should be:
Code: | blink_half_period = (30000000 / (rpm_bcd[0] * 1000ul + rpm_bcd[1] * 100ul + rpm_bcd[2] * 10 + rpm_bcd[3])) >> 9; |
Now all is working fine. |
|
|
|