Forum: Compiler & IDEs Ulrich Radig´s DCF für Atmega2560 an INT2 statt INT0


von lufthaken (Gast)


Lesenswert?

hallo zusammen,

Die DCF Uhr lief lange zeit echt super mit dem code vom Uli.
ich habe es an INT0 am Atmega2560 angeschlossen.
Nun möchte ich zusätzlich einen DS1307 über den TWI Bus nutzen, TWI 
liegt am Atmega an PD0 und PD1 liegt. Problematisch dabei ist nun das 
PD0 gleich INT0 ist.
1
Atmega2560 Datenblatt auszüge:
2
  Bit    7     6     5     4     3     2     1      0
3
(0x69) ISC31 ISC30 ISC21 ISC20 ISC11 ISC10 ISC01 ISC00 EICRA
4
5
...
6
7
ISCn1 ISCn0 Description
8
0       0   The low level of INTn generates an interrupt request.
9
0       1   Any edge of INTn generates asynchronously an interrupt request.
10
1       0   The falling edge of INTn generates asynchronously an interrupt request.
11
1       1   The rising edge of INTn generates asynchronously an interrupt request.


eigentlich kein ding, einfach dcf signal an INT2(PD2) hängen und 
folgende zeilen ändern;
1
//für Atmega 2560 Int0:
2
//Interrupt an dem das DCF77 Modul hängt hier INT0
3
#define DCF77_INT_ENABLE()  enable_external_int (1<<INT0);
4
#define DCF77_INT      SIG_INTERRUPT0
5
6
#define INT0_CONTROL    EICRA
7
#define INT0_FALLING_EDGE  0x02
8
#define INT0_RISING_EDGE  0x03
1
//für Atmega2560 INT2:
2
//Interrupt an dem das DCF77 Modul hängt hier INT2(PD2)
3
#define DCF77_INT_ENABLE()  EIMSK |= (1<<INT2);
4
#define DCF77_INT      SIG_INTERRUPT2
5
#define INT2_CONTROL    EICRA
6
#define INT2_FALLING_EDGE  0x32
7
#define INT2_RISING_EDGE  0x48
8
9
//############################################################################
10
//DCF77 Modul empfängt Träger 
11
SIGNAL (DCF77_INT)
12
//############################################################################
13
{ 
14
   //Auswertung der Pulseweite 
15
   if (INT2_CONTROL == INT2_RISING_EDGE)
16
      {
17
      flags.dcf_rx ^= 1;
18
      //Secunden Hilfs Counter berechnen // SYSCLK defined in USART.H
19
      h_ss = h_ss + TCNT1 - (65535 - (F_CPU / 1024));
20
      //Zurücksetzen des Timers
21
      TCNT1 = 65535 - (F_CPU / 1024);
22
      //ist eine Secunde verstrichen // SYSCLK defined in USART.H
23
      if (h_ss > (F_CPU / 1024 / 100 * 90)) //90% von 1Sekunde
24
         {
25
         //Addiere +1 zu Sekunden
26
         Add_one_Second();
27
         //Zurücksetzen des Hilfs Counters
28
         h_ss = 0;
29
         };
30
      //Nächster Interrupt wird ausgelöst bei abfallender Flanke
31
      INT2_CONTROL = INT2_FALLING_EDGE;
32
      }
33
   else
34
      {
35
      //Auslesen der Pulsweite von ansteigender Flanke zu abfallender Flanke
36
      unsigned int pulse_wide = TCNT1;
37
      //Zurücksetzen des Timers
38
      TCNT1 = 65535 - (F_CPU / 1024);
39
      //Secunden Hilfs Counter berechnen
40
      h_ss = h_ss + pulse_wide - (65535 - (F_CPU / 1024));
41
      //Parity speichern
42
      //beginn von Bereich P1/P2/P3
43
      if (rx_bit_counter ==  21 || rx_bit_counter ==  29 || rx_bit_counter ==  36) 
44
         {
45
         flags.parity_err = 0;
46
         };
47
      //Speichern von P1
48
      if (rx_bit_counter ==  28) {flags.parity_P1 = flags.parity_err;};
49
      //Speichern von P2
50
      if (rx_bit_counter ==  35) {flags.parity_P2 = flags.parity_err;};
51
      //Speichern von P3
52
      if (rx_bit_counter ==  58) {flags.parity_P3 = flags.parity_err;};
53
      //Überprüfen ob eine 0 oder eine 1 empfangen wurde
54
      //0 = 100ms
55
      //1 = 200ms
56
      //Abfrage größer als 150ms (15% von 1Sekund also 150ms)   
57
      if (pulse_wide > (65535 - (F_CPU / 1024)/100*85))
58
         {
59
         //Schreiben einer 1 im dcf_rx_buffer an der Bitstelle rx_bit_counter
60
         dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) 1 << rx_bit_counter);
61
         //Toggel Hilfs Parity
62
         flags.parity_err = flags.parity_err ^ 1;
63
         }
64
      //Nächster Interrupt wird ausgelöst bei ansteigender Flanke
65
      INT2_CONTROL = INT2_RISING_EDGE;
66
      //RX Bit Counter wird um 1 incrementiert
67
      rx_bit_counter++;
68
      }
69
};

dcf liegt nun an 'PD2 und nicht an PD0 aber es geht noch nicht.
hab ich was übersehen?

von Stefan E. (sternst)


Lesenswert?

1
#define INT2_FALLING_EDGE  0x32
2
#define INT2_RISING_EDGE  0x48
Nö.

Quizfrage: was bedeutet das 0x vor den Zahlen?

von lufthaken (Gast)


Lesenswert?

Ui, ja hex zahl und ich schreib da die dez zahl rein, ürgh...

habs geändert und es ging irgendwie immernochnich auf INT2.
dann hab ich das ganze auf INT3 versucht, das ging sofort.
seltsam mit INT2(PD2) muss im übrigen code nochn fehler sein oder der 
pin is doof. -.-

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
   if (INT2_CONTROL == INT2_RISING_EDGE)
ist auch verbesserungswürdig.

Wenn da noch andere Flags im EICRA benutzt werden, dann ist hier Ärger 
vorprogrammiert.

von Karl H. (kbuchegg)


Lesenswert?

lufthaken schrieb:
> Ui, ja hex zahl und ich schreib da die dez zahl rein, ürgh...

Schreibs so

#define INT2_FALLING_EDGE  (1<<ISC20)
#define INT2_RISING_EDGE   ((1<<ISC20) | (1<<ISC21))

dann hast du das Problem nicht.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das hier
>
1
>    if (INT2_CONTROL == INT2_RISING_EDGE)
2
>
> ist auch verbesserungswürdig.
>
> Wenn da noch andere Flags im EICRA benutzt werden, dann ist hier Ärger
> vorprogrammiert.

Genauso wie hier
1
     INT2_CONTROL = INT2_FALLING_EDGE;
bzw.
1
      INT2_CONTROL = INT2_RISING_EDGE;

Das muss ziemlich alter Code sein. SIGNAL ist schon lange aus der Mode 
und der Code ist von der Registerbenutzung her nicht sehr sauber 
geschrieben.

Da würde ich erst mal Hand anlegen und das ganze auf eine saubere 
Bitoperation setzen die nicht davon ausgeht, dass das hier der einzige 
benutzte externe Interrupt ist.

von Karl H. (kbuchegg)


Lesenswert?

lufthaken schrieb:

> habs geändert und es ging irgendwie immernochnich auf INT2.
> dann hab ich das ganze auf INT3 versucht, das ging sofort.
> seltsam mit INT2(PD2) muss im übrigen code nochn fehler sein oder der
> pin is doof. -.-

Pin auf Eingang gestellt?
Pullup eingeschaltet (falls notwendig)?

Gib dir in die ISR eine Ausgabe rein, die dir anzeigt ob die ISR 
aufgerufen wird (LED toggeln). Dann weiß man schon mal mehr.

(Die Initialisierung ebenfalls auf 'wilde' Registerkonstrukte 
durchsehen!)

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.