Hi, Ich sitz jetzt schon Tage daran meinen ATMega168(http://embedit.de/content/view/37/26/) seriell anzusprechen. Ich habs mit mehreren eigenen und mehreren kopierten(aus dem Internet) Quelltexten und mit Linux und Windows probiert. Hier mal ein Beispiel aus dem Internet, das einwandfrei kompiliert: #include <avr/io.h> #include <avr/interrupt.h> #include <stdint.h> #define USART_BAUDRATE 9600 #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) int main (void) { DDRB = 0xff; PORTB = 0xff; UCSR0B |= (1 << RXEN0) | (1 << TXEN0); // Turn on the transmission and reception circuitry UCSR0C |= (1 << UMSEL00) | (1 << UCSZ00) | (1 << UCSZ01); // Use 8-bit character sizes UBRR0L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register UBRR0H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register UCSR0B |= (1 << RXCIE0) | (1 << RXC0); // Enable the USART Recieve Complete interrupt (USART_RXC) sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed while(1); } ISR(SIG_USART_RECV) { char ReceivedByte; ReceivedByte = UDR0; // Fetch the recieved byte value into the variable "ByteReceived" UDR0 = ReceivedByte; // Echo back the received byte back to the computer if(PORTB == 0xff) PORTB = 0x00; else PORTB = 0xff; } Die 3 wichtigen Pins RxD, TxD und Ground sind mit dem PC verbunden( RxD und TxD sind gekreuzt). Signale geb ich mit SuperTerm 2. Ich Connecte mit der Baudrate 9600 auf den entsprechenden COM-Port und schreib was ins Terminal-> Nichts passiert. Was mir unter Linux mit einem anderen Quelltext, in dem nur das RXEN0 angeschaltet sein musste und ein serielles Signal ankommen musste, passiert ist, war dass der Controller einfach gar nichts mehr getan hat. (Da war eine while Schleife, die die Lampe immer an und ausgeschalten hatte und wo das Byte kam, blieb die Lampe an bzw. aus). Sicher ist das ganze ein Anfängerfehler da ich aber schon ewig rumprobiere, kann ich grad echt nicht weitergooglen. Ich finde einfach nichts mehr, weil ich nicht weiß obs am PC, am Kabel, am Controller oder sonst was liegt. Für Hilfe wär ich sehr dankbar, Moritz
Moritz Sch wrote: > Hier mal ein Beispiel aus dem Internet, das einwandfrei kompiliert: Bitte benutze [c]-Markierungen um deine Quelltexte, sonst kann die keiner mehr lesen. > Die 3 wichtigen Pins RxD, TxD und Ground sind mit dem PC verbunden( RxD > und TxD sind gekreuzt). Aber RS-232-Levelshifter (und -Inverter) hast du drin, ja?
Hast Du einen Pegelwandler zwischen AVR und PC? Die TTL-Signale (0V 5V) müssen erst noch auf höhere Pegel (+12V -12V) gebracht werden, damit der PC damit was anfangen kann. z.B. Der MAX232 ist dafür da.....
Stefan P. wrote: > Hast Du einen Pegelwandler zwischen AVR und PC? > Die TTL-Signale (0V 5V) müssen erst noch auf höhere Pegel (+12V -12V) > gebracht werden, damit der PC damit was anfangen kann. Vor allem müssen sie negiert werden. Viele PC-Schnittstellen würden vermutlich statt ±12 V ganz brauchbar mit 0 V / 5 V hinkommen, aber dummerweise entspricht TTL/CMOS-High einem RS-232-Pegen von -(5...12) V und TTL/CMOS-Low einem RS-232-Pegel von +(5...12) V.
1 | Auf dem Modul ist ein Pegelwandler für RS232 Signale untergebracht. Dadurch kann das Modul von |
2 | einem PC gesteuert werden oder kann selbst über die serielle Schnittstelle andere Geräte steuern. Die |
3 | RS232 Signale sind auf einer 10 poligen Stiftleiste herausgeführt wie sie auch auf einem PC Mainboard zu |
4 | finden sind. |
Ein Pegelwandler ist auf dem Modul. Ich geh mal davon aus, dass er die Signale gleich noch mit invertiert.
Hi, Also ich habe jetzt mal einen neuen Code (unter Linux) probiert:
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | #include <stdint.h> |
5 | #include <util/delay.h> |
6 | |
7 | #define USART_BAUD_RATE 9600
|
8 | #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)
|
9 | |
10 | |
11 | uint16_t gloFrequ; |
12 | |
13 | int main() |
14 | {
|
15 | //SREG |=(1<<7);
|
16 | sei(); |
17 | |
18 | UBRR0H = (unsigned char)(USART_BAUD_SELECT>>8); |
19 | UBRR0L = (unsigned char)USART_BAUD_SELECT; |
20 | UCSR0B = (1<<RXEN0)|(1<<TXEN0) | (1<<RXCIE0); |
21 | /* Set frame format: 8data, 2stop bit */
|
22 | UCSR0C = (1<<USBS0)|(3<<UCSZ00); |
23 | |
24 | DDRC = 0xff; |
25 | DDRB = 0xff; |
26 | //register aktivieren
|
27 | PORTB = 0xff; |
28 | PORTC = 0xff; |
29 | gloFrequ=500; |
30 | //lichter an aus
|
31 | while(1) |
32 | {
|
33 | _delay_ms(gloFrequ); |
34 | if(PORTB == 0xff) |
35 | PORTB = 0x00; |
36 | else if(PORTB == 0x00) |
37 | PORTB = 0xff; |
38 | }
|
39 | return(0); |
40 | }
|
41 | |
42 | ISR(USART_RX_vect) |
43 | {
|
44 | gloFrequ = 100; |
45 | PORTC = 0xFF; |
46 | }
|
47 | |
48 | //
|
und folgendes festgestellt: Sende ich ein Byte auf den seriellen Port, dann wird der Controller um ca. 1/10 langsamer. (die Lampe blinkt langsamer). der code in ISR(USART_RX_vect) wird nicht ausgeführt. (PORTC wird nicht aktiviert und die lampe blinkt nach senden eines Bytes unabhängig von gloFrequ = ...; immer gleich schnell. Kommentiere ich die ISR-Funktion komplett aus, dann bleibt der Controller ganz stehen (die Lampe bleibt bei dem Wert, als das Byte gesendet wurde). Ideen? Gruß Moritz
Du nutzt ein _delay_ms(), daher musst Du die Optimierung anschalten, damit das richtig funktioniert, hast Du das? (siehe http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29) Ist das Modul tatsächlich mit 20 MHz getaktet, sprich sind die Fuses richtig gesetzt? (http://www.mikrocontroller.net/articles/AVR_Fuses) Wo wird F_CPU definiert? Makefile? Einfach mal "#define F_CPU 20000000" Testweise ausprobieren. Ansonsten http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Der_UART
Erstmal zu dem Mhz-Problem: Ich verwende Eclipse AVR Plugin und da kann ich den Projekt-Einstellungen die Frequenz einstellen. Wenn ich die verändere verändert sich auch die Geschwindigkeit mit der die Lampe blinkt. Und wenn ich die Frequenz auf 20000000 stelle, dann blinkt die Lampe auch so schnell wie sie soll. (In meinem Code einmal an und einmal aus pro Sekunde). Das heißt doch, dass F_CPU richtig ist oder?
> der code in ISR(USART_RX_vect) wird nicht ausgeführt. Vermutlich doch. > (PORTC wird nicht aktiviert Was soll denn da aktiviert werden? Du setzt den Port doch schon in main auf 0xFF, wie soll denn das "PORTC = 0xFF;" in der ISR noch irgendetwas sichtbares bewirken? > und die lampe blinkt nach senden eines Bytes unabhängig von > gloFrequ = ...; immer gleich schnell. Weil du gloFrequ nicht volatile deklariert hast. Und dass der Controller scheinbar langsamer wird, liegt daran, dass du in der ISR das UART-Datenregister nicht ausließt. Deshalb wird der Interrupt nach Verlassen der ISR sofort (naja, fast sofort, nach einem Befehl) wieder ausgelöst, und die ISR wird daher immer und immer wieder ausgeführt.
Hi, Hab grad nicht so viel Zeit, werd mich aber nachher vielleicht mal drann setzen und das Register auslesen.
Vielen Dank jetzt tuts:
1 | #ifndef F_CPU
|
2 | #define F_CPU 20000000UL
|
3 | #endif
|
4 | |
5 | #include <avr/io.h> |
6 | #include <avr/interrupt.h> |
7 | |
8 | #include <stdint.h> |
9 | #include <util/delay.h> |
10 | |
11 | |
12 | #define USART_BAUD_RATE 9600
|
13 | #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)
|
14 | |
15 | |
16 | volatile uint16_t gloFrequ; |
17 | |
18 | int main() |
19 | {
|
20 | //SREG |=(1<<7);
|
21 | sei(); |
22 | |
23 | UBRR0H = (unsigned char)(USART_BAUD_SELECT>>8); |
24 | UBRR0L = (unsigned char)USART_BAUD_SELECT; |
25 | UCSR0B = (1<<RXEN0)|(1<<TXEN0) | (1<<RXCIE0); |
26 | /* Set frame format: 8data, 2stop bit */
|
27 | UCSR0C = (1<<USBS0)|(3<<UCSZ00); |
28 | |
29 | DDRC = 0xff; |
30 | DDRB = 0xff; |
31 | //register aktivieren
|
32 | PORTB = 0xff; |
33 | gloFrequ=500; |
34 | //lichter an aus
|
35 | while(1) |
36 | {
|
37 | _delay_ms(gloFrequ); |
38 | if(PORTB == 0xff) |
39 | PORTB = 0x00; |
40 | else if(PORTB == 0x00) |
41 | PORTB = 0xff; |
42 | }
|
43 | return(0); |
44 | }
|
45 | |
46 | ISR(USART_RX_vect) |
47 | {
|
48 | gloFrequ = UDR0*5; |
49 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.