Hi folks,
I have the following problem:
I am using TIMER0 with an ATMMEGA32 to generate an Interrupt for every 1ms.
With a 16MHz-Crystal, Prescaler=64, CTC-Mode and OCR0=249 this should be achieved:
[code:1:3cb6f5d76d]
$regfile = "m32def.dat" 'ATMEGA32: 32k Flash, 2k RAM, 1k EEPROM
$framesize = 200
$swstack = 200
$hwstack = 200
$crystal = 16000000 '16 MHz Quarz
Config Timer0 = Timer , Prescale = 64 , Clear Timer = 1 'Timer 0 als 1ms-Zähler
'Tccr0 = &B00001011 'Normal Mode (=Timer),Normal Port operation = OC0 disconnected, CTC=1-->Auto-Reload, Prescaler=64
Ocr0 = 249 'Output-Compare Register --> t=64*250/16MHz
Stop Timer0 'bis zum Main-Loop-Start Timer vorerst stoppen
On Compare0 Timer0_isr Saveall 'Interrupt definieren und enablen
Start Timer0
Enable Compare0 'TIMSK Bit1=1
Enable Interrupts
[/code:1:3cb6f5d76d]
Now in the Timer0-IRS the long-variable "Timer_sum_total" counts the number of the interrupts and in the main program this is converted to seconds by dividing by 1000 and then to Hours, minutes and seconds with the LSECOFDAY and TIME-functions.
But the time in real hardware with a 16MHz crystal runs about 5..6% slow.
"Timer_sum_total" is only modified/incremented inside the IRS and in the main-program it is only read, but not written.
So a change of "Timer_sum_total" outside of the IRS is not possible.
At first I thought, that the IRS itself can last more than 1ms in the worst case when all conditions are fulfilled and then a new interrupt during the execution of the already running IRS would be missed.
But the simulator shows, that in worst case the IRS takes only 0.3ms. So this can not be the cause.
TIMER0 is not reused anywhere in the program.
It solely serves for the generation of the 1ms-interrupts.
However I am using EEPROM-writes in the main loop of the program.
As far as I know during EEPROM-writes interrupts are globally disabled for not corrupting the EEPROM.
So could it be, that EEPROM-writes take more than 1ms so that some interrupts are missed???
Or any other idea, what coulod cause the slow running time?
A short excerpt of the (very long) program is attached.
Kind regards
Roger
[code:1:3cb6f5d76d]
Timer0_isr:
Incr Ten_ms_counter 'ms-Zähler für 10ms erhöhen
If Ten_ms_counter = 10 Then '10ms abgelaufen?
Ten_ms_counter = 0 'Zähler zurücksetzen
If Polarity = 1 Then
Amp_hours_src = Amp_hours_src + Amp_hours_add_src 'Ah-Zähler für SOURCE-Mode erhöhen
Elseif Polarity = -1 Then
Amp_hours_sink = Amp_hours_sink + Amp_hours_add_sink 'Ah-Zähler für SINK-Mode erhöhen
End If
End If
Incr Timer_sum_total 'Gesamt-Timer-Zähler (LONG) erhöhen
If Pulsed_mode = 1 Then 'Falls im Puls-Betrieb...
Incr Ms_counter 'ms-Zähler (LONG) erhöhen
If High_low = 1 And Ms_counter = Timer_high_compare Then 'High-Zeit abgelaufen?
High_low = 0 'Wechsele auf Low-Mode
Ms_counter = 0
If Device_mode < 4 Then 'für Constant-Current-/Charge-/Discharge-Mode
I_out = I_low
Call Set_current(i_out) 'Setze Strom-PWM
Call Set_pulse_high_low_led 'Setzt LED entsprechend
End If
Elseif High_low = 0 And Ms_counter = Timer_low_compare Then 'Low-Zeit abgelaufen?
High_low = 1 'auf High-Mode wechseln
Ms_counter = 0
If Device_mode < 4 Then 'für Constant-Current-/Charge-/Discharge-Mode
I_out = I_high
Call Set_current(i_out) 'Setze Strom-PWM
End If
Call Set_pulse_high_low_led 'Setzt LED entsprechend
End If
Else
End If
Return
[/code:1:3cb6f5d76d]
[b:3cb6f5d76d][color=red:3cb6f5d76d](BASCOM-AVR version : 2.0.7.6 )[/b:3cb6f5d76d][/color:3cb6f5d76d]
↧