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();
}
}
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?!?
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