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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren