Hallo, ich möchte ein Programm schreiben welches analoge Signale in PWM-signale umwandelt aber ich bin noch recht unerfahren in der µController-Programmierung. Das Programm funktioniert soweit auch ganz gut aber ich wollte nun eine Funktion einfügen um festzulegen das die anliegende Analogspannung 100% für die PWM entspricht. zB bei maximal anliegenden 3,7V am PortC.0 (zur Zeit ein Poti angeschlossen) soll, wenn an PortC.1 ein Taster gedrückt wird, die am PORTB.1 angeschlossene LED 100% leuchten. Wenn die maximale Spannung allerdings 4,8V sein sollte möchte ich ohne Veränderung am Programm die 4,8V als 100% zuweisen. Ich hoffe ich konnte mich verständlich machen. Vielleicht kann ja jemand sich das mal ansehen und mir sagen wo der Fehler ist. Ich bin natürlich auch für Verbesserungsvorschäge offen :) Das Programm soll später auf einen ATtiny13 umgeschrieben werden dann entfällt ja auch die Möglichkeit den Analogwert via UART auszulesen. Bisher teste ich auf einen ATmega8. Vielen Dank im vorraus.
ich glaub ich hab den Fehler gefunden. Mein PortC.1 Taster zieht auf GND wenn ich ihn drück, im Programm sollte er aber das Eingangsbit setzen. Jetzt habe ich den internen Pullup-widerstand aktiviert und statt sbis, sbic eingesetzt. Trotzdem wäre ich dankbar wenn jemand n Kommentar zu dem Programm schreibt (ist mein 1.) eine Frage hab ich aber noch: Wenn ich das Programm im AVR-Studio simuliere, löscht es die Bits im OCR1AH-register während die Werte im ORC1AL-register bleiben. Woran liegt das?
Hi >Trotzdem wäre ich dankbar wenn jemand n Kommentar zu dem Programm >schreibt (ist mein 1.) 1. Finger weg von der Tab-Taste oder schalte in den Editor-Options 'Replace tabs with space' ein. > ;2x nach rechts verschieben entspricht durch 4 teilen (um Mittelwert >zu erhalten) > lsr temp3 > ror temp2 > BRCC div1 ; Springe wenn kein Runden > INC temp2 ; Aufrunden >div1: > lsr temp3 > ror temp2 Das ist fehlerträchtig. Überlege mal was passiert, wenn dein Wert 0bxxxxxxx1 11111111 ist. Da sollte eine 16-Bit-Addition mit 1 hin. MfG Spess
Oh besten Dank, wäre mir gar nicht aufgefallen das da ein Fehler auftreten kann. 'Replace tabs with space' hab ich auch eingeschaltet. Gibt es noch weitere Stellen an denen ich noch etwas machen müsste Ich hab das Programm nochmal überarbeitet und angehängt. Den UART-Teil hab ich entfernt.
Hi
>Gibt es noch weitere Stellen an denen ich noch etwas machen müsste
Also erst mal nichts offensichtliches. Nur erschließt sich mir der
Startwert für ICR1 von $05B4 nicht so richtig. Vom AD-Wandler können
maximal $3FF kommen.
MfG Spess
spess53 schrieb: > Also erst mal nichts offensichtliches. Nur erschließt sich mir der > Startwert für ICR1 von $05B4 nicht so richtig. Vom AD-Wandler können > maximal $3FF kommen Ich hatte in der 1. Version des Programmes mir die Analogwerte via UART ausgelesen und dabei festgestellt das mein maximaler Wert eben nur 0x05B4 ist, wunderte mich auch, und hab das gleiche nochmal mit AREV probiert und kam auch auf ca 0x05B4. Daher kommt der Wert. als Anmerkung vielleicht noch: ich nutz das myAVR Board MK2 USB, bin aber auch gerade daran mir was für den ATtiny13 zu bauen.
Markus S. schrieb: > spess53 schrieb: >> Also erst mal nichts offensichtliches. Nur erschließt sich mir der >> Startwert für ICR1 von $05B4 nicht so richtig. Vom AD-Wandler können >> maximal $3FF kommen > > Ich hatte in der 1. Version des Programmes mir die Analogwerte via UART > ausgelesen und dabei festgestellt das mein maximaler Wert eben nur > 0x05B4 ist, wunderte mich auch, und hab das gleiche nochmal mit AREV > probiert und kam auch auf ca 0x05B4. Daher kommt der Wert. Kann es vielleicht daran liegen das die Analogwerte verfälscht werden wenn nebenbei die Pulsweiten-Modulation läuft?
Hi >Kann es vielleicht daran liegen das die Analogwerte verfälscht werden >wenn nebenbei die Pulsweiten-Modulation läuft? Was funktioniert denn bei dir nicht? Ich habe dein Programm mal auf einen ATMega88 umgeschrieben und getestet. Läuft. MfG Spess
Das Programm funktioniert. Aber ich frag mich warum der ADC auf die Werte kommt. Da ja bei einer 10bit-Wandlung ja nur maximal 0x3FF rauskommen sollten und nicht 0x5B4. Kann es sein das die PWM den ADC so stört das solche Werte rauskommen? @Spess53: Danke übrigens für deine Hilfe bisher.
Hi
>Kann es sein das die PWM den ADC so stört das solche Werte rauskommen?
Nein. Ich habe hier ein STK500 und ca. 50cm Kabel zwischen Poti und
PortC Steckverbinder. Kein C am ADC-Eingang. Die Werte bleiben brav im
erlaubten Bereich (Dragon mit Debugwire).
Bist du sicher, das das nicht der kumulierte Wert ist?
MfG Spess
@Spess53 Dem TO wird die Abschaltung der Tab-Taste empfohlen, kann mir bitte einer erklären warum? Macht der GCC oder der ASM "Mist", letzteres konnte ich noch nicht beobachten. Oder macht nur eine bestimmter gebräuchlicher Texteditor Probleme. Daß Tabs Ärger machen ist mir neu, lerne aber gerne hinzu. Bei Umlauten würde mich das nicht wundern, da "zicken" manche Programme. Danke für Hinweise wegen der Tabs.
Ich hab ja in der 1. Version des Programmes mir die Werte via UART ausgelesen weswegen ich ja erst festgestellt hab das sie viel höher sind als sie sein dürften. Habe ich vielleicht im UART-Teil einen Fehler gemacht?
Hi >Dem TO wird die Abschaltung der Tab-Taste empfohlen, >kann mir bitte einer erklären warum? Das hat nur mit der Darstellung des Codes in verschieden Programmen zu tun. Einrückungen mit Leerzeichen sehen in allen Programmen gleich aus. Mit Tabs unterschiedlicher Weite nicht. MfG Spess
Ich versuch ja gerade das Programm für einen ATtiny13 umzuschreiben aber ich komm an einer Stelle nicht weiter. Wie definier ich den Endwert für den Zähler? Beim ATmega8 konnte ich das ja in ICR1H und ICR1L eintragen. Aber ich finde im Datenblatt keinen Hinweis wo man das eintragen könnte.
Hi
>Beim ATmega8 konnte ich das ja in ICR1H und ICR1L eintragen.
Der Timer vom ATTiny kennt nur $FF oder OCRA als Top.
MfG Spess
ORCA ist ja der Comparewert, nehm ich an. Damit müsste ich das Programm ja komplett umschreiben damit ich wieder die Möglichkeit habe einen beliebigen Analogwert als 100% für die PWM zu zuweisen.
Hi
>ORCA ist ja der Comparewert, nehm ich an.
OCRA kann je nach PWM-Mode entweder Compare-Wert oder Top-Wert sein.
Bei letzterem ist OCRB das Compare-Register.
MfG Spess
Das heist,wenn ich den OC0B-Pin für die PWM nutze, kann ich ORCA als TOP und ORCB als Compare nutzen.
Hi >Das heist,wenn ich den OC0B-Pin für die PWM nutze, kann ich ORCA als TOP >und ORCB als Compare nutzen. Ja. MfG Spess
Super, ich dachte schon ich muss mir was neues ausdenken. Vielen Dank für die Hilfe
1 | ldi temp1, (1<<COM0A0)|(1<<COM0B1)|(1<<WGM01)|(0<<WGM00) |
2 | out TCCR0A, temp1 |
3 | ldi temp1, (1<<WGM02) | (1<<CS01) |
4 | out TCCR0B, temp1 |
Hab jetzt die Einstellungen für die Initialisierung und muss jetzt ja nur noch TOP und Compare eintragen.
Hi >Hab jetzt die Einstellungen für die Initialisierung und >muss jetzt ja nur noch TOP und Compare eintragen. Nein. Du brauchst PWM-Mode 7. Du hast 'Reserved' (6) eingestellt. MfG Spess
Oh hatte ich übersehen. Danke. Bin gerade beim testen, irgendwo hab ich noch einen Überlauf drin. Ich schau mal woran es liegen könnte und stell das Programm dann nochmal online.
Soweit so gut. Das Programm funktioniert. Das einzige was mir noch nich so gefällt ist, das bei 0V die LED noch "glimmt" und das Spannung/Helligkeit -Verhältnis noch nicht ganz linear ist. Vielleicht hat ja jemand noch eine Idee was man da noch machen könnte.
Hi >Das einzige was mir noch nich so gefällt ist, das bei 0V die LED noch >"glimmt" und das Spannung/Helligkeit -Verhältnis noch nicht ganz linear >ist. >Vielleicht hat ja jemand noch eine Idee was man da noch machen könnte. Invertierte PWM benutzen oder bei Null PWM abschalten. MfG Spess
Bei einer Invertierten PWM kann ich OCR0A (also den TOP-wert) nicht mehr so einfach definieren. Aber linearer wird das dadurch ja auch nicht oder?
Hi >Bei einer Invertierten PWM kann ich OCR0A (also den TOP-wert) nicht mehr >so einfach definieren. Was hat das damit zu tun? Lediglich das OC-Register muss mit Topwert - errechneten OC-Wert geladen werden. MfG Spess
So, hab jetzt erstmal ohne invertierte PWM weitergearbeitet damit ich meine Testplatine nicht nochmal umlöten muss. Die Änderung sieht jetzt so aus:
1 | PWM: |
2 | ; Wert in PWM eintragen |
3 | ldi temp1, 0 |
4 | cp temp2, temp1 |
5 | BRNE pwm_an |
6 | cbi DDRB,1 |
7 | rjmp weiter |
8 | pwm_an: |
9 | cp temp2, temp1 |
10 | BREQ weiter |
11 | sbi DDRB,1 |
12 | weiter: |
13 | out OCR0B, temp2 |
14 | ret |
Hi >So, hab jetzt erstmal ohne invertierte PWM weitergearbeitet damit ich >meine Testplatine nicht nochmal umlöten muss. Da braucht man nichts umlöten. COM-Bits ändern und OC-Wert wie oben berechnen. MfG Spess
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.