www.mikrocontroller.net

Forum: Compiler & IDEs Veränderbare Spannung per PWM @ Atmega16 und dazugehöriges.


Autor: Basti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, jetzt habe ich mich doch schon etwas mit meinem nun funktionierenden 
Atmega16 auseinandergesetzt.
Was ich jetzt gerne als Endprodukt hätte ist folgendes:

Der µC soll in der Lage sein eine konkrete Spannung zwischen 0 und 5V 
auszugeben. Also soll man zB. am PC sagen können "Lass ma 3V 
rüberwachsen", per Nullmodemkabel wird der für den µC passende Befehl an 
diesen weitergegeben und dieser setzt per PWM einen Pin auf eben die 
gewünschten 3V.

Das ganze 2 mal, und zwar sollten auch verschiedene Spannungen möglich 
sein ("Pin X bitte 3V, Pin Y bitte 2,5V").




Gegebenenfalls bitte erst die Posts weiter unten lesen bevor man sich 
durch meine langen Texte wühlt, wenn dort schon über andere Fragen 
diskutiert wird, wurden die früher beschriebenen Probleme vermutlich 
schon gelöst ;-)







Wie ich mich bisher an diese Aufgabe herantaste:

Hab mir alles was ich hier an PWM-Tutorials finden konnte durchgelesen 
und denk dass ich die Funktionsweise von PWM soweit verstanden habe. 
Allerdings bin ich auch im Umgang mit C nicht gerade geübt, weshalb noch 
ein paar Fragen auftauchen.
Ich möchte jetzt erst einmal Versuchen dass ich die Spannungen 
herbekomme die ich gerne hätte, aber irgendwie bekomm ich das noch nich 
so ganz hin...

Ich hab mir aus gefundenen Programmstücken bzw. nach den verschiedenen 
Tutorials folgende Grundversion zusammengeschrieben:

#include "avr/io.h"
#include <avr/pgmspace.h>
#define F_CPU 11059200
#include <util/delay.h>

void init(void)
{
DDRD=0b00110000;    //Pin 18 und 19 als Ausgang
ICR1=0xFFFF;      //Top-Wert
TCCR1A=0b10100010;  //fast PWM, mode 14, non-inverting
TCCR1B=0b00011001;  //fast PWM, no clock division
OCR1A=0x8000;      //Compare-Wert A
OCR1B=0x8000;      //Compare-Wert B
}

int main(void)
{
init();

return 0;
}



Läuft soweit alles, ich hab als Comment mal die "Auswirkungen" der 
Einstellungen angefügt, hoffe doch das das soweit Korrekt ist, wenn 
nicht bitte bescheid geben =)

Achja, delay.h hab ich noch drin weil ich vorher mit nachfolgendem 
Pausieren in der Main-Schleife gespielt hab, will das aber erstmal 
rauslassen.


Habe nun an Pin 18 und 19 je einen 100k Ohm Widerstand und nen 22nF 
Kondensator angelötet, wie hier halt:
http://www.mikrocontroller.net/articles/Bild:Pwm_f...


Wie gesagt, das Progrämmchen läuft, aber wenn ich jetzt die 
Ausgangsspannung messen möchte bekomme ich bei Pin 18 die zu erwartenden 
2,5V, an Pin 19 allerdings steigt die Spannung in ca. 7 Sekunden von 0 
auf 5V an, fällt wieder auf 0 usw.
Ich dachte ich hätte die beiden Ausgänge identisch programmiert, hab ich 
mir da doch irgendwelche Programmteile falsch "zusammengeklaut" bzw. was 
in der Programmierung falsch Verstanden?
Wäre schön wenn ihr mir dabei weiterhelfen könntet =)

Tja und nun das zweite Problem:

Nach diesem Tutorial:
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
steht so schön "Durch Verändern des OCR1A Wertes werden die 
unterschidelichen PWM Werte eingestellt"
Wenn ich da allerdings was ändere passiert gar nix: Pin 18 behält seine 
2,5V bei, Pin 19 sein (aus meiner Sicht) komisches Verhalten.

Wiederum bin ich Dankbar wenn mir jemand Aufklärung verschafft, entweder 
stimmt was nich oder ich hab was falsch aufgefasst.



So, das wars erstmal, ich werde vermutlich dieses Thema für im weiteren 
Verlauf auftretende Fragen mitbenutzen.

Schonmal vielen Dank für eure hoffentlich zahl- oder lieber hilfreichen 
Antworten ;-)

Basti

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Programm ist nicht sonderlich hübsch, aber es funktioniert.
Die Registerbits solltest du besser mit symbolischen Namen
benennen, also:
TCCR1A=_BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);
TCCR1B=_BV(WGM12) | _BV(WGM13) | _BV(CS10);

Ich habe es bei mir auf einen herumliegenden ATmega16 geflasht,
und bekomme zwei saubere 1:1-Rechtecksignale an PD4 und PD5.
Dein Fehler muss also irgendwo anders liegen.

Hier das Hexfile:
:100000000C942A000C9447000C9447000C94470071
:100010000C9447000C9447000C9447000C94470044
:100020000C9447000C9447000C9447000C94470034
:100030000C9447000C9447000C9447000C94470024
:100040000C9447000C9447000C9447000C94470014
:100050000C94470011241FBECFE5D4E0DEBFCDBF16
:1000600010E0A0E6B0E0EAECF0E002C005900D92EE
:10007000A036B107D9F710E0A0E6B0E001C01D92AC
:10008000A036B107E1F70E945A000C9464000C946A
:10009000000080E381BB8FEF9FEF97BD86BD82EAB2
:1000A0008FBD89E18EBD80E090E89BBD8ABD99BD82
:1000B00088BD0895CFE5D4E0DEBFCDBF0E944900E2
:0A00C00080E090E00C946400FFCF94
:00000001FF

Autor: Basti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, ich glaub ich spinn -.-

Hab jetzt nochmal das gepostete Programm genommen und in hex umgewandelt 
(compiliert, oder?), sowie das gepostete Programm mit deiner Änderung 
versehen und umgewandelt, stimmt aber einfach nicht mit dem von dir 
erzeugten Hexfile überein :S

Ich bekomm folgende Hex-Datei raus:

:100000000C942A000C9447000C9447000C94470071
:100010000C9447000C9447000C9447000C94470044
:100020000C9447000C9447000C9447000C94470034
:100030000C9447000C9447000C9447000C94470024
:100040000C9447000C9447000C9447000C94470014
:100050000C94470011241FBECFE5D4E0DEBFCDBF16
:1000600010E0A0E6B0E0EEEDF0E002C005900D92E9
:10007000A036B107D9F710E0A0E6B0E001C01D92AC
:10008000A036B107E1F70E945A000C946D000C9461
:10009000000080E381BB8FEF9FEF97BD86BD82EAB2
:1000A0008FBD89E18EBD80E090E89BBD8ABD99BD82
:1000B00088BD089580E381BB8FEF9FEF97BD86BD1C
:1000C00082EA8FBD89E18EBD80E090E89BBD8ABD4C
:0E00D00099BD88BD80E090E00895F894FFCFC0
:00000001FF



Mit deiner hexfile funktioniert es richtig, beide Pins liefern 2,5V. Bei 
mir hauts eben nicht hin. Was für ein Programm bzw. was für einen 
Compiler benutzt du denn?
Ich hatte jetzt mit AVR Studio und dazu installiertem WinAVR gearbeitet.

Hoffe das ich die Lösung find, wenn bei mir was falsch compiliert wird 
kanns ja nich laufen >.<

Autor: Sebastian L. (boaschti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achja: könntest du vielleicht einfach das komplette Programm so posten 
wie dus compiliert hast, vielleicht is ja doch was anders :S

Ansonsten: was kann ich probieren um zu sehen woran es liegt?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich vermute mal, dass du irgendwo eine falsche Einstellung zum Prozessor 
gemacht hast. Welche Software benutzt du zum Programmieren?

Autor: Sebastian L. (boaschti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie gesagt AVR Studio 4.15, build 623 mit installiertem WinAVR 
(1.0.0.10).

Hab halt beim Projekt erstellen "AVR GCC" ausgewählt, dann "AVR 
Simulator" und den ATmega16.

Auf 2 Computern probiert, das Ergebnis is immer das Selbe und stimmt mit 
dem Post von Jörg nicht überein.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian L. wrote:
> Wie gesagt AVR Studio 4.15, build 623 mit installiertem WinAVR
> (1.0.0.10).

Was auch immer WinAVR 1.0.0.10 sein soll...  WinAVR-Versionsnummern
sind normalerweise in der Form YYYYMMDD.

> Auf 2 Computern probiert, das Ergebnis is immer das Selbe und stimmt mit
> dem Post von Jörg nicht überein.

Meins war mit einem GCC 4.2.2 compiliert.  Der Unterschied ist, dass
bei mir die Funktion init() wirklich gerufen wird, bei dir dagegen
hat der Compiler sie in main() inline erweitert.  Da die Funktion aber
nicht "static" deklariert ist, musste er trotzdem noch eine Kopie
separat anlegen (damit sie als globale Funktion ggf. von anderen
Modulen aufgerufen werden kann -- dass du keine anderen Module weiter
haben wirst, hast du bzw. AVR Studio ihm nicht mitgeteilt).  Kann
aber auch sein, dass es simpel nur eine andere Optimierung war (bei
mir -Os).

Anyway: dein Hexfile läuft bei mir genauso.  Warum auch nicht, der
tatsächlich ausgeführte Code ist der gleiche.

Autor: Sebastian L. (boaschti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In grad mit nem Trojaner am kämpfen, kann die WinAVR Version grad nich 
mehr überprüfen, wenn ich mich richtig erinnere war es aber genau das, 
nur durch Kommas statt Punkte getrennt.

Ich ahbe keine Ahnung wieso, ich habe nichts verändert, aber es läuft 
jetzt. An beiden Pins liegen 2,5V an, die Spannung lässt sich auch 
verändern wenn ich etwas anderes für den Compare-Wert nehme.
Ehrlich gesagt gehts mir so langsam auf die Nerven dass ich irgendwelche 
Probleme habe die dann von alleine verschwinden. Klar is das besser als 
wenn man keine Lösung fidnet, aber trotzdem wüsste ich gerne warum es 
nich funktioniert hat >.<

Ertsmal vielen Dank fürs Antworten, werd jetzt weiter damit rumspielen, 
bis zur nächsten Frage ;-)

Basti

Autor: Sebastian L. (boaschti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, da kommen auch schon die nächsten Fragen. Bin leider Anfänger sowohl 
in C-Programmierung als auch bzgl. µC, deshalb bin ich bei meinem 
Projekt etwas auf mithilfe angewiesen. Habe zwar schon das 
AVR-GCC-Tutorial durchstöbert, aber noch ist mir die Realisierung zu 
meiner "Aufgabe" nicht über den Weg gelaufen und momentan habe ich weder 
Zeit noch Nerven von Grund auf das gesamte Tutorial durchzuarbeiten, das 
kommt bei Gelegenheit mal. Deshalb wäre ich euch sehr dankbar wenn ihr 
mir in Grundzügen beschreibt wie ich das am besten umsetzten sollte, 
oder mir sagt wo ich die dafür nötigen Informationen finden kann.


Wie oben beschrieben geht es um folgendes:

Der µC soll in der Lage sein eine konkrete Spannung zwischen 0 und 5V
auszugeben. Also soll man zB. am PC sagen können "Lass ma 3V
rüberwachsen", per Nullmodemkabel wird der für den µC passende Befehl an
diesen weitergegeben und dieser setzt per PWM einen Pin auf eben die
gewünschten 3V.

Das ganze 2 mal, und zwar sollten auch verschiedene Spannungen möglich
sein ("Pin X bitte 3V, Pin Y bitte 2,5V").

Diese 0-5V sollen dann per weiterer Gerätschaften die sich über die 
Spannungen Regeln lassen auf 0-300V bzw. 0-2A umgewandelt werden.


Mein PWM-Progrämmchen (siehe oben) läuft soweit, ich kann über eine 
Veränderung des Compare-Wertes die Spannung auch perfekt verändern.

Jetzt habe ich mir mal folgendes ausgerechnet:

Ich setze den Top-Wert auf FFFF, also Dezimal auf 65535.
Die vom µC ausgegebene Spannung wird ja versechzigfacht, diese 
Endspannung sollte in 25V-Schritten veränderbar sein. Das wiederum 
heisst die vom µC ausgegebene Spannung sollte in 25/60, d.h in 5/12 
Volt-Schritten veränderbar sein.
Das wiederum würde bedeuten ich müsste den Compare-Wert in Schritten von 
5461 verändern.


Wie lässt sich das realisieren? Also dass eine Eingabe über die serielle 
Schnittstelle erfolgt, und diese dann vom µC verarbeitet werden kann, so 
dass die beiden Compare-Werte den passenden Wert annehmen?

Das wäre jetzt nur die Umsetzung der Aufgabenstellung die ich mir 
überlege, wenn es auch anders möglich ist eine Ausgangsspannung 
entsprechend einem Befehl vom PC aus zu steuern bin ich auch dafür 
offen.


Wie gesagt, mir fehlt einfach die Zeit alles selbst zu entwickeln, es 
ist auch nicht gerade leicht das zu tun wenn man sowohl in 
C-Programmierung als auch in Sachen µC Angänger ist :S

Insofern hoffe ich einfach dass sich jemand die Zeit nimmt mir dabei ein 
wenig unter die Arme zu greifen, das wäre wirklich sehr freundlich.
Achja: Ich weiss nicht, aber nahc einer wahnsinnig ausgefallenen 
Aufgabenstellung klingt das doch eigentlich nicht? Falls es schon 
irgendwo eine Anleitung oder ein Thema zum umsetzten von "PC lässt den 
µC bestimmte Spannungen asugeben" gibt wäre ich natürlich froh darüber 
mir das ansehen zu können.

Ansonste schon einmal vielen Dank im Voraus, ich weiss das es meist 
nicht sonderlich interessant ist einem Anfänger zu helfen, aber ich wäre 
wirklich froh wenn das trotzdem jemand tun könnte ^^


Basti

Autor: Sebastian L. (boaschti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bump... wie gesagt, ich bin gewissermassen auf eure Hilfe angewiesen, 
wäre schön wenn sich jemand findet der mir ein paar Hinweise gibt =)

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sebastian,

du baust am besten erst mal in die init Funktion das folgende mit ein:
UCSRB |= (1<<TXEN);

UCSRC |=
(1<<URSEL)|     /*muss gesetzt sein*/
(0<<UMSEL)|     /*Asynchrone Schnittstelle*/
(0<<UPM1)|      /*no parity*/
(0<<UPM0)|      /*no parity*/
(0<<USBS)|      /*one stop bit only*/
(1<<UCSZ1)|     /*8-bit mode*/
(1<<UCSZ0)|     /*8-bit mode*/
(0<<UCPOL);     /*Write this to zero in asynchronous mode*/

UBRRH = 0;
UBRRL = 71;

UBRRL ist für die Baudrate zuständig, die Einstellung sollte mit deinem 
Quarz 9600 Baud ergeben. Die Schnittstelle ist dann konfiguriert und 
kann verwendet werden.

Dann machst du am besten so weiter, wie es im Tutorial steht:
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Dann musst du dir ein Übertragungsprotokoll ausdenken, das die 
übertragenen Daten im Atmega rekonstruieren kann und auf PC Seite 
überhaupt erst mal erzeugt. Das ist im einfachsten Fall eine 
Konsolenanwendung, die nur auf dem Atmega läuft und auf PC Seite ein 
Terminal hat. Dort könnte man die Daten manuell eingeben. Wenn 
irgendwelche Funktionen komplizierterer Art als Spannung ausgegeben 
weden sollen, ist auf PC Seite wohl auch noch ein Stück Software 
notwendig, sei es nur ein VB-Makro, dass irgendwelche Daten von Excel 
zum Mikrocontroller schickt. Du hast irgendwas von einem Webserver 
gesagt, der das steuern soll?

>Habe nun an Pin 18 und 19 je einen 100k Ohm Widerstand und nen
>22nF Kondensator angelötet, wie hier halt:

Ich habe 47k und 22µF eingebaut...
Sonst wäre die Glättung etwas schlecht bei 168Hz.

Grüße,

Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.