Hallo nemesis,
hier ist eine gute Anleitung zum Compiler und zum AVR:
http://www.mikrocontroller.net/artic...R-GCC-Tutorial
Grüße
Hi,
ich habe ein echtes Problem mit dem UART. Ich möchte Daten zwischen meinem PC und dem Atmega 32 austauschen.
Da ich nicht möchte das der Atmega 32 in der schleife fest steckt bis er etwas über die Comport Leitung vom PC empfängt. Dachte ich mir das ich das mit einem Interrupt versuche.
Ich kann den Interrupt jedoch nicht aktivieren/einstellen.
Hab schon alles mögliche versucht aber nix ging.
Hab dann auch etwas auf der roboternetz Seite gefunden das einem zeigt wie genau mann vor zu gehen hat. Um mit dem UART-Interrupt arbeiten zu können.
Das soll dann so fuktionieren:
1) Konfiguriere Interrupt
2) generell Interrupts zulassen
3) schalte speziell den InterruptXXX ein
4) verzweige bei InterruptXXX zu SprungXXX
Das ganze ist hier zu finden:
https://www.roboternetz.de/wissen/in...com_Interrupts
Mit den Punkten 1 und 3 komme ich nicht zurecht hab keine ahnung wie mann das macht.
Mein Programm sieht etwa so aus:
Zum Code(so soll es sein):Code:#include <avr/io.h> #include <avr/interrupt.h> #define USART_RXC_vect _VECTOR(14) #include <avr/delay.h> /* USART-Init beim ATmega16 */ #ifndef F_CPU #define F_CPU 16000000 /* Oszillator-Frequenz in Hz */ #endif // Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt) #define UART_UBRR_CALC(BAUD_,FREQ_) ((16000000)/((19200)*16L)-1) #define UART_BAUD_RATE 19200 char c = 97; int main(void) { ///////////////////////////////////////////interrupt für UART einstellen /*1*/ /*2*/sei(); /*3*/ /*4*///steht oben //////////////////////////////////////////// ///////////////////////////////////////////UART einstellungen UCSRB |= (1<<TXEN); // UART TX einschalten UCSRC |= (1<<URSEL)|(3<<UCSZ0); // Asynchron 8N1 UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 ); UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ); ////////////////////////////////////////////////// while(c != 300) { UCSRB |= (1<<TXEN); // UART TX einschalten UDR = c; _delay_ms(200); } } ISR(USART_RXC_vect) /* veraltet: SIGNAL(SIG_UART_RECV) */ { while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar c = UDR; }
Ich schicke zu beginn ein kleines a vom controller zum PC (welches ich auch ohne Probleme am PC empfangen kann), danach sende ich ein irgent ein zeichen z.b. ein x vom PC zum Controller. Dieses Zeichen soll der Controller dann mit hilfe des Interrupts aufnehmen(damit er nicht in der Schleife für das Daten Empfangen fest hängt) und dann wieder zum PC zurück schicken.
Das einziegste was der Controller macht, ist mir immer nur das a zu schicken.
Ich hoffe es kann mir jemand dabei helf damit es richtig funktioniert.
Gruß Nemesis
Hallo nemesis,
hier ist eine gute Anleitung zum Compiler und zum AVR:
http://www.mikrocontroller.net/artic...R-GCC-Tutorial
Grüße
Hallo,
wie willst Du was empfangen, wenn Du den Empfänger nicht einschaltest
das geht so,
Jetzt kannst Du senden,empfangen und der Interrupt ist eingescheltet, der für den Empfang zuständigt ist.Code:UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
Im einfachstem Fall machst Du ein Echo:
Du brauchst hier auf nichts zu warten, weil das Zeichen schon da istCode:ISR (USART_RXC_vect) { uint8_t tmp = UDR; UDR = tmp; }
Wichtig ist nur, das UDR auch ausgelesen wird!
willst Du aus dem Hauptprogramm was senden, mußt Du UDRE testen:
Gruß sebastianCode:while(!(UCSRA & (1<<UDRE))); UDR = 'a';
Linus TorvaldSoftware is like s e x: its better when its free.
Hallo Sebastian,
hab eben ausprobiert was du geschrieben hast und nun funktioniert es.
Da rauf wäre ich so schnell wohl nicht gekommen, vielen dank.
Allerdings gibt es noch ein kleines problem. Und zwar habe ich eine globale Variable "char c = 'a'; ". Wenn der Interrupt ausgelöst wird, wird das Hauptprogramm gestopt und der Controller sprinkt in die Funktion vom Interrupt.
In dieser Funktion lasse ich mir dann das Zeichen welches ich vom PC gesendet habe (z.b. x) zurück zum PC schicken. Wie schon gesagt das klappt jetzt bestens. Aber ich möchte das das x nun das a in der Variablen c ersetzt. Das funktioniert jedoch nicht und ich hab keine ahnung warum nicht.
Vielleich hat dafür jemand ne Lösung.
Gruß Nemesis
Ist c als volatile deklariert?
Hab zwar keine ahnung was volatile macht aber nun geht alles.
Das ist aber schlecht,
Als (angehender) C Programmierer sollte man es schon wissen
Zugegeben, bei PC Programmierung sieht man volatile seltener, aber google hilft hier weiter:
http://www.google.com/search?client=...utf-8&oe=utf-8
wühl Dich da mal durch...
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
volatile sagt dem Compiler, dass die Variable von anderen Stelle aus geändert werden kann. Es greifen ja das Hauptprogramm und der Interrupt darauf zu. Ohne volatile denkt der Compiler, dass die Variable immer gleich bleibt, wenn sie nicht im Hauptprogramm geändert wird. Er lädt sie darum zb nicht immer aus dem RAM, sondern puffert sie vielleicht in einem Register. Wenn das Hauptprogramm nie was an c ändert, kann der Compiler daraus sogar ne Konstante machen. Egal wie er hier optimiert, das Ergebnis ist, dass das Hauptprogramm nicht mitbekommt, dass im Speicher für c schon ein neuer Wert steht.
Naja bin eigentlich E-Techniker und hatte erst 2 Semester C-Programmierung.
Doch da kam sowas nicht vor. Aber gut das ich es nun weis.
Ihr habt mir Heute echt gut und schnell geholfen vielen Dank nochmal.
Gruß Nemesis
....Zugegeben, bei PC Programmierung sieht man volatile seltener, .....
es ist keine schande , wenn man nicht weiss, wo man volatile setzen muss.
auch c-fachleute scheitern daran, weil jeder c-compiler die werte anders handhabt. mal bleiben die werte der variablen erhalten, mal sind sie weg...lol... das ist c.
gerade das scheiss winavr-c lässt ein manchmal im stich, hier ist es angebracht, fast alles volatile zu setzen um diese fehlerquelle erst einmal auszuschliessen.
mfg
Lesezeichen