PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupt Fragen



meldano
28.10.2007, 18:18
Hallo,

nach anfänglichen Bascom Irritationen :-$ habe ich mich nun entschlossen mal meine ersten Gehversuche in C zu starten. Die Bascom Sachen laufen einwandfrei, doch denke ich C ist sinnvoller.

Portabfragen usw. laufen, PWM auch, doch habe ich Probleme eine ISR für den Timer 0 Overflow Interrupt anzulegen.

Hier mal mein erster C Code (ist unsinn, nur zum üben):


#include <avr/io.h>
#define F_CPU 1000000

/* Delay aufrufen mit _delay_ms(Wert_in_ms); */
#include <util/delay.h>

#include <avr/interrupt.h>



/* Bitfeld anlegen um einzelne Bits ansprechen zu können
Bit setzen: BIT.bit1 = 1;
Bit rücksetzen BIT.bit1 = 0; */

struct { unsigned char bit1 :1;
unsigned char bit2 :2;
unsigned char bit3 :3;
unsigned char bit4 :4;
unsigned char bit5 :5;
unsigned char bit6 :6;
unsigned char bit7 :7;
unsigned char bit8 :8;
} BOOL;


void rinit (void)
{
/* Timer 0 für PWM */
TCCR0A |= (1<<COM0A1) | (1<<COM0A0) | (1<<WGM00); //Phase Correct PWM Mode
TCCR0B |= (0<<CS02) | (1<<CS01) | (1<<CS00); //Prescaler 64

/* Timer 1 für Overflow */
TCCR1 |= (1<<CS12) | (1<<CS11) | (1<<CS10); //Prescaler 64
TIMSK |= (1<<TOIE1); //Timer1 ISR bei Overflow

/* Eingänge / Ausgänge */
DDRB |= (0<<PB3) | (1<<PB2) | (1<<PB1) | (1<<PB0) ; //PB0..2 Ausgang, PB3 Eingang
PORTB |= (1<<PB3); // Pull Up für PB3 aktivieren
}





int main(void)
{

sei(); //Alle Interrupts ein

rinit(); //Register initialisieren

BOOL.bit1 = 0; //bit1 initialisieren

while (1) //Hauptschleife
{

if ( !(PINB & (1<<PB3))) //wenn PINB3=0 dann bit1 = 1
{
BOOL.bit1=1;
}


if (BOOL.bit1==1)
{
PORTB |= (1<<PB0);
}


} //end while

} //end main



Wie programmiere ich nun die ISR für den Timer 1 Überlauf?

Bevor ich Zukunft noch mehr so einfach zu beantwortende Fragen stelle:
Wie finde ich den die Bezeichner für die ISR´s, so das ich auch mal einen ADC Interrupt etc. programmieren kann ?

Achso, Entwicklungsumgebung AVR Studio und als Plug in Win AVR.


Danke!

Rabazzz
28.10.2007, 19:42
Also ganz auf die Schnelle...
Interrupts immer mit ISR(Source){} wobei Source der Name des entsprechenden Interrups ist... also zB TIMER0_OVF_vect, die findest du im Datenblatt. Danach einfach die ISR schreiben, wie ne normale Fkt.

roboterheld
28.10.2007, 20:42
hier gibt es zig hunderte winavr-cprogramme :

http://www.mikrocontroller.net/forum/gcc

askazo
29.10.2007, 10:20
Die Bezeichner der Interrupts findest Du in der zum Prozessor passenden io.h
Wenn Du also den ATMega8 einsetzt, kannst Du in
WinAVR\avr\include\avr\iom8.h
nachschauen. Dort sind neben den Interruptbezeichnern auch sämtliche Register des Prozessors definiert.

askazo

SprinterSB
29.10.2007, 10:22
zu deinem code:

-- sei erst *nach* der init-phase!
-- TCCxx =... ist angesagt anstatt TCCxx |=...
-- wenn du wirklich bits willst, dann :1 im strukt ( :4 sind zb 4 bits)
-- die isr-namen findest du im header gcc-dir/avr/include/avr/ioxxx.h und xxx hängt von deinem µc ab, ib iom8.h für atmeg8, iotn2313.h für attiny2313...

meldano
29.10.2007, 18:04
Hi SprinterSB,

danke für deine Tips! Nur so kann ich lernen. sei() erst nach der init kann ich nachvollziehen.


-- TCCxx =... ist angesagt anstatt TCCxx |=...
Kannst du erläutern warum? Da habe ich wohl was garnicht verstanden.




-- wenn du wirklich bits willst, dann :1 im strukt ( :4 sind zb 4 bits)

Dann so? :

struct { unsigned char bit1 :1;
unsigned char bit2 :1;
unsigned char bit3 :1;
unsigned char bit4 :1;
unsigned char bit5 :1;
unsigned char bit6 :1;
unsigned char bit7 :1;
unsigned char bit8 :1;
} BOOL;



-- die isr-namen findest du im header gcc-dir/avr/include/avr/ioxxx.h und xxx hängt von deinem µc ab, ib iom8.h für atmeg8, iotn2313.h für attiny2313...

DANKE!
Ich habe die Bezeichner für die ISR´s jetzt gefunden.
Hier hat es sich auch mal gelohnt reinzugucken:
avr-libc-user-manual.pdf


Gruß
Daniel