Forum: Mikrocontroller und Digitale Elektronik ATtiny84 und RFM12B


von Jens K. (mister232)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich habe zurzeit folgendes Projekt:
Ich möchte mit einem ATtiny84 die Temperatur mittels DS18B20 messen und 
die Daten via Funk (RFM12B) an einen Empfänger senden. Momentan bin ich 
dabei die Kommunikation zwischen ATtiny84 und RFM12B zum laufen zu 
bekommen. Dazu sende ich mit einem Raspberry periodisch eine Nachricht 
via RFM12B raus und versuche die zu Empfangen. Nebenbei läuft ein 
ATmega32, auf dem die Kommunikation funktioniert und welcher auch schön 
jede Nachricht empfängt. Leider empfängt der ATtiny84 nichts.
Im Anhang findet ihr mein Projekt und einen Screenshot des 
Logic-Analyzers, welcher die Kommunikation zwischen ATtiny84 und RFM12B 
beobachtet. Die Initialisierungsdaten scheinen korrekt übertragen zu 
werden.

: Bearbeitet durch User
von Jens K. (mister232)


Angehängte Dateien:

Lesenswert?

Hatte den Code vergessen ;-)

von Felix P. (fixxl)


Lesenswert?

Es kann sein, dass der Funktionsaufruf aus der ISR ein Problem ist. 
Versuch doch mal, in der ISR nur ein Flag zu setzen, dieses im 
Hauptprogramm zu prüfen und dann die beiden Funktionen aus der main 
heraus aufzurufen.

: Bearbeitet durch User
von Jens K. (mister232)


Lesenswert?

Tut sich leider auch nichts. Im ATmega32 funktioniert das übrbrings auch 
in der ISR. Die Debug-LED blinkt auch nicht, er schein also gar keinen 
Interrupt zu bekommen. Im Diagramm des Logic-Analyzers kann man ja auch 
erkennen, dass nIRQ die ganze Zeit auf Low bleibt. Ein externer Pull-Up 
bringt auch nichts. Wenn ich das Status-Register auslese, dann geht nIRQ 
auf High, kurze Zeit später aber wieder auf Low und ich kann dann auch 
kein Status-Register mehr lesen

von Jens K. (mister232)


Angehängte Dateien:

Lesenswert?

Wenn ich direkt nach der Initialisierung das Status-Register auslese, 
dann antwortet er mir mit 0x2300 und nIRQ geht auf High (siehe 
Diagramm). Nach einer Weile geht nIRQ dann wieder auf Low (evtl. Daten 
empfangen?), aber der Mikrocontroller reagiert nicht mehr (auch kein 
blinken der Debug-LED).

von A. Zöller (Gast)


Lesenswert?

Hallo Jens,

schau dir doch mal die Library von JeeLabs an. Die verwende ich auch mit 
dem JeeMicro mit Attiny84. Funtioniert einwandfrei.

Andreas

von Jens K. (mister232)


Lesenswert?

Von der JeeLabs Bibliothek habe ich schon gelesen, aber ist das nicht 
nur in Verbindung mit einem Andruino als Programer? Ich verwende AVR 
Studio mit einem MKII

von Felix P. (fixxl)


Lesenswert?

Jens K. schrieb:
> Nach einer Weile geht nIRQ dann wieder auf Low (evtl. Daten
> empfangen?), aber der Mikrocontroller reagiert nicht mehr (auch kein
> blinken der Debug-LED).

Sind zu diesem Zeitpunkt die Interrupts schon aktiv? Wenn ja, dann würde 
ich die Interrupt-Routine mal langsam steigern (LED einschalten, LED 
blinken lassen, ...), um zu sehen, ob oder ab wann der Controller sich 
aufhängt.

von Jens K. (mister232)


Lesenswert?

Ich habe nun durch dein Vorgehen schon herausgefunden, dass der 
INT0-Interrupt, wenn in der ISR die Daten abgeholt werden, den 
Timer-Interrupt für die SPI-Schnittstelle blockiert.

Setze ich nun aber nur ein Flag, sodass er in die ISR von INT0 spring, 
das Flag setzt und dieses dann in der main-Schleife abfragt, dann 
erreicht er die main-Schleife nicht mehr, obwohl in der ISR von INT0 nur 
ein Flag gesetzt wird und fertig. Ich habe auch schon versucht das 
INT0-Flag manuell zurück zu setzten, doch das funktioniert auch nicht.

Packe ich die Debug-Routine in die ISR, so blink er jedes Mal, wenn ich 
GND an INT0 anlege (habe den RFM12B erstmal abgeklemmt, um die ISR von 
INT0 vernünftig zum laufen zu bekommen). Manchmal (nicht immer) blinkt 
er auch, wenn ich GND wieder abnehme, wobei ich denke, dass dies durch 
Prellen entsteht.
Wenn ich nun die Debug-Routine aus der ISR für INT0 herausnehme und sie 
stattdessen in die main-Schleife einfüge, da wo das Flag (Daten 
empfangen) abgefragt wird, so blinkt die LED nie.

Also irgendwie..... hätte ich nur einen richtigen Debugger :-(

von Felix P. (fixxl)


Lesenswert?

Jens K. schrieb:
> Setze ich nun aber nur ein Flag, sodass er in die ISR von INT0 spring,
> das Flag setzt und dieses dann in der main-Schleife abfragt, dann
> erreicht er die main-Schleife nicht mehr, obwohl in der ISR von INT0 nur
> ein Flag gesetzt wird und fertig.

Du hast auch daran gedacht, das Flag als eine globale Variable mit dem 
Attribut volatile zu initialisieren? Das zu vergessen ist ein häufiger 
Fehler:

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Datenaustausch_mit_Interrupt-Routinen

: Bearbeitet durch User
von Jens K. (mister232)


Lesenswert?

Ne, hatte ich vergessen, ändert sich aber nichts. Ich habe aus 
Verzweiflung nun mal folgenden Code geschrieben:
1
/*
2
 * TestINT0_ATtiny84.c
3
 *
4
 * Created: 19.02.2015 15:03:01
5
 *  Author: Jens
6
 */ 
7
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
12
volatile uint8_t flag;
13
14
int main(void)
15
{
16
  DDRA |= (1<<PA0);
17
  
18
  DDRB &= ~(1<<PB2);
19
  PORTB |= (1<<PB2);
20
  
21
  MCUCR |= (1<<ISC01);
22
  GIMSK |= (1<<INT0);
23
  
24
  sei();
25
  
26
  flag = 0;
27
  
28
    while(1)
29
    {
30
    PORTA |= (1<<PA0);
31
    
32
        if(flag)
33
    {
34
      PORTA &= ~(1<<PA0);
35
      
36
      flag = 0;
37
    }
38
    }
39
}
40
41
ISR(INT0_vect)
42
{
43
  flag = 1;
44
}

Und ich muss feststellen, die LED bleibt an. Also scheint irgendetwas an 
meiner INT0-Konfiguration grundlegend nicht zu stimmen

von Jens K. (mister232)


Lesenswert?

Okay, den Fehler in dem Test-Code habe ich gefunden. Man sollte schon 
ein Delay einbauen :-)....

Leider ist der Fehler im Projekt immer noch da :-(

von Jens K. (mister232)


Lesenswert?

Also das mit dem Flag in der INT0-ISR setzten und in der main-Schleife 
auswerten klappt nun auch. Hatte vergessen das Flag auch im Header in 
volatile zu ändern.

Leider habe ich immer noch das ursprüngliche Problem, nämlich das nIRQ 
auf Low bleibt.

von Jens K. (mister232)


Lesenswert?

Es lebt!!!!

Also folgende Fehler waren drin:
1. Nachdem ich den RFM12B komplett initialisiert habe, schicke ich nun 
nochmal 0x00 hinterher, um das Status-Register des RFM12B auszulesen und 
damit den nIRQ wieder auf high zu bringen.
2. Die Flag-Variable musste auf volatile geändert werden
3. Nachdem er eine Nachricht empfangen hatte, hörte er auf zu empfangen. 
Das lag daran, dass ich nach der Empfangsroutine noch einmal 0xCA83 
senden musst, da sonst der FIFO des RFM12B deaktiviert blieb.

Hauptfehlerursache war es aber wohl, dass der INT0-Interrupt den 
Timer-Interrupt der SPI-Schnittstelle blockiert hat.

Danke für eure Hilfe ;-)

von Felix P. (fixxl)


Lesenswert?

Sehr schön, viel Spaß beim Funken! ;-)

: Bearbeitet durch User
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.