Forum: Compiler & IDEs Atmega8 an Empfänger Flankenerkennung


von Henry-810 (Gast)


Lesenswert?

Guten Tag

Würde gerne mit einem Atmega8 einen Kanal an einem 2.4GHZ Fernsteuerungs 
Empfänger auswerten.

Habe im Internet einen Code gefunden, er Funktioniert bei mir nicht habe 
das Signal von dem Empfänger an INT0 (PD2) angeschlossen, wenn ich die 
Fernbedienung bediene tut sich nichts es leuchte einfach PB3.

Der Code sollte die Steigende und Fallende Flanken erkennen.

Hoffe Jeamand kann mir Helfen.

Danke im vorraus.




•
1
/*
2
 * AtMega8_Empfänger_auswerten_Internet_1.c
3
 *
4
 * Created: 12.01.2014 14:52:43
5
 
6
7
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include "inttypes.h"
11
12
 
13
int start;
14
int stop;
15
int32_t impuls;
16
int flanke;
17
18
19
int main(void)
20
{
21
 
22
DDRB |=  (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4) | (1<<PB5);
23
24
25
26
MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
27
GICR  |= (1<<INT0); //Interrupt von INT0 auf Enable
28
29
30
31
32
sei(); //Interrupts aktivieren
33
34
while(1)
35
{
36
if (flanke == 1)
37
{
38
  start = TCNT1;
39
  MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
40
  MCUCR &= ~(1<<ISC00);
41
  flanke = 0;
42
}
43
else
44
{
45
  stop = TCNT1;
46
  impuls = stop - start;
47
  MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus)
48
  flanke = 1;
49
50
}
51
52
//****************************************************************************   
53
  if (impuls < 1100)
54
  {
55
   PORTB |= (1<<PB3); //Bit3 auf High setzen
56
  }
57
  
58
  if (impuls > 1800)
59
  {
60
   PORTB |= (1<<PB4); //Bit4 auf High setzen
61
  }
62
  
63
  
64
  if ((impuls > 1490) & (impuls < 1550))
65
  {
66
   PORTB &= ~(1<<PB4); //Bit4 auf Low setzen
67
   PORTB &= ~(1<<PB3); //Bit3 auf Low setzen
68
  }
69
    
70
//****************************************************************************
71
72
}
73
  
74
}

von Laurenz K. (gimmebottles)


Lesenswert?

Henry-810 schrieb:
> if ((impuls > 1490) & (impuls < 1550))

muss "if ((impuls > 1490) && (impuls < 1550))" heißen, also doppeltes 
'&'.

Einfaches und ist logische UND-verknüpfung, und da einer der beides 
Vergleiche immer falsch ist kommt immer false raus.

von Kurt H. (Firma: KHTronik) (kurtharders)


Lesenswert?

Hallo,
mit den Abfragen auf die Variable impuls willst Du wahrscheinlich auf 
die Signalmitte von 1,5ms abfragen. Läuft Timer1 sicher mit 1µs? Im Code 
steht da nichts, was den Timer initialisiert.
Ausserdem sehe ich keine Interruptroutine für für INT0.
Da Du sonst nichts machst, kannst Du die Flankenerkennung auch im main() 
machen. Der Impuls kommt ja alle ca. 20ms, so dass die Zeit auch für 
einiges an Verarbeitung reichen müsste.
Wenn Du es mit Interrupts machen willst, nimm doch beide INT-Pins und 
setze den einen auf steigend und den anderen auf fallend. In der ISR 
musst Du dann nur noch impuls setzen. Und volatile nicht vergessen :-)
Grüße, Kurt

von Henry-810 (Gast)


Lesenswert?

Guten Tag

Danke für die Hilfe.

Habe es überarbeitet, funktioniert leider (noch) nicht.

Könnte ich die Steigende Flanke auch anderst testen als mit dem 
Empfänger?

Steigende Flanke auf INT0 und Fallnde Flanke auf INT1 würde ich als 
nächstes Testen danke für den Tipp.

Grüsse


•
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
volatile unsigned int start;
6
volatile unsigned int stop;
7
volatile unsigned int impuls;
8
volatile unsigned int flanke;
9
10
11
12
int main(void)
13
{
14
15
  DDRB |=  (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4) | (1<<PB5);
16
  
17
  
18
  
19
  TCCR0 |= (1<<CS01);   //Vorteiler auf CPU Takt/8
20
21
  MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
22
  GICR  |= (1<<INT0); //Interrupt von INT0 auf Enable
23
24
25
  sei(); //Interrupts aktivieren
26
27
  while(1)
28
  {
29
30
31
32
    if (impuls < 1100)
33
    {
34
      PORTB |= (1<<PB3); //Bit3 auf High setzen
35
    }
36
    
37
    if (impuls > 1800)
38
    {
39
      PORTB |= (1<<PB4); //Bit4 auf High setzen
40
    }
41
    
42
    
43
    if ((impuls > 1490) && (impuls < 1550))
44
    {
45
      PORTB &= ~(1<<PB4); //Bit4 auf Low setzen
46
      PORTB &= ~(1<<PB3); //Bit3 auf Low setzen
47
    }
48
    
49
50
  }
51
52
}
53
54
55
56
ISR(INT0_vect)
57
{
58
  if (flanke == 1)
59
  {
60
    start = TCNT1;
61
    MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
62
    MCUCR &= ~(1<<ISC00);
63
    flanke = 0;
64
  }
65
  else
66
  {
67
    stop = TCNT1;
68
    impuls = stop - start;
69
    MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus)
70
    flanke = 1;
71
  }
72
}

von Karl H. (kbuchegg)


Lesenswert?

Henry-810 schrieb:

> ISR(INT0_vect)
> {
>   if (flanke == 1)
>   {
>     start = TCNT1;
>     MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
>     MCUCR &= ~(1<<ISC00);
>     flanke = 0;
>   }
>   else
>   {
>     stop = TCNT1;
>     impuls = stop - start;
>     MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke
> stellen (Löst Interrupt bei steigendet Flanke an INT0 aus)
>     flanke = 1;
>   }
> }


Beim Umschalten der Flankenrichtung immer auch das zu diesem Interrupt 
gehörende Interrupt Flag nachher löschen. Denn es kann sein, dass 
alleine durch das Umschalten der Richtung bereits ein falscher Interrupt 
registriert wird.

von Henry-810 (Gast)


Lesenswert?

Guten Tag

Hast du Dir das so gedacht?? Mit cli();

Grüsse

•
1
ISR(INT0_vect)
2
{
3
  if (flanke == 1)
4
  {
5
    start = TCNT1;
6
    MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
7
    MCUCR &= ~(1<<ISC00);
8
    flanke = 0;
9
    cli();
10
  }
11
  
12
  
13
  else
14
  {
15
    stop = TCNT1;
16
    impuls = stop - start;
17
    MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus)
18
    flanke = 1;
19
    cli();
20
  }
21
}

von Karl H. (kbuchegg)


Lesenswert?

Henry-810 schrieb:
> Guten Tag
>
> Hast du Dir das so gedacht?? Mit cli();

Nö.

Das Flag INTF0 im GIFR Register löschen.
Aber Datenblatt lesen, das erfordert Sonderbehandlung!


Edit: INteressant ist, dass diese Möglichkeit beim INT2 dokumentiert 
ist, beim INT0 jedoch nicht. D.h. das könnte sein, dass dieses gar nicht 
das Problem ist. Schaden tuts auf jeden Fall nicht das Flag zu löschen, 
auch wenn es das Problem nicht löst.

von Kurt H. (Firma: KHTronik) (kurtharders)


Angehängte Dateien:

Lesenswert?

Hallo Henry,
ich habe das Programm mal etwas überarbeitet :-)
- INT0 erzeugt Interrupt auf beiden Flanken. In der ISR wird dann der 
Pin abgefragt.
- Die Auswertung in der main-Loop erfolgt nur, wenn die fallende Flanke 
erkannt wurde.
Kompiliert oder getestet habe ich das allerdings nicht :-).
Grüße, Kurt

von Henry-810 (Gast)


Lesenswert?

Guten Abend

Danke für den Code hat leider nicht geholfen.

Werde die Flanken auswertung mal auf eis legen, bis ich mehr von Timer 
verstehe.

Grüsse und vielen Dank

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.