Hallo,
vorab: mein erster Einsatz der neuen DD-Familie, bisher immer Atmega und
Attiny (alt)
Nach einigen Versuchen aufgrund eines seltsamen Verhalten beim AVR64DD
habe ich folgendes eingegrenzt:
Ich betreibe den Chip mit 3.3V und einem externen 3,6864MHz Quarz und
nutze auch die util/delay.h. Den TCA0 nutze ich zum Zählen von
50ms-Einheiten. Sobald ich bei der Initialisierung des TCA0 einen Wert
in TCA0.SINGLE.PER schreibe, wird delay_ms nun massiv langsamer.
Ich benutze an anderer Stelle die RTC - daher hier der TCA.
Initialisierung auf 3,6864 MHZ - kontrolliert mit DSO über aktivierten
PA7:
1 | int main(void) {
|
2 | //Systemspeed 3,6864 MHz using external crystal
|
3 | ccp_write_io((uint8_t *)&CLKCTRL.XOSCHFCTRLA,
|
4 | CLKCTRL_RUNSTDBY_bm
|
5 | | CLKCTRL_CSUTHF_4K_gc
|
6 | | CLKCTRL_FRQRANGE_8M_gc
|
7 | | CLKCTRL_ENABLE_bm);
|
8 | while(!(CLKCTRL.MCLKSTATUS & CLKCTRL_EXTS_bm)){;}
|
9 |
|
10 | /* Clear Main Clock Prescaler */
|
11 | _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0);
|
12 |
|
13 | //activate external clock
|
14 | ccp_write_io((uint8_t *)&CLKCTRL.MCLKCTRLA,
|
15 | CLKCTRL_CLKSEL_EXTCLK_gc
|
16 | | CLKCTRL_CLKOUT_bm //output clock on PA7
|
17 | );
|
18 | while(CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm){;}
|
nun das interessante:
1 | _delay_ms(5000); //wartet 5 Sekunden
|
2 |
|
3 | //Initialisierung TCA0
|
4 | /* set the period */
|
5 | TCA0.SINGLE.PER = 180; //das hier ist die kritische Zeile...
|
6 | /* enable with prescaler */
|
7 | TCA0.SINGLE.CTRLA =
|
8 | TCA_SINGLE_CLKSEL_DIV1024_gc // -> 3600Hz
|
9 | | TCA_SINGLE_ENABLE_bm; /* start timer */
|
10 |
|
11 | /* enable overflow interrupt */
|
12 | TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
|
13 | /* set Normal mode */
|
14 | TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;
|
15 | /* disable event counting */
|
16 | TCA0.SINGLE.EVCTRL &= ~(TCA_SINGLE_CNTAEI_bm);
|
17 |
|
18 | sei();
|
19 |
|
20 | _delay_ms(5000); //wartet ca. 170 (vermutlich 180) Sekunden
|
21 | }
|
22 |
|
23 | volatile uint8_t sensor_counter_50ms = 0;
|
24 | ISR(TCA0_OVF_vect) {
|
25 | sensor_counter_50ms++;
|
26 | TCA0.SINGLE.INTFLAGS &= ~TCA_SINGLE_OVF_bm;
|
27 | }
|
Ich habe zunächst vermutet, dass der TCA-Prescaler aus irgendeinem Grund
den Systemtakt ändert. Via DSO habe ich aber verifiziert, dass auch im
zweiten Delay der Systemtakt an PA7 noch bei den 3,68 MHz ist.
*Sobald ich das Setzen der PER aus dem TCA0 rausnehme, sind auch der
untere delay 5 Sekunden (es reicht die eine Zeile auszukommentieren).*
Es scheint nun, dass der delay als Basis nicht den System Takt nimmt,
sondern 5000 mal den Overflow von TCA0 (das wären dann ca. 250 Sekunden
was hinkommenm könnte). Da ich hierzu aber keinerlei Hinweis im
Datasheet finde und ich auch nicht von so einem Hardware-Bug ausgehe,
ist die tatsächliche Ursache aber vermutlich eine andere.
Kann hier jemand zur Aufklärung und Lösung beitragen?
Grüße Micha