Forum: Mikrocontroller und Digitale Elektronik Analog zu PWM. Fehler im Programm?


von Markus S. (flash_gordon)


Angehängte Dateien:

Lesenswert?

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.

von Markus S. (flash_gordon)


Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Angehängte Dateien:

Lesenswert?

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.

von Markus S. (flash_gordon)


Angehängte Dateien:

Lesenswert?

Und nochmal ohne Tabs ;)

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

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.

von Markus S. (flash_gordon)


Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Anton (Gast)


Lesenswert?

@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.

von Markus S. (flash_gordon)


Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

Das heist,wenn ich den OC0B-Pin für die PWM nutze, kann ich ORCA als TOP 
und ORCB als Compare nutzen.

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

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.

von Markus S. (flash_gordon)


Angehängte Dateien:

Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

von Markus S. (flash_gordon)


Lesenswert?

stimmt, hatte grad ein Denkfehler.

von Markus S. (flash_gordon)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.