Hy, Ich habe hier einen Atmega8L ohne Quarz mit FTDI232 Kabel an meinem Laptop. Ich sende Strings an die USART des m8 welche er im EEPROM speichert und mir über Int0 dann wieder am USART ausgeben soll. Das funktioniert auch, bis ich mit der BaudRate hochgehe bis (die erforderlichen) 57600! Je höher die BaudRate wird umso weniger Zeichen bekomme ich zurück, oder vertauschte Zeichen. So sieht die Ausgabe im Terminal (Termite3.1) aus : 1Gesendet: 1200=Baudrate/Test:1234567890123456789012345678901234567890 1Bekommen: 1200=Baudrate/Test:1234567890123456789012345678901234567890 Soweit OK 2Gesendet: 2400=Baudrate/Test:1234567890123456789012345678901234567890 2Bekommen: 2400=Bart/et13579135791357913579 Schlecht 3Gesendet: 4800=Baudrate/Test:1234567890123456789012345678901234567890 3Bekommen: 4800=r/t3715937159 Schlechter 4Gesendet: 57600=Baudrate/Test:1234567890123456789012345678901234567890 4Bekommen: 57600 Depremierendes Ergebniss! Im HTerm siehts genauso aus! Hab schon einiges probiert, aber immer mit dem gleichen Ergebniss! *1 Am fehlenden Quarz oder der Baudratenabweichung von 3,6% sollte es nicht liegen weil ich grössere ZeichenStrings ohne Probleme schicken kann, nur nicht im EEPROM speichern. *2 Die Interrupts kommen sich auch nicht in die quere. "Glaubichhaltso" *3 Kann es sein das "usartrxc"-ISR zu langsam ist und sich nach ein paar Zeichen verhaschpelt? Hier der Quellcode: [avrasm] .include "m8def.inc" ; .equ f_cpu = 8000000 ;Prozessortakt .equ baud = 57600 ;Gewünschte Baudrate ; .equ ubrr_val = ((f_cpu+baud*8)/(baud*16)-1);Clever runden .equ baud_real = (f_cpu/(16*(ubrr_val+1)));Reale Baudrate .equ baud_error =((baud_real*1000)/baud-1000) ;Fehler in Promille ; .if ((baud_error>36) || (baud_error<-36)) .error "Baudrate Error" .endif ; intx0:;;;;;;;;;;;;;;;Insert Interrupt Routine bei Tastendruck ; eeprom_read: sbic eecr, eewe rjmp eeprom_read out eearh, zh ;EEPROM Adresse bekantgeben out eearl, zl sbi eecr, eere in zeichen, eedr ; serout: sbis ucsra, udre rjmp serout out udr, zeichen ;Zeichen senden ; adiw Zl, 1 ; Zeiger erhöhen cpi zeichen, '\r' ; auf CR warten brne eeprom_read ;ungleich, springen ldi ZL, low(Daten) ldi ZH, high(Daten) lange_pause reti usartrxc:;;;;;;;;;;;Insert Interrupt Routine ; in zeichen, udr ;Zeichen holen ; eeprom_write: sbic eecr, eewe rjmp eeprom_write out eearh, zh ;EEPROM Adresse bekantgeben out eearl, zl out eedr, zeichen ;Zeichen laden sbi eecr, eemwe sbi eecr, eewe ;Zeichen absenden an EEPROM ; adiw Zl, 1 ; Zeiger erhöhen cpi zeichen, '\r' ; auf CR warten brne eeprom_write1 ; wenn ungleich, springen ldi ZL, low(Daten) ; zurücksetzen ldi ZH, high(Daten) eeprom_write1: reti ;;;;;;;;;;;;;;PROGRAMM START;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; reset: ldi ssr, high(RAMEND) ;Stack out sph, ssr ldi ssr, low(RAMEND) out spl, ssr ; ldi ZL, low(daten) ldi ZH, high(daten) ; sbi ucsrb, txen ;USART senden aktiviert sbi ucsrb, rxen ;USART empfangen aktiviert sbi ucsrb, rxcie ;Interrupt bei USART Empfang ldi ssr, (1<<ursel | 1<<ucsz1 | 1<<ucsz0) out ucsrc, ssr ;8 Datenbits, kein Parity, 1 Stop ldi ssr, HIGH(ubrr_val) out ubrrh, ssr ldi ssr, LOW(ubrr_val) out ubrrl, ssr ; sei loop: rjmp loop .ESEG Daten: .db 0 [avrasm]
:
Bearbeitet durch User
Serout() ist ja blockierend. Das geht so natuerlich nicht. Mach das per interrupt.
Schau mal im Datenblatt nach, wie lange das Schreiben eines EEPROM Bytes dauert. Das darf bei Dir nur eine Byte-Zeit beim UART lang sein, was vermutlich nur für 1200 Baud zutrifft. Abhilfe für schnellere Baudraten: String puffern und erst am Ende der Übertragung ins EEPROM schreiben.
Jim Meba schrieb: > Schau mal im Datenblatt nach, wie lange das Schreiben eines EEPROM Bytes > dauert. Das darf bei Dir nur eine Byte-Zeit beim UART lang sein, was > vermutlich nur für 1200 Baud zutrifft. Im Datenblatt steht 8,5ms/Byte abhängig von der Genauigkeit des internen RC-Oscillators (1MHz und unabhängig von der tatsächlichen CPU clock). Das ergibt 117,6 Bytes pro Sekunde und ist für 1200 Baud eigentlich schon zu knapp.
:
Bearbeitet durch User
Jim Meba schrieb: > Schau mal im Datenblatt nach, wie lange das Schreiben eines EEPROM Bytes > dauert. Das darf bei Dir nur eine Byte-Zeit beim UART lang sein, was > vermutlich nur für 1200 Baud zutrifft. > > Abhilfe für schnellere Baudraten: String puffern und erst am Ende der > Übertragung ins EEPROM schreiben. Klaus 2m5 schrieb: > Im Datenblatt steht 8,5ms/Byte abhängig von der Genauigkeit des internen > RC-Oscillators (1MHz und unabhängig von der tatsächlichen CPU clock). > > Das ergibt 117,6 Bytes pro Sekunde und ist für 1200 Baud eigentlich > schon zu knapp. Genau das habe ich auch gerade gelesen. Das wird wohl der Fehler sein! :-) Wenn ich fertig bin mit lesen und programmieren werd ich mal posten wies ausgegangen ist. Vielen Dank erstmal.
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.