hallo, habe folgendes problem, ich habe die baud rate auf dem PC und µc angepast (9600 8N1) und den externen quartz eingestelt 3,6MHz auch die dafür notwendigen fuse bits gesetzt, meine konfiguration in C (siehe unten). Ich bekomme aber laute unsinige Zeichen angezeigt. ich komme einfach nicht weiter. #define F_CPU 3686400 #include <avr\io.h> #define BAUD 9600 //---------------------------------------------------------------------- // Titel : C-Funktion Zeichen zu UART senden. // IN : char data //---------------------------------------------------------------------- void uartPutChar(char data) { //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313 while (!(UCSRA&32)); //sende UDR=data; } void uartPutBin(char data) { //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313 while (!(UCSRA&32)); //sende if (data&1) uartPutChar('1'); else uartPutChar('0'); if (data&2) uartPutChar('1'); else uartPutChar('0'); if (data&4) uartPutChar('1'); else uartPutChar('0'); if (data&8) uartPutChar('1'); else uartPutChar('0'); if (data&16) uartPutChar('1'); else uartPutChar('0'); if (data&32) uartPutChar('1'); else uartPutChar('0'); if (data&64) uartPutChar('1'); else uartPutChar('0'); if (data&128) uartPutChar('1'); else uartPutChar('0'); } //---------------------------------------------------------------------- // Titel : C-Funktion wartet auf Zeichen von UART. // OUT : data //---------------------------------------------------------------------- char uartGetChar() { char data=0; //warte bis RX-complete RXC UCSRA / USR bei z.B.: AT090S2313 while (!(UCSRA&128)); //empfangen data=UDR; return data; } //---------------------------------------------------------------------- // Titel : C-Funktion wartet auf Zeichen von UART. // OUT : data, error = keine Daten //---------------------------------------------------------------------- bool error; char uartIsChar() { char data=0; error=true; //chek RX-complete RXC UCSRA if (!(UCSRA&128)) return 0; //zeihen abholen data=UDR; error=false; return data; } //---------------------------------------------------------------------- // Titel : C-Funktion Zeichenkette zu UART senden. // IN : char *buffer, Zeichenkette mit NUll abgeschlossen //---------------------------------------------------------------------- void uartPutString(char *buffer) { for (int i=0; buffer[i] !=0;i++) uartPutChar (buffer[i]); } //---------------------------------------------------------------------- -- // Initialisierungen //---------------------------------------------------------------------- -- void init() { // UART initialisieren sbi(UCSRB,3); // TX aktiv sbi(UCSRB,4); // RX aktivieren UBRRL=(uint8_t)(F_CPU/(BAUD*16L))-1; // Baudrate festlegen UBRRH=(uint8_t)((F_CPU/(BAUD*16L))-1)>>8; // Baudrate festlegen //alles Ausgang DDRB=0b00111111; DDRC=0b11111111; DDRD=0b11111110; }
Deine Init stimmt nicht.
1 | void init_uart( uint16_t bauddivider ) |
2 | {
|
3 | UBRRH = bauddivider >> 8; |
4 | UBRRL = bauddivider; // set baud rate |
5 | UCSRA = 0; // no U2X, MPCM |
6 | UCSRC = 1<<UCSZ1^1<<UCSZ0 // 8 Bit |
7 | #ifdef URSEL
|
8 | ^1<<URSEL // if UCSR0C shared with UBRR0H |
9 | #endif
|
10 | ;
|
11 | UCSRB = 1<<RXEN^1<<TXEN; // enable RX, TX |
12 | }
|
Peter
Viktor Tschetwerik schrieb: > void init() > { > // UART initialisieren > sbi(UCSRB,3); // TX aktiv > sbi(UCSRB,4); // RX aktivieren Machs doch so wie alle anderen:
1 | UCSRB = (1<<RXEN) | (1<<TXEN); |
2 | UBRRL=(uint8_t)(F_CPU/(BAUD*16L))-1; // Baudrate festlegen |
3 | UBRRH=(uint8_t)((F_CPU/(BAUD*16L))-1)>>8; // Baudrate festlegen |
4 | // Hier was wichtiges:
|
5 | UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1 |
6 | DDRB=0xff; |
7 | DDRC=0xff; |
8 | DDRD = ~(1<<PD0); |
Und was ist denn das für eine Schreibweise >void uartPutChar(char data) >{ > //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313 > while (!(UCSRA&32)); besser:
1 | void uartPutChar(char data) |
2 | {
|
3 | //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
|
4 | while (!(UCSRA & (1<<UDRE))) ; |
5 | UDR=data; |
6 | }
|
übrigens kannst du dir das " while (!(UCSRA & (1<<UDRE))) ;" in der uartPutBin auch sparen, da du es eh bei jedem Zeichen in der uartPutChar prüfst.
Viktor Tschetwerik schrieb: > void uartPutBin(char data) > { > //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313 > while (!(UCSRA&32)); > //sende > if (data&1) uartPutChar('1'); else uartPutChar('0'); > if (data&2) uartPutChar('1'); else uartPutChar('0'); > if (data&4) uartPutChar('1'); else uartPutChar('0'); > if (data&8) uartPutChar('1'); else uartPutChar('0'); > if (data&16) uartPutChar('1'); else uartPutChar('0'); > if (data&32) uartPutChar('1'); else uartPutChar('0'); > if (data&64) uartPutChar('1'); else uartPutChar('0'); > if (data&128) uartPutChar('1'); else uartPutChar('0'); > } Also in unseren Breitengraden steht ja üblicherweise das höchstwertige Digit links. Auch muß man Flash nicht mit Gewalt vergeuden.
1 | void binout( uint8_t val ) |
2 | {
|
3 | for( uint8_t i = 8; i--; val <<= 1 ) |
4 | uputchar( '0' + !!(val & 0x80) ); |
5 | }
|
Peter
> !!(val & 0x80)
^^ das ist echt tricky, gefällt mir.
Hab sonst auch immer
1 | if(val & 0x80) |
2 | putchar('1'); |
3 | else
|
4 | putchar('0'); |
gemacht, vorteil ist natürlich dass es leserlicher ist.
Vielen dank für eure schnelle Antwort, ich habe es ausprobiert und es geht immer noch nicht. Dar selbe fehlerbild!:-( er zeigt mir laute unleserliche zeichen!
Viktor Tschetwerik schrieb: > Vielen dank für eure schnelle Antwort, ich habe es ausprobiert und es > geht immer noch nicht. Dar selbe fehlerbild!:-( er zeigt mir laute > unleserliche zeichen! Dann solltest du erst mal prüfen, ob das hier #define F_CPU 3686400 auch tatsächlich stimmt. Dort ist eine Testprozedur beschrieben: http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART Solange du die nicht positiv bestätigen kannst, macht es keinen Sinn, sich über weitere Dinge zu unterhalten. Deine Init hast du schon korrigiert?
Viktor Tschetwerik schrieb: > Vielen dank für eure schnelle Antwort, ich habe es ausprobiert und es Welche der beiden Vorschläge hast du ausprobiert? In deinem Beispiel sehe ich auch keine main() Funktion. Man kann nicht entscheiden, ob du die uart* Funktionen überhaupt korrekt aufrufst. > geht immer noch nicht. Dar selbe fehlerbild!:-( er zeigt mir laute > unleserliche zeichen! Und die wären bei welchem gesendeten Zeichen welches empfangene Zeichen? Hast du schon auf dem PC alle Baudraten (insbes. 1200 BAUD) durchprobiert? Welche Werte stehen in UBRRH und UBRRL letztendlich?
Wichtig ist zb auch hier im Original
1 | UBRRL=(uint8_t)(F_CPU/(BAUD*16L))-1; // Baudrate festlegen |
2 | UBRRH=(uint8_t)((F_CPU/(BAUD*16L))-1)>>8; // Baudrate festlegen |
das die Reihenfolge, in der 16 Bit Pseudoregister beschrieben werden, eben nicht egal ist. Diese hier ist falsch rum. Bei derartigen 16-Bit Registern: Immer zuerst H beschreiben und dann L Ein Studium des Tutorial-Artikels http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART ist dringend angeraten!
hallo, tut mir leid das ich mich lange nicht gemeldet hab, ich habe folgendes ausprobiert und es hat mehr oder weniger geklapt, blos halt zimmlich ungenu und langsam. #define F_CPU 3686400 #include <avr\io.h> //---------------------------------------------------------------------- void uartInit() { UBRRL = 23; //9600Baud siehe Baudratentabelle UCSRB = 8 + 16; //Sender enable, Empfänger enable } //---------------------------------------------------------------------- char uartGetChar() { char data=0; //warte bis RX-complete RXC UCSRA / USR bei z.B.: AT090S2313 while (!(UCSRA&128)); //empfangen data=UDR; return data; } //---------------------------------------------------------------------- void uartPutChar(char data) { //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313 while (!(UCSRA&32)); //sende UDR=data; } //---------------------------------------------------------------------- main () { uartInit(); while (true) // Mainloop { char zeichen; zeichen=uartGetChar(); uartPutChar(zeichen); } } hier ist noch die intro funktion was er mir anzeigen soll habe aus eimen bsp rausgenomen und wie es in main aufegufen wird. void intro() { uartPutChar('\n'); for (int i=0;i<42;i++) uartPutChar('='); uartPutString("\n mySmartControl Simple Term 1.2 \n www.myAVR.de"); uartPutChar('\n'); for (int i=0;i<42;i++) uartPutChar('-'); uartPutString("\nKommandos: zwei Byte, Kein Trennzeichen"); uartPutString("\n PB = PortB alle Bits ON"); uartPutString("\n pb = PortB alle Bits OFF"); uartPutString("\n PC = PortC alle Bits ON"); uartPutString("\n pc = PortC alle Bits OFF"); uartPutString("\n PD = PortD alle Bits ON"); uartPutString("\n Bx = PortB Bit X ON (X = 0..5)"); uartPutString("\n bx = PortB Bit X OFF (X = 0..5)"); uartPutString("\n Cx = PortC Bit X ON (X = 0..5)"); uartPutString("\n cx = PortC Bit X OFF (X = 0..5)"); uartPutString("\n Dx = PortD Bit X ON (X = 2..7)"); uartPutString("\n dx = PortD Bit X OFF (X = 2..7)"); uartPutString("\n iX = config Port(C,B,D) IN mit PullUP"); uartPutString("\n ix = config Port(c,b,d) IN ohne PullUP"); uartPutString("\n gx = get PIN(b,c,d)"); uartPutString("\n GX = get Port(B,C,D)"); uartPutString("\n Gx = get DDR(b,c,d)"); uartPutString("\n Ox = config Port(B,C,D) = OUT"); uartPutChar('\n'); for (int i=0;i<42;i++) uartPutChar('='); } //////////////////////////////////////////////////////////////////////// ///// // Main-Funktion //////////////////////////////////////////////////////////////////////// ///// main() { unsigned char portBuffer[3]={0}; // B,C,D char z1,z2; init(); // Initialisierungen intro(); while (true) // Mainloop-Begin Großen dank nochmal!
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.