Forum: Mikrocontroller und Digitale Elektronik ATTINY804 RTC bekomme ich nicht hin


von Anselm 6. (anselm68)



Lesenswert?

Hallo Ihr,

ich versuche den RTC zum laufen zu bekommen, scheine aber irgendwas im 
Datenblatt übersehen zu haben.
Könnt Ihr mal drüber sehen?
1
#define F_CPU 20000000
2
3
#include <avr/io.h>
4
#include <avr/cpufunc.h>
5
#include <avr/interrupt.h>
6
#include <util.h>
7
#include <util/delay.h>
8
9
uint64_t systemtick64_10ms = 0;
10
11
void CLOCK_init(){
12
  ccp_write_io((void*)& CLKCTRL.MCLKCTRLA,0);  // Masterclock set to 16/20MHz, CLK_OUT is off
13
  ccp_write_io((void*)& CLKCTRL.MCLKCTRLB,0);  // no division, prescaler disabled
14
15
  RTC.CLKSEL = 0x00;                  // internal rtc
16
  RTC.CNT = 16384;  // 2Hz for Debugtest, original 327                  // 16Bit counter value for 10ms period @ prescaler 0 & 32768Hz (10.009ms)
17
  RTC.CTRLA =  0x01;                  // no prescaler - rtc enable
18
  RTC.INTCTRL = 0b00000001;              // Overflow
19
}
20
21
void pinout_init(){
22
  PORTA.DIR = 0b01001000;    // PA 3 & 6 are output, others are input
23
  PORTA.PIN3CTRL = 0x00;    // Signal inverted by transistor - writing 1 to this output will pull the reset on mainboard to 0V
24
  PORTA.PIN6CTRL = 0x80;    // Signal inverted on µC, writing 1 will pull CFGMODE to 0 (activate mode)
25
}
26
27
int main(){
28
  CLOCK_init();
29
  pinout_init();
30
  sei();
31
  while (1) {
32
    ;
33
  }
34
}
35
36
ISR(RTC_CNT_vect){          // OVF for CTC Mode
37
  PORTA.OUTTGL |= PIN6_bm;    // toggelt CFGMODE zu Testzwecken
38
  //RTC.INTFLAGS = RTC_OVF_bm;    // clear interrupt
39
}

von Georg M. (g_m)


Lesenswert?

> RTC.CNT = 16384;

Nicht "RTC.PER"?

Außerdem:
OUTTGL braucht kein "|".
"RTC.INTFLAGS = RTC_OVF_bm;" muss sein.

von Anselm 6. (anselm68)


Lesenswert?

|=, da hast du recht, aber es stört auch nicht, denn in der mainloop mit einem 
_delay_ms toggelt mein Pin wie erwartet.
Die Zeile zum löschen des INTFLAGS hatte ich beim test auch mal aus 
gemacht...

.PER versus .CNT, die verwirren mich etwas
Der PIT erzeugt nur periodische events (eventcontrol), oder liege ich da 
falsch?

Anselm

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Anselm 6. schrieb:
> |=, da hast du recht, aber es stört auch nicht, denn in der mainloop mit einem
> _delay_ms toggelt mein Pin wie erwartet.

Solange Du keinen anderen Pin aus PortA als Ausgang nutzt, siehe 
Datenblatt:
Bits 7:0 – OUTTGL[7:0] Output Value Toggle
(...)
Reading this bit field will return the value of PORTx.OUT.

> .PER versus .CNT, die verwirren mich etwas

.CNT wird bei jedem Zähltakt inkrementiert. Sobald dessen Inhalt gleich 
dem des .PER Registers ist, wird .CNT auf 0 gesetzt. Deshalb der Name 
.PER, wie PERIODE.

Grüßle,
Volker

: Bearbeitet durch User
von Georg M. (g_m)


Lesenswert?

Hier ist ein Blink-LED Testcode für den RTC, getestet am ATtiny402:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/sleep.h>
4
5
ISR(RTC_CNT_vect) 
6
{
7
  if(RTC.INTFLAGS & RTC_OVF_bm)
8
  {
9
    PORTA.OUTSET = PIN3_bm;               // LED on
10
    RTC.INTFLAGS = RTC_OVF_bm;            // clear RTC OVF interrupt flag
11
  }
12
  else if(RTC.INTFLAGS & RTC_CMP_bm)
13
  {
14
    PORTA.OUTCLR = PIN3_bm;               // LED off
15
    RTC.INTFLAGS = RTC_CMP_bm;            // clear RTC CMP interrupt flag
16
  }
17
}
18
19
int main(void)
20
{
21
  PORTA.DIRSET = PIN3_bm;                       // PA3 output (LED)
22
23
  RTC.CLKSEL = RTC_CLKSEL_INT1K_gc;             // 1024 Hz from OSCULP32K
24
  while (RTC.STATUS > 0) {}                     // wait for all register to be synchronized
25
  RTC.INTCTRL = RTC_OVF_bm | RTC_CMP_bm;        // enable RTC OVF and CMP interrupts
26
  RTC.PER = 0x003F;                             // RTC Period (~1s)
27
  RTC.CMP = 0x000A;                             // Compare Value (~0.1s)
28
  RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_PRESCALER_DIV16_gc | RTC_RTCEN_bm;  // enable Run In Standby, RTC clock 64Hz, enable RTC
29
30
  SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc;       // select STANDBY sleep mode
31
  sei();                                        // enable Global Interrupts
32
33
  while(1)
34
  {
35
    sleep_mode();
36
  }
37
}

von Anselm 6. (anselm68)


Lesenswert?

Danke, der funktioniert auch auf meinem 804. Damit ist mir sehr 
geholfen.

Anselm

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.