Hallo zusammen,
mir ist bewusst, dass ein ATMEGA128 nicht unbedingt der optimale uC ist
um mit dem uC programmieren zu beginnen. Da ich aber ein
funktionstüchtiges Testboard vorliegen habe versuch ichs damit trotzdem.
Leider scheine ich schon an einem externen Interrupt zu scheitern.
Zunächst zum Prog.:
An einem funktionstüchtigem Testboard mit einem ATMEGA128 soll an PortC
eine RGB LED ansteuert werden. Nach Programmstart soll eine Farbe
leuchten. Nach einem externen Interrupt an PORTD0 (INT0) der bei einer
fallenden Flanke ausgelöst werden soll, soll sich die Farbe ändern.
Mein Code:
1 | #ifndef F_CPU
|
2 | #warning "F_CPU war noch nicht definiert, wird nun mit 16000000UL definiert"
|
3 | #define F_CPU 16000000UL /* Quarz mit 16 Mhz */
|
4 | #endif
|
5 | #include <avr/io.h>
|
6 | #include <avr/interrupt.h>
|
7 |
|
8 | /* ********************************* Variablen und Konstanten definieren************************** */
|
9 | volatile uint8_t aaa;
|
10 | uint8_t rot = 0b11111110;
|
11 | uint8_t gelb = 0b11111100;
|
12 | uint8_t gruen = 0b11111101;
|
13 | uint8_t cyan = 0b11111001;
|
14 | uint8_t blau = 0b11111011;
|
15 | uint8_t violett = 0b11111010;
|
16 | uint8_t weiss = 0b11111000;
|
17 | uint8_t schwarz = 0b11111111;
|
18 |
|
19 | /* ********************************** Main Prog. ********************************************** */
|
20 |
|
21 | int main(void)
|
22 | {
|
23 | DDRC = 0xFF; //Ausgangsport für die LED definieren
|
24 | PORTC = 0xFF; //Ausgangspins alle auf logisch 1 setzten (alle LEDs aus / schwarz)
|
25 |
|
26 | /* *********************************Initialisierung Interrupt ********************************** */
|
27 |
|
28 | DDRD = 0x00; //Eingangspot für Interrupt definieren
|
29 | PORTD = 0x01; //Pullup Widerstand setzten für Interrupt an fallender Flanke bei INT0
|
30 |
|
31 | EICRA |= (1<<ISC01); //INT0 bei fallender Flanke
|
32 | EIMSK |= (1<<INT0); //Interrupt an INT0 aktivieren
|
33 |
|
34 | PORTC = rot; //Rotes Licht soll leuten bevor Programm startet.
|
35 |
|
36 | sei(); // Erlaube globale Interrupts
|
37 | aaa = 0; // Wert einer Variablen zuweisen. Diese Variable soll im Interrupt geändert werden
|
38 |
|
39 | /* ********************Standardprgramm starten: Hier LED Farben werden im 1sec Takt gewechselt. ************* */
|
40 | while(1)
|
41 | {
|
42 | if (aaa == 0)
|
43 | {
|
44 | PORTC = gelb;
|
45 | }
|
46 | else
|
47 | {
|
48 | PORTC = blau;
|
49 | }
|
50 | }
|
51 | }
|
52 |
|
53 | /* ********************************** Interrupts ***************************** */
|
54 | ISR(INT0_vect)
|
55 | {
|
56 | //cli();
|
57 | aaa != aaa;
|
58 | //sei();
|
59 | }
|
Nach dem Starten des Programms leuchtet es wie gewollt gelb. Das es
zwischendrin mal rot war ist natürlich nicht zu sehen. Wenn ich jetzt
aber einen Interrupt an INT0 auslöse indem ich INT0 extern auf Masse
ziehe, leuchtet es nicht blau, sondern immer rot, d.h. das der uC nach
dem sei() ununterbrochen resettet so lange INT0 auf Masse liegt.
Leider habe ich in den anderen Beiträgen keine passenden Beiträge
gefunden, die mir weitergeholfen haben. Sobald ich einen externen
Interrupt auslöse wird dieser abgearbeitet und danach das Programm neu
gestartet. Dies hab ich gestestet indem ich in dierkt in die ISR() eine
Farbfolge ablaufen lies, was auch geklappt hat. Danach wurde aber nicht
an die reichtige Stelle zurückgesprungen sondern das Prog. neu
gestartet.
Was ist falsch? Bitte um Hinweise bzw. Verbesserungen des Codes.
Danke im voraus
Andreas