Atmega8 an Empfänger Flankenerkennung

Gast #3483863
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
}
(Firma: KHTronik) #3484026
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
Gast #3489257
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
}
#3489394
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.
Gast #3490667
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
}
#3490678
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.
(Firma: KHTronik) #3490748
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
Angehängte Dateien:

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.