Forum: Compiler & IDEs xmega und dcf von u. radig


von Daniel P. (pirndi)


Lesenswert?

Hallo!

Ich versuche zurzeit den DCF code von U. Radig auf meinem xmega zum 
laufen zu bringen. Leider ohne erfolg. Die Sekunden zählen in 5er oder 
10er schritten hoch??

 meine Einstellungen
1
  /*Port Interrupt einstellen */ 
2
  // Initialisiert PORTA pin 0 als Eingang
3
  PORTA.DIR &= ~(1<<PIN0);
4
5
  // Bei Steigender Flanke Interupt auslösen
6
  PORTA.PIN0CTRL = PORT_ISC_RISING_gc;
7
8
  // Wählt PIN0 als Source für Interrupt 0 an PORTA
9
  PORTA.INT0MASK = 0x01;
10
   
11
  // Setzt INT0 mit Priorität High
12
  PORTA.INTCTRL = PORT_INT0LVL_HI_gc;
13
14
15
  /*Timer einstellen*/   
16
  TCC0.CNT = 0x00;
17
  
18
  TCC0.PER = 34285; // 65535 - (32000000 / 1024)
19
     
20
  /*1024 Vorteiler*/
21
  TCC0.CTRLA = TC_CLKSEL_DIV1024_gc;
22
   
23
  /*Timer im Normalmodus*/
24
  TCC0.CTRLB = TC_WGMODE_NORMAL_gc; 
25
26
     /*Interrupt konfigurieren*/
27
  TCC0.INTCTRLA = TC_OVFINTLVL_MED_gc;





für das zurücksetzten des Timers habe ich TCC0.CNT = 0x00; geschrieben
TCC0.CNT nehme ich auch für die Pulsweite her.

Bin für jede Hilfe dankbar!

mfg Daniel

von Daniel P. (pirndi)


Lesenswert?

Hallo!

Ich konnte jetzt das Problem eingrenzen. Wenn ich den Pin interrupt 
ausschalte funktioniert der Timer. Also muss das Problem beim 
Pininterrupt liegen.
1
//############################################################################
2
//DCF77 Modul empfängt Träger 
3
ISR (PORTA_INT0_vect)
4
//############################################################################
5
{
6
   //Auswertung der Pulseweite 
7
   //if (INT0_CONTROL == INT0_RISING_EDGE)
8
      
9
   if (PORTA.PIN0CTRL == PORT_ISC_RISING_gc)
10
      {
11
      flags.dcf_rx ^= 1;
12
    PORTE.OUTTGL |= (1<<PIN1);
13
    
14
      //Secunden Hilfs Counter berechnen // SYSCLK defined in USART.H
15
      h_ss = h_ss + TCC0.CNT - DCF_CYCLE_1S; //(65535 - (SYSCLK / 1024));
16
      //Zurücksetzen des Timers
17
     //TCC0.CTRLFCLR = TC_CMD_RESTART_gc;
18
     //TCC0.PER = DCF_CYCLE_1S; //65535 - (SYSCLK / 1024);
19
   
20
   TimerReset();
21
      //ist eine Secunde verstrichen // SYSCLK defined in USART.H
22
      //if (h_ss > ( SYSCLK / 1024 / 100 * 90)) //90% von 1Sekunde
23
    if (h_ss > ( DCF_SYSCLOCK / 100 * 90)) //90% von 1Sekunde      
24
                  
25
         {
26
         //Addiere +1 zu Sekunden
27
         Add_one_Second();
28
         //Zurücksetzen des Hilfs Counters
29
         h_ss = 0;
30
         };
31
      ////Nächster Interrupt wird ausgelöst bei abfallender Flanke
32
      //INT0_CONTROL = INT0_FALLING_EDGE;
33
    PORTA.PIN0CTRL = PORT_ISC_FALLING_gc;
34
      }
35
   else
36
      {
37
      //Auslesen der Pulsweite von ansteigender Flanke zu abfallender Flanke
38
      unsigned int pulse_wide = TCC0.CNT;
39
      
40
    //Zurücksetzen des Timers
41
      //TCC0.CTRLFCLR = TC_CMD_RESTART_gc;
42
      //TCC0.PER = DCF_CYCLE_1S; //65535 - (SYSCLK / 1024);
43
    TimerReset();
44
      //Secunden Hilfs Counter berechnen
45
      h_ss = h_ss + pulse_wide - DCF_CYCLE_1S;
46
      //Parity speichern
47
      //beginn von Bereich P1/P2/P3
48
      if (rx_bit_counter ==  21 || rx_bit_counter ==  29 || rx_bit_counter ==  36) 
49
         {
50
         flags.parity_err = 0;
51
         };
52
      //Speichern von P1
53
      if (rx_bit_counter ==  28) {flags.parity_P1 = flags.parity_err;};
54
      //Speichern von P2
55
      if (rx_bit_counter ==  35) {flags.parity_P2 = flags.parity_err;};
56
      //Speichern von P3
57
      if (rx_bit_counter ==  58) {flags.parity_P3 = flags.parity_err;};
58
      //Überprüfen ob eine 0 oder eine 1 empfangen wurde
59
      //0 = 100ms
60
      //1 = 200ms
61
      //Abfrage größer als 150ms (15% von 1Sekund also 150ms)   
62
      if (pulse_wide > (DCF_CYCLE_1S /100*85))
63
         {
64
         //Schreiben einer 1 im dcf_rx_buffer an der Bitstelle rx_bit_counter
65
         dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) 1 << rx_bit_counter);
66
         //Toggel Hilfs Parity
67
         flags.parity_err = flags.parity_err ^ 1;
68
         }
69
      //Nächster Interrupt wird ausgelöst bei ansteigender Flanke
70
     // INT0_CONTROL = INT0_RISING_EDGE;
71
   PORTA.PIN0CTRL = PORT_ISC_RISING_gc;
72
      //RX Bit Counter wird um 1 incrementiert
73
      rx_bit_counter++;
74
      }
75
};

ich lasse für das Signal auch ein LED mit toggeln da kommt mir das 
signal eigenartig vor. Ich habe auch schon mit einem OP eine 
Testschaltung gebaut da sieht das Signal normal aus. Der empfänger ist 
von Conrad und ich betreibe ihn mit 3v.

Bin für jede Hilfe dankbar

mfg Daniel

von XMEGA (Gast)


Lesenswert?

Hallo,

Daniel P. schrieb:

> PORTE.OUTTGL |= (1<<PIN1);

richtig: PORTE.OUTTGL = (1<<PIN1);
.OUTTGL beinhaltet bereits das Zeichen "|".
mit dieser Geschichte hab ich schon die tollsten Sachen erlebt!

Den von dir beschrieben Code kann mann nur schwer folgen.

> DCF code von U. Radig
Will mir den Code  jetzt nicht im Original verinnerlichen.

Beschreibe mal den Ablauf kurz.

Gruß XMEGA

von Daniel P. (pirndi)


Angehängte Dateien:

Lesenswert?

Hallo!

die Clock.c ist die vom xmega die andere ist die originale die am atmega 
läuft.

DCF_CYCLE_1S steht für 34285 müste im TCC0.PER register für eine sekunde 
stehen. Für SYSTEMCLK habe ich bei den Berechnungen 32000000 eingesetzt. 
Der CPU läuft auch mit 32mhz denn wenn ich denn Interrupt am Pin 
deaktiviere läuft der Timer im sekundentakt. Ich denke das der Fehler im 
auslesen vom TCC0.CNT liegt. Im Originalcode steht TCNT1 was ja das 
zählregister beim ATmega ist. Beim Xmega ist PER der Topwert und CNT das 
Zählregister soweit ich aus dem DB verstanden habe.

mfg Daniel

von Daniel P. (pirndi)


Angehängte Dateien:

Lesenswert?

Sorry hab die falsche Datei angehängt. Diese verwende ich am Xmega die 
nicht läuft.

mfg Daniel

von Daniel P. (pirndi)


Lesenswert?

Hab den Fehler gefunden.

Man stellt TCC0.PER auf den max Wert 65535 und setzt bei TCC0.CNT den 
wert für eine Sekunde ein und läd diesen dann nach beim zurücksetzten.

von schnufff (Gast)


Lesenswert?

Beim XMega bietet es sich an, einfach (32000000/1024) in TCC0.PER zu 
schreiben. Der Overflow-Interrupt wird dann bei genau diesem Wert 
ausgelöst und der Timer automatisch wieder auf 0 gesetzt.

von Kris M. (kristijan_m)


Lesenswert?

wäre schön gewesen wenn du den code mit uns teilst. es ist nicht leicht 
den code mit fehler zu verfolgen und ihn für xmega weiter zu verwenden

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.