Autor |
Interrupts in "C" bei Atmel |
|
|
|
|
BID = 159904
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
|
Zuerst die gute Nachricht:
Meine ersten Schritte mit den Atmels (Attiny2313) waren schon erfolgreich, hab' auch schon etwas programmiert und es funkt!
AAAAABER:
Total unproffessionell in einer langen Schleife als main()....
Das muss besser werden!
Eine der grundlegenden Funktionen sind Beispielsweise viel besser in einem zyklischen Interrupt aufgehoben ... (Ausgabe von PWM - Signalen).
Und jetzt klemmts: (Oder bin ich einfach zu doof???)
Ich hab's noch nicht kapiert, wie ich mit WINAVR einen Interrupt in "C" programmiere.
Eigentlich sind 2 Probleme zu lösen:
a) Timerprogrammierung (init)
b) Zyklischen Interrupt durch Timer bearbeiten.
Gibt's ein möglichst einfaches "howto" im Netz, welches mir weiterhilft?
... oder hat jemand von Euch einen Tip?
Wahrscheinlich fehlt nur ein kleiner Schubs, um mein Verständniss dafür in die richtige Rille zu bringen...
|
|
BID = 159927
giwer Stammposter
Beiträge: 202
|
|
Hier ein Beispiel für 1 Sek. Interrupt. (8 MHZ Quarz)
#include <avr/io.h>
#include <avr/interrupt.h>
int main (void)
{
sei(); // Globalen Interrupt freigeben
ETIMSK =_BV(OCIE3A);// Vergleichswertüberlauf Interrupt einschalten
TCCR3B = _BV(CS32);// Vorteiler =256
OCR3A = 8000000/ 256 - 1; // compare 1 x/ Sekunde.
for(;;)
{..
...
..
}
/***********************
Interruptroutine wird aufgerufen wenn OCR3A = TCNT3.
(1x pro Sekunde)
************************/
SIGNAL(SIG_OUTPUT_COMPARE3A) //
{
TCNT3 = 0x0000; // Rücksetzen
mache jede Sekunde irgendwas();
Achtung.
Routine so kurz und schnell sein.
Keine lange schleifen, keine umfangreiche Berechnungen, u.s.w.
}
}
|
|
BID = 160217
Henne02 Stammposter
Beiträge: 493 Wohnort: Aachen
|
schau Dir im Mikrocontroller.net - Wiki das avrgcc-Tutorial an!
Das löst alle Deine Probleme und bringt Dich auf Ideen / Lösungen von denen nicht zu träumen wagtest. (Aber Groß/kleinschreibung beachten!!)
Grüße, Hendrik
|
BID = 160220
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
@giwer:
Danke für den Code, werde ihn mal ausprobieren!
@Henne2:
Danke für den Hinweis - super Site!
Hajo
|
BID = 160684
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
@giwer:
War leider nix
Die Portbezeichnungen passen nicht zum Attiny2313.
Auch nachdem ich hier was ausgebessert hab, bekomme ich noch keine vernünftige Ausgabe (ich lasse nur ein paar LEDs am Port D blinken).
Arbeitest Du auch mit WinAVR?
... und mit Attiny2313 oder einem anderen Chip?
bin weiter am probieren...
Hajo
|
BID = 160838
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
Des Ding will net im Unterbrechungsmodus....
Möglicherweise kann sich mal jemand den Sourcecode ansehen, ist wirklich nicht viel....
Für heut' mag ich nimmer!
hajo
|
BID = 160906
giwer Stammposter
Beiträge: 202
|
Ja, ich hab WinAvr.
Das Beispiel war ein Ausschnitt aus dem Programm mit Atmega128.
Ich werde mir mal heute Abend dein Code in Ruhe anschauen.
|
BID = 161006
MinceR Stammposter
Beiträge: 277
|
ich hab mir gerade die demo vom ICCAVR compiler gezogen. ist meiner meinung nach ein super proggi. komm ich irgendwie mehr zurecht als mit winavr...
|
BID = 161110
giwer Stammposter
Beiträge: 202
|
Code getestet mit den 90S8515 (habe kein Attiny2313).
Die LED-0 am Port D blinkt 1 mal pro Sekunde.
Wenn du einen anderen Quarz verwendest, dann musst statt 8000000 den entsprechenden Wert eintragen, und eventuell die 60000 ändern.
|
BID = 161123
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
Danke für den code...
hat auch (auf den ersten Blick) funktioniert.
Dann hab' ich aber eine kleine Änderung vorgenommen, um sicher zu gehen, daß der IRQ durchlaufen wird
... und es war wieder nix!
Hier der Code:
// prozessor definitionen im makefile
#define XTAL 1000000// verwendete Quarz (Hz) (damit's etwas schneller geht, Wert kleiner!
#include <avr/io.h>// Zugriff auf die I/O's des Controllers
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
void init_avr(void);
static unsigned char d;
int main (void)
{
init_avr();
for (;;)
{
PORTB = d;
}// for
}// main
SIGNAL(SIG_OUTPUT_COMPARE1A)// Wird 4x pro Sekunde aufgerufen
{
TCNT1 = 0x0000;// Zurücksetzen
d++;
}
void init_avr(void)
{
DDRB = 0xFF;// Port B als Ausgang
DDRD = 0x00;// Port D als Eingang
d=85; // ein nettes Muster
TIMSK =_BV(OCIE1A);// Vergleichswertüberlauf Interrupt einschalten
TCCR1B = _BV(CS12);// Vorteiler =256
OCR1A = XTAL / 256 - 1;// compare 1 x/ Sekunde.
sei();
}
|
BID = 161127
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
... wenn ich jedoch den "globalen" (=unbehandelte Interrupts) IRQ anstatt dem SIG_OUTPUT_COMPARE1A verwende "SIGNAL(__vector_default)", dann klappt's.
Wie kann ich feststellen, durch welchen Interrupt - Kanal dieser IRQ ausgelöst wird?
Gibt's da ein Statusregister ffür die anliegenden Interrupts?
|
BID = 161135
giwer Stammposter
Beiträge: 202
|
Entferne die PORTB=d Zeile in der for Schleife und füge sie hier ein.
SIGNAL(SIG_OUTPUT_COMPARE1A)// Wird 4x pro Sekunde aufgerufen
{
TCNT1 = 0x0000;// Zurücksetzen
d++;
PORTB=d;
}
Schau dir die Datei io2313.h an, da sind die Interrupt Vektoren festgelegt, und das Datenblatt Seite 43.
|
BID = 161165
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
HURRA!!!
Der richtige Tip war dabei (RTFM)
Es haben sich die Namen der Signale geändert!!!
mit
SIGNAL(SIG_TIMER1_COMPA)
...
funktionierts!
Maximalen Dank an giwer!
hajo
|
BID = 161176
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
... und weiter mit den Herausforderungen (es gibt ja keine Probleme...)
Wie kann ich eine Variable sowohl im Hauprprogramm als auch in der Interrupt - Routine benutzen?
Hintergrund:
Interner Tick wird im IRQ hochgezählt und im Hauptprogramm damit eine Zustandsmaschine gesteuert.
Dabei muß sowohl im IRQ als auch im Hauptprogramm lesend und schreibend auf die Variable zugegriffen werden.
Hat bis jetzt noch nicht geklappt...
|
BID = 161192
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
Jetzt reicht's!
Hab' einfach "volatile" in der Var - Definition vergessen
Ab jetzt sollte es eigentlich ohne fremde Hilfe weitergehen!
Nochmals Danke an alle, die hier mitgeholfen haben!
Hajo
|