Hellö Neuer Ansatz neuer Aufhänger xD Ich möchte mittlerweile gezielt zeichen über den UDR aus meinem Mega16 schicken. ich lade dabei einzelne zeichen in ein register und gebe sie nach und nach am UDR aus. damit sich der gute Controller nicht aufhängt hab ich einen skip befehl eingebaut falls das UDRE flag noch gesetzt ist. nun die kontroverse: nach dem zweiten gesendeten zeichen (immer mit der selben befehlsreihnfolge) ist das UDRE nicht mehr gesetzt. Es hat sich allerdings nie etwas geändert. ich hab sogar mit den komplet selben zeichen probiert also vermute ich mal das es mit der häufigkeit bzw.: der zeilenanzahlzusammenhängt. Oder will deas UDRE nach einiger zeit einfach nicht mehr Arbeiten???? bitte bitte bitte helft mir dieses arbeitsfaule flag zu motivieren. p.s.: gut zureden hat leider nicht funktioniert
Meistens sitzt die Ursache solcher Fehler vor Deiner Tastatur. Es hilft dann überhaupt nichts, zu beschreiben, wie Du denkst, daß die selbst gestrickte Software funktionieren sollte. Exaktes Copy&Paste in den Dateianhang ist das einzige Mittel, was hilft. Peter
Wie wäre es mit etwas Code? Dass der Controller ein zweistufiges UDR hat, hast du schon gemerkt, oder? So wie ich deine Anwendung verstehe, wäre sie prädestiniert für den Einsatz eines (Ring-)Puffers und entsprechender Indezes. UDRE wird schon seinen Job richtig machen. Das Problem liegt garantiert an deiner Software, die bis jetzt für uns leider unsichtbar geblieben ist...
Die markanten ounkte sind diese.... ich hab ihm jetzt drei mal ein s senden lassen damit alle bedingungen gleich sind. Nein ich benutze kein interrupts bezüglich senden/empfangen Schleife: ldi temp, 's' rcall serout ldi temp, 's' rcall serout ldi temp, 's' serout: sbis UCSRA,UDRE rjmp serout out UDR, temp ret
Das UDRE kommt wenn das UART Datenregister im Sendefall leer ist. Falls das nicht kommt, wird zb nicht gesendet, indem das UART nicht eingeschaltet wurde. holzi
Jetzt wäre interessant, was zwischen "ldi temp,'s'" und "serout" steht. Da steht zwar etwas von einer Schleife, die endet aber an einem "ret" und das gibt auf Dauer einen Stacküberlauf (oder -unterlauf?).
Der Code-Ausschnitt sieht nicht so schlecht aus. Woher weist du, dass das Bit nicht gesetzt wird? (Wie testest du?). Sieht so aus, als ob du mal ein komplettes Testprogram posten müsstest (vorher aber abklären, ob das Testprogram dieselben Symptome zeigt).
danke für eure antworten. fahr jetz nach hause und werd mich dann von dort nochmal damit beschäftigen. also bitte keine antworten in naher zukunft erwarten xD liebe grüße tekknö
oha das programm könnt ihr gerne haben. bin nur grad am zusammenpacken (blöde weihnachtsfeier der lehrer inner schule) schick alles von zu Hause. Danke nochmal vielmals
rjmp Schleife fehlt. Dann geht´s (vorausgesetzt, das UART ist korrekt initialisiert).
so wieder da. das rjmp schleife ist eh vorhanden ^^ ist nur ein ausschnit aus der schleife. hab das programm angefügt und hoffe ihr könnt mir nun weiterhelfen und macht mich nicht NUR auf Fehler im programm aufmerksam ;) danke im voraus Tekknö
Das Programm (ups... ich arbeite serwohl mit nem interrupt) .include "m16def.inc" .def temp = R16 .equ CLOCK = 4000000 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 .org 0x00 rjmp Hauptprogramm .org URXCaddr rjmp int_rxc Hauptprogramm: ldi temp, LOW(RAMEND) out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ldi temp, 0xFF out DDRC, temp ldi temp, LOW(UBRRVAL) out UBRRL, temp ldi temp, HIGH(UBRRVAL) out UBRRH, temp ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp sbi UCSRB, RXCIE sbi UCSRB, RXEN sbi UCSRB, TXEN sei Schleife: ldi temp, 's' rcall serout ldi temp, 'v' rcall serout ldi temp, 32 rcall serout ldi temp, '0' rcall serout ldi temp, 32 rcall serout ldi temp, '1' rcall serout ldi temp, '8' rcall serout ldi temp, '0' rcall serout ldi temp, 13 rcall serout rjmp Input serout: sbis UCSRA,UDRE rjmp serout out UDR, temp ret int_rxc: push temp in temp, UDR out PORTC, temp pop temp reti
sorry hab ich aus versehn gelöscht :( ldi temp, 0x00 out DDRA, temp --> gehört nach ausgaberegister deffinnition Input: in temp, PORTA inc temp dec temp brne Schleife rjmp Input ---> vor interrupthandler
Sollte man nicht erst UBRRH und danach UBRRL schreiben? Ausserdem fehlt das Label Input, rjmp Input funktioniert nicht. Was soll ldi temp, (1<<URSEL)|(3<<UCSZ0) bewirken? URSEL finde ich nicht in der Doku von Atmel. MfG Falk
URSEL muß beim setzen von UCSRC immer gesetzt werden, da dieses Register mit UBRRH geteilt ist.
Stimmt UBRRH muß zuerst geschrieben werden. Außerdem sichert die RXC Interrupt-Service-Routine nicht das Status-Register und stellt es auch nicht wieder her. Das sollte in jedem Fall noch gemacht werden. @Falk: das Label Input ist doch da.
in Temp, PortA muß in Temp, PinA heißen. inc Temp und darauffolgend dec Temp macht keinen Sinn.
Danke für die anworten aber was muss den noch alles gesichert werden? reicht das temp register nicht? und spielt das beim senden der schleife nicht sowieso keine rolle? es wird doch nichts empfangen?
Ich frage nochmal: Woher weist du eigentlich, dss sich das Bit abartig verhält? Wie testest du? Gehts einfach nicht oder hast du stichhaltige Anhaltspunkte dass es das Flag ist.
das mit inc und dec hab ich gemacht weil ich sonst keine ahnung hab wie ich es sonst vergleichen soll ^^ bin noch ein bischen schwach im programieren wie ihr unschwer erkennen könnt ;) und das mim PINA sind kleine fehler da ich es sowieso noch nich auf meinem stk500 probiern konnte (blöde weihnachtsfeier)
ich teste es mit AVRStudio und seh mir seinen status ganz einfach an. habs sowohl mit singe step als auch mit autostep auf 4 kHz und breakpoints angesehn.
Das Statusregister auf jeden Fall sichern, es enthält sämtliche Flags der Arithmetischen Einheit des Controllers. Machst Du im Interrupt eine Berechnung, dann paßt nach dem Verlassen des Interrupts das Statusregister nicht mehr, was in Deinem Hauptprogramm zu folgenschweren Fehlinterpretationen führen kann. Ansonsten müssen alle Register, die Du in der ISR verwendest, zuvor gesichert und am Ende rückgesichert werden.
> sowieso noch nich auf > meinem stk500 probiern konnte Daraus entnehme ich, dass du das bisher nur im Simulator hast laufen lassen. Stimmt das?
wie kann ich denn bitte auf das SREG zugreifen oder es auslesen? kann im Assembler helpfile keinen passenden befehl finden und wenn ichs als SREG eingeb bekomm ich die meldung invalid register :( (wie gesagt: schwach im programieren sichschämentut)
Danke allen die hier was geantwortet haben. mein prof hat mir grad eine nette mail bezüglich dem RICHTIGEN :( setzen der break points geschrieben..... hat eh wunderbar funktioniert ;) @Karl Heinz: sorry das ich an dir bzw dem flag gezweifelt hab. kommt nicht wieder vor :)
> Karl Heinz: sorry das ich an dir bzw dem flag gezweifelt hab. kommt > nicht wieder vor :) Kein Problem. Die Sache ist nur die: Auch dem Simulator kann man nicht immer trauen. So ein Simulator ist letztendlich auch nur ein Programm :-)
Und dann auch noch eins auf ´nem W.....f - PC, dem sollte man sowieso nicht trauen ;-)
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.