Ich hatte keinen ADC da um Werte mit dem PC zu messen, daher habe ich ein kleines Programm für den AT90S8535 geschrieben, um die Spannungen an den 8 Eingängen zu messen. Durch Befehle kann man die einzelnen Kanäle abfragen, oder zwischen 10 oder 8bit Wählen (Bit ADC10 in Register Bits gesetzt oder nicht). Ebenso wird entweder einmal oder kontinuierlich umgewandelt und übertragen (Bit FreeRun in Register Bits, ich verwende dabei nicht den FreeRun Modus des ADC sondern den Singe Modus !). Wenn ich nur einmal umwandle (FreeRun gelöscht), dann funktioniert alles. Ist aber das Bit FreeRun gesetzt, wird am Ende der ADC Interrupt Routine nach der Übertragung wieder eine neue Umwandlung gestartet und somit ununterbrochen Werte übertragen. Aber das funktioniert nicht. Ich bekomme falsche Werte und Framing Fehler. Hier der Code der ADC Interrupt Routine: ADC_COMPLETE_INT: ;ADC Interrupt sbis USR,UDRE ; wait for TX to be ready rjmp ADC_COMPLETE_INT; no, wait some more sbrc Bits, ADC10 rjmp ADC10bitSend in r18, ADCL in r0, ADCH ror r0 ror r18 ;10bit -> 8bit ror r0 ror r18 out UDR, r18 sbrc Bits, FreeRun sbi ADCSR, ADSC reti ADC10bitSend: sbrc Bits, FreeRun cbr Bits, 1 in r18, ADCL out UDR, r18 HBWait: sbis USR,UDRE ; wait for TX to be ready rjmp HBWait ; no, wait some more in r18, ADCH out UDR, r18 sbrc Bits, FreeRun sbi ADCSR, ADSC reti
Hi... Sehe ich das richtig? Du hast in der ADC-ISR eine Warteschleife auf "UART fertig"?? Warteschleifen in ISRs sind sträflich! Du musst die ISR so schnell wie möglich verlassen, damit andere Interrupts nicht blockiert werden. Schick das doch mal durch den Simulator (ich kann es nicht, da ich nicht das komplette Programm habe). Ich arbeite oft mit ADC (Tiny15, Mega8, 8535/Mega8535), meist lasse ich den ADC im Free-Running-Mode (Ohne Int!!!) vor sich hin klappern und lese das nächste Wertepaar aus, wenn ich es brauche, meist durch einen Timer-Interrupt gesteuert. Dabei muss ich natürlich überprüfen (rechnen), dass der ADC auch fertig ist, danach richtet sich auch der Vorteiler. Notfalls (wenn man nicht vorhersagen kann, wann der nächste Wert ausgelesen werden soll) muss man vor dem Auslesen des ADC eben in einer Schleife das ADC-Int-Flag abfragen (Datenblatt fragen). Aber dies im normalen Code und nicht in einer ISR! Viel Erfolg, Bit- & Bytebruch... ...HanneS...
Der ADC ist so eingestellt, dass er langsamer ist als das Senden eines Bytes. Da der uC nur als ADC arbeitet und sonst nicht viel zu tun hat, ist eine Warteschlange in der ISR nicht weiter schlimm. Außerdem stelle ich das Programm auf den Noice canceler Modus um, da wird der Mikrocontroller sowiso während der Messung angehalten... Den Fehler habe ich jetzt auch gefunden: Es lag am Kabel ! Mir fiel auf, dass die Transmit (PC->uC) LED am MAX232 aufleuchtet, obwohl ich keine Daten sende, nur Daten empfange. Anscheinend ist der MAX232 (kein orginal MAX, sondern so ein billig Nachbau) etwas empfindlicher und das Kabel (ca.5m) hat zu hohe Kapazitäten zwischen den beiden Leitungen. Mit kurzem Kabel geht es jetzt einwandfrei, seltsam ich hatte damit bisher noch nie Probleme... Das beste ist immer noch Stereo Audioleitung mit eigener Abschirmung um jede Leitung.
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.