Hallo,
Ich möchte über die serielle Schnittstelle auf meiner Platine die
Pulsbreite meiner PWM ädern. Ich benutze einen Atmega8 mit
entsprechendem max232 pegelwandler.
Die PWM habe ich meinem Microcontroller beigebracht und kann über die
entsprechende Variable im Programm die Breite meines Pulses ändern.
Da ich den Puls on the flight ändern möchte, ohne den Controller jedes
mal neu zu programmieren, würde ich gerne über die serielle
Schnittstelle an die Variable herankommen. Geht das?
Muss ich sie dafür in irgendeinen Speicher schreiben? Oder ist es
einfacher bei jedem Signal die Variable zu verändern (größer, kleiner)
anstatt die neue Variable direkt zu übertragen?
Mein erster Ansatz war, dass ich die entsprechenden Pins am Controller
auf Eingang setze...
Wäre schön, wenn mir jemand da Tipps/Anregungen geben könnte.
Ich muss natürlich noch sagen, dass ich im ganzen
microcontroller-programmieren noch recht unerfahren bin. grundsätzlich
sind C kenntnisse vorhanden.
Danke im Voraus :)
Tach Leon,
grundsätzlich ist deine Idee den neunen Sollwert vom USART Modul an die
entsprechende Stelle im Speicher zu schreiben richtig. Aber du denkst zu
kompliziert. Du hast deinen code nicht gepostet, von daher kann ich nur
sehr abstrackt reden.
Damit das Timermodul ein PWM Signal erzeugen kann benötigt es einen
Sollwert in OCRxx. Außerdem hast du ein USART Modul, dass in der Lage
ist Daten von einem PC zu empfangen. Im Prinzip musst du nun nur noch
die vom PC gesendeten bytes in das entsprechende OCR kopieren. Die mega
AVRs haben noch kein DMA, sodass für jedes eintreffende byte die CPU
aktiv werden muss. Am einfachsten geht das, indem du den RX interrupt
auf dem USART aktivierst und in der ISR einfach ein OCRxx = UDR machst.
Komplizierter wird es natürlich, wenn du ein 16bit timer verwendest.
Thor
Lies Dir erstmal das hier durch:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART
Du brauchst auch eine passene Kalibrierung Deines internen Taktes bzw.
besser einen passenden Baudratenquarz als externen Taktgeber.
Vielleicht wäre auch USB was für Dich ?
Dein Programm braucht dann wohl noch eine Empfangsroutine für die
serielle Schnittstelle. Je nachdem, welches Zeichen da ankommt (also
welches Zeichen Du in Deinem Terminal-Programm tippst), sollte die
entsprechend reagieren.
Ganz grob:
Wenn z.B. das Zeichen '+' kommt, kannst Du Deine Variable um 1 erhöhen,
wenn ein '-' kommt, verringern, und wenn eine Ziffer kommt, kannst Du
die Dir merken, mit 10 multiplizieren und die weitere addieren, wenn
eine weitere kommt, und die Zahl als Wert setzen, wenn ein '\n'
(Enter-Taste) kommt.
Dafür musst Du die serielle Schnittstelle entsprechend dem Artikel
initialisieren und eine ISR für "Zeichen empfangen" schreiben.
Das könnte ganz grob in der einfachsten implementierung so aussehen:
Leon schrieb:> Wäre schön, wenn mir jemand da Tipps/Anregungen geben könnte.
Das ist jetzt ein bischen schwierig, denn eigentlich ist das ziemlich
simpel, wenn man ein bischen Übung in der Programmierung hat. Speziell
einen einzelnen 8-Bit Wert per UART zu übertragen ist nicht wirklich
Raketentechnik. Bei mehr Bytes bzw. wenn es sich jetzt um einen 16-Bit
Wert handelt, wird das schon ein wenig schwieriger.
Hast du dir denn schon mal die Tutorien hier auf der Web-Site angesehen?
AVR-TutorialAVR-GCC-Tutorial> Mein erster Ansatz war, dass ich die entsprechenden Pins> am Controller auf Eingang setze...
Wenn du bei UART bleiben willst, dann ist das schon ein wenig
aufwändiger. Und nein, genau diesen Schritt brauchst du dabei nicht. Das
macht sich die UART im Mega8 schon selber, wenn du sie einschaltest. Man
kann jetzt den UART Empfang per Interrupt machen, aber als Anfänger
würde ich dir erst mal ein Polling (also regelmässiges Nachsehen ob was
da ist) empfehlen. Ist leichter zu verstehen, wie da die Abläufe sind.
Die Tutorien sind da deine Freunde.
Das größte Problem beim UART ist allerdings in vielen Fällen die
Inbetriebnahme. Denn wann da irgendwo etwas nicht stimmt, dann geht erst
mal gar nichts. Daher nimmt man eine UART meistens auch erst mal so in
Betrieb, dass man vom µC aus an den PC senden lässt und dort mit einem
Terminalprogramm kontrolliert, ob alles in Ordnung ist.
Eine andere Idee wäre es, zb mit einem Poti und dem AD-Wandler die
Vorgabe für die PWM zu erhalten. Auch dazu findet sich in den Tutorien
was.
Als erstes musst Du den UART zum Laufen bringen. Dazu würde ich erstmal
versuchen, ein Zeichen vom Mikrocontroller an den PC zu senden und im
Terminal zu sehen. Wenn das geht, machst Du die andere Richtung, ein
Zeichen vom UART im Mikrocontroller empfangen.
Du schreibst Dir also eine Funktion:
1
intuart_getchar(void)
Die liefert das empfangene Zeichen vom UART zurück, wenn eins kam oder
-1, wenn keins kam. Es gibt auch fertige UART-Bibliotheken, die Du
nutzen kannst, z.B. von Peter Fleury. Der Lerneffekt ist aber größer,
wenn man es selber schreibt. Ungepuffert sind das nur wenige Zeilen.
So, jetzt kannst Du also einzelne Zeichen empfangen. Dann kannst Du
Deiner Phantasie freien Lauf lassen und Dir ein Übertragungsprotokoll
überlegen. Für den Anfang ist es das einfachste, die Variable bei einem
bestimmten Zeichen zu erhöhen und mit einem anderen zu erniedrigen:
1
while(1){
2
intzeichen=uart_getchar();
3
if(zeichen=='a'&&variable<255){
4
variable++;
5
}elseif(zeichen=='b'&&variable>0){
6
variable--;
7
}
8
]
Wenn das funktioniert kannst Du etwas weiter gehen und die Zahl dezimal
als ASCII-Zeichen übertragen (so wie ein Mensch sie in die Tastatur
eingeben würde) und mit einem <Enter>, also dem Zeichen '\r',
terminieren.
Das Programm muss dann in einer Schleife die UART-Zeichen empfangen,
hintereinenader in einen Pufferspeicher legen bis ein '\r' kommt, den
String in eine Zahl umwandeln und der Variable zuweisen.
Hallo,
danke für die Hilfe. hat mir alles sehr geholfen:) habs anfangs noch
selber versucht, hab dann aber die uart_getchar() von peter fleury
verwendet. Leider klappt diese nicht mit einem Interupt, weswegen ich
nun die ganze zeit eine abfrage senden muss. Aber sie funktioniert.
Nun hab ich das problem, dass ich mit dem uart_getchar() anscheinend nur
einstellige character senden/empfangen kann. da ich meine PWM-Variable
aber von 0-100 durchstimmen will, hilft mir das leider nur bedingt.
hat da jemand eine Lösung parat?