Halli Hallo, hab' folgendes Problem mit der SART vom Atmega128 und wär' tierisch froh wenn mir jemand helfen könnt.... Bei mir gehen irgendwie bytes verloren - ich habe ein serielle Kompassmodul (2x-cm1 oder so vgl. datasheet) welches alle 0,5 sek. 3 Byte sendet (2 Daten und 1 cheksumme) - das ganze läuft mit einem 16Mhz Quarz - Spannung am Quarz ist messbar also läuft er wohl auch damit..... Das Programm soll lediglich die 2 Daten bytes zu einem int zusammenfassen und am LCD ausgeben - es wirde ddann noch eine berechnete Checksumme und einen empfange Checksumme ausgegeben. Leider kommt immer nur Blödsinn raus - der Bytecounter (der auch auf dem LCD dargestelt wird) läiuft viel zu langsam (ca. 1byte pro Sekunde) und setzt manchmal sogar aus. Die Daten vom Kompass kommen aber richtig (test mit Hyperterm) Hoffe ihr könnt mir helfen!!! Anbei noch mein Programm. Vielen Dank Christian unsigned int kompass = 0 ; unsigned char uart_recv = 0; char lcd_buffer[30]; unsigned char check_sum; unsigned int byte = 0; unsigned char uart_rxbuf[4]; unsigned char uart_rx_pos; unsigned char uart_trans; unsigned char x = 0; typedef unsigned char u08; void calc_kompasswert(void) { kompass = (( uart_rxbuf[2]*256) + uart_rxbuf[1] ) /2; uart_rx_pos = 0; check_sum = 0xFF + uart_rxbuf[2] + uart_rxbuf[1]; } SIGNAL(SIG_UART0_RECV) { uart_rx_pos++; byte++; uart_rxbuf[uart_rx_pos]=inp(UDR0); if (uart_rx_pos == 3) calc_kompasswert(); } void print_info(void) { set_cursor_pos(0,0); //gibt die x und y Position auf dem LCD an sprintf(lcd_buffer, "Kompasswert: %u ", kompass); lcd_printstring(lcd_buffer); set_cursor_pos(0,1); //gibt die x und y Position auf dem LCD an sprintf(lcd_buffer, "gelesene bytes: %u ", byte); lcd_printstring(lcd_buffer); set_cursor_pos(0,2); //gibt die x und y Position auf dem LCD an sprintf(lcd_buffer, "uart_rx_pos bytes: %u ", uart_rx_pos); lcd_printstring(lcd_buffer); set_cursor_pos(0,3); //gibt die x und y Position auf dem LCD an sprintf(lcd_buffer, "Check Summe MC berechnet: %u" , check_sum); lcd_printstring(lcd_buffer); set_cursor_pos(0,4); //gibt die x und y Position auf dem LCD an sprintf(lcd_buffer, "Check Summe Kompass: %u ", uart_rxbuf[3]); lcd_printstring(lcd_buffer); set_cursor_pos(0,5); //gibt die x und y Position auf dem LCD an sprintf(lcd_buffer, "empfangene Bytewerte: %u, %u ", uart_rxbuf[0],uart_rxbuf[1]); lcd_printstring(lcd_buffer); } void main(void) { cbi (UCSR0A, 1); outp((1<<RXCIE)|(1<<RXEN)|(1<<TXEN),UCSR0B); /* enable RX interrupt */ //UCR wurde durch UCSRB getauscht!! outp(207, UBRR0H); //9600bps uart_rxbuf[4] = 0; t6963c_init(); uart_rx_pos = 0; print_info(); sei(); /* enable interrupts */ for (;;) //loop forever { print_info(); } }
Kann es sein, daß du vergessen hast von 1 MHz internem Oszillator auf externen Quarz umzustellen?
Servus. vergessen hab' ichs sicherlich nicht, aber möglicherweise falsch gemacht. Wollt gerade die Fuse bits Einstellungen ändern aber jetzt funktioniert mein Kompassmodul plötzlich nicht mehr - hoffentlichhab' ichs nicht falsch rum angeschlossen..... Vielen Dank!! Christian PS: Das Listening oben ist übrigens falsch - da hab' ich gerade mit den Baudrate settings rumgespielt - ansonsten ist es aber unverändert
Würde ich auch vermuten. Im Auslieferzustand laufen den neuen Megas alle mit dem internen RC-Oszillator auf ca 1MHz. Da muß man erst mal per ISP ein paar Fuses umbiegen. Gruß Markus
Hallo, es funktioniert leider immer noch nicht und ich bin mittlerweile echt am verzweifeln (mal wieder) - im Anhang hab' ich mal meine Lockbit Konfiguration mitgepostet - vielleicht könnte ihr mir ja helfen!!! Vielen Dank Christian
Nochmal Hallo, das Problem hat sich geändert: nachdem ich feststellen musste, dass ich vor lauter dummheit die Baudratesettings in das falsche Register geschrieben habe wird zwar jetzt ein String empfangen, allerdings hat dieser plötzlich 4 bytes und nicht wie gehofft 3 - was jetzt schon wieder falsch? Bin über eure Anregungen immer noch froh und dankbar!!! mfg Christian
Hallo Christian,
das du die Baudrate in UBRRH anstelle in UBRRL geschrieben hast, war
mir schon aufgefallen, aber du hattest ja geschrieben, das du daran
rumgebastelt hast. Was mich allerdings verunsichert hat sind die
merkwürdigen 0en in den Registerbezeichnungen (UBRR0H, UDR0... ?). U2X
zu setzen ohne Not, halt ich eigentlich nicht für sinnvoll (wenn nicht
gesetzt dann UBRLL =103.
> allerdings hat dieser plötzlich 4 bytes ...
Werf doch noch mal einen Blick auf das Datenblatt.
Wenn du dem Teil keinen Befehl sendest sollte er eigentlich nach dem
Einschalten alle 0,5 Sekunden 4-byte senden LSB, MSB, check sum und 13h.
Gruß Bernhard
Hallo Bernhard, vielen Dank für den Tipp - du hast mir sehr weitergeholfen - anscheinend bin ich wirklich nicht in der Lage Datenblätter zu lesen (ich hab's bestimmt 2x gelesen und mehrmals überflogen als ich nach irgendwas geschaut hab....) Dass ich U2X gesetzt habe war auch nur so eine Baudratenspielerei, die ganzen nullen in den Registerbezeichnungen hab' ich verwendet, weils der avrgcc sonst nicht verstanden hat welche USART ich haben will (siehe iom^128.h im Anhang). Die 13h werden zuverlässig übermittelt, allerdings scheinbar immer an 3. Stelle im Datenstring, an 1. Stelle im String kommt immer 128 egal wie ich den Kompass drehe und die 2. und 4. Stelle variiert - keine Ahnung was ich Hirschkopf jetzt schon wieder verpasst hab'.... Vielen Dank nochmals!! mfg Christian
Hallo Christian, ich hab's auch nicht immer so mit dem lesen (der Mega128 hat ja 1 USART mehr als mein Mega8). Was mir aufgefallen ist, ist das deinem Kompass ja bei einem Fehler während der Kalibrierung das bit7 im MSB setzt (=128 !), und wenn mein Englisch mich nicht täusch zeigt er das anschließend auch an.:(If the distortion warning displays continuously or display after calibration , then user is suggested to perform calibration again , where there is less magnetic interference.) Hast du das Problem mit der Reihenfolge auch wenn du mit nem Terminalprogram testest? P.S. Was kostet denn so ein Teil, und woher ? Gruß Bernhard
vielleicht liegt es aber auch daran: Deine RX-Routine weist dem erstem Byte uart_rxbuf[1] zu SIGNAL(SIG_UART0_RECV) {uart_rx_pos++; (Zähler wird hier schon erhöht) byte++; uart_rxbuf[uart_rx_pos]=inp(UDR0); if (uart_rx_pos == 3) calc_kompasswert(); } Du läßt dir aber später uart_rxbuf[0] anzeigen. Gruß Bernhard
Hallo, das Ding hat ungefähr 60 Euro gekostet und gekauft hab ichs bei www.jpohl.de (noch nicht online - musst eine mail schreiben). Mit dem Hyperterminal funktionierts mit der Reihenfolge - hab' ich mir schon gedacht.... Den Fehler auf den du mich hingewiesen hast ist nur im alten Listening - im neuen sollts eigentlich nicht mehr so sein (is aber so....) Wär toll wenn sich das jemand anschauen könnt!! mfg Christian
die angaben von uart_rxbuf[x] stimmen selten, weil ich da ein wenig rumgespiel habe!! Fakt ist uart_rxbuf[3] ist immer 13H, aber das ist ja das 3.Byte im String und muss eigentlich das 4. sein?!?
Hi! meines erachtens sind rxbuf[0] bis rxbuf[3] = 4Byte. Oder habe ich einen Denkfehler? Uwe
Ja stimmt schon und ich zähl bis rx_buf[4], weil rx_buf0 immer gleich übersprungen wird - das kann man sicherlich intelligenter und Speicher sparender lösen, aber daran liegts meiner Meinung nach nicht.... mfg Christian
Na das war ja diesmal eine extrem schwierige Geburt, aber jetzt gehts!! HHHHUUUURRRRAAAA !!!!!!!!!!!!!! Vielen Dank an alle die ihre Zeit geopfhert haben um mir zu helfen!! Viele Grüße Christian
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.