Hallo liebe mikrocontroller.net Community, ich bin noch Neuling im Bereich uC Programmierung deshalb benötige ich eure Hilfe :). Natürlich habe ich schon die Tutorials hier auf der Seite komplett gelesen und mich auch schon in dem uC Handbuch eingelesen. Zum Problem: Ich benutze einen ATMega 644 (20Mhz) und habe an meinem PB1 ein PWM-Signal (1Khz, Tastverhältnis 20-80%) anliegen. Jetzt muss ich dieses Signal im uC softwaretechnisch erfassen und das Tastverhältnis berechnen. Das Tastverhältnis soll danach der Soll-Wert für ein PID-Regler sein der dann später ein Drehstrommotor über ein PWM-Modul ansteuert. Die Platine ist komplett fertig und funktioniert auch, ich benötige eher programmiertechnische Hilfe ;).. meine größte Sorge ist wie ich das Signal am besten auswerte ?? meine erste Idee war die ansteigende Flanke des Signals zu erfassen und meinen Timer0 (Timer1 verwende ich dann für meine PWM) zu starten. Wenn die Flanke fällt speichere ich in einer Variablen "an" die Zählerwerte und lass weiter laufen bis die nächste steigende Flanke kommt und speicher den Timer0 wert (-> komplette Periode)"periode" und Teile den ersten Wert "an" / "periode". Das ganze Funktioniert nur leider nicht. Mein Code stelle ich dazu ->unten. Wenn ihr bessere Lösungsverschläge habt bin ich dafür offen z.B abtasten des Signals etc etc ... Schon im vorraus vielen Danke für eure Hilfe gee
> if(PINB & 0x02){ // Wenn Signal (1) an PB1
Du willst eine Flanke erkennen und nicht den Code ausführen, wenn PB2
auf 1 ist.
Flanke!
Dazu musst du erkennen, wann PB2 den Pegel WECHSELT.
1 | OldPegel = PINB & 0x02; |
2 | |
3 | |
4 | while( 1 ) { |
5 | |
6 | ...
|
7 | |
8 | Pegel = PINB & 0x02; // welchen Zustand hat der Pin jetzt |
9 | |
10 | |
11 | if( Pegel != OldPegel ) { // hat sich was verändert? |
12 | // wenn ja, dann war da eine Flanke an diesem Pin
|
13 | |
14 | if( Pegel ) { // was war das für eine Flanke ? |
15 | // nachdem der Pin jetzt auf 1 ist, muss er
|
16 | // vorher auf 0 gewesen sein, und das ganze
|
17 | // war eine Flanke 0-> 1
|
18 | ....
|
19 | }
|
20 | else { // No, der Pin ist jetzt 0. |
21 | // also muss das eine Flanke 1 -> 0 gewesen sein
|
22 | ...
|
23 | }
|
24 | |
25 | OldPegel = Pegel; // jetzigen Zustand merken, damit im nächsten |
26 | // Durchgang wieder eine Veränderung festgestellt
|
27 | // werden kann
|
28 | }
|
29 | }
|
Danke für deinen Hinweis ich werde das gleich morgen testen :) gee
Ich habe deinen Hinweis ausprobiert und die Flanken erkenne ich, vielen Danke dafür noch mal. Das weiter Problem das ich gerade habe ist, dass ich sobald eine "High" Flanke kommt ich meinen Timer0 hochzählen lassen möchte. Wenn die Flanke abfällt speicher ich meinen Zählerwert des Timers in einer Variablen, lass aber alles weiter laufen bis die nächste "High"Flanke kommt um einen Zählerwert für die komplette Periode zu haben. Das Problem ist nur das mein Timer0 nur bis 255 Zählen kann und deshalb mehrmals einen Overflow verursacht, weshalb ich falsche Werte erhalte. Habt ihr da einen Tipp oder eine bessere Möglichkeit ? Freue mich weiterhin sehr über eure Hilfe Gruß gee
gee schrieb: > Das Problem ist nur das mein Timer0 nur bis 255 Zählen kann und > deshalb mehrmals einen Overflow verursacht, weshalb ich falsche Werte > erhalte. Du könntest mit dem Overflow einen Interrupt auslösen und per Software die Anzahl der Überläufe zählen, so dass du mit Softwarezähler und Timer insgesamt 16 Bit zur Verfügung hast.
gee schrieb: > haben. Das Problem ist nur das mein Timer0 nur bis 255 Zählen kann und > deshalb mehrmals einen Overflow verursacht, weshalb ich falsche Werte > erhalte. Habt ihr da einen Tipp oder eine bessere Möglichkeit ? Warum wählst du nicht einfach einen höheren Timer? Entweder per definiertem Top Wert oder z.b. 10 Bit statt aktuell 8. Gruß
Hallo, Du kannst Dir eine weitere Hilfsvariable definieren, die bei jedem Timerüberlauf (Interrupt verwenden) um eins hochgezählt wird. Diese zusammen mit dem Timer0-Wert gibt Dir dann die benötigten Zeiten.
Danke für eure Tipps ich versuche es. Eine Frage ich habe gerade als Test einfach mal meinen 16bit Timer1 genommen und habe nur mal versucht die komplette Periode zu messen. Auch hier kommt immer was anderes raus !? .. mhm.. die 20Mhz werden wohl auch hier einen OVF verursachen.. egal ob ich jetzt T0 oder T1 verwende die von euch oben genannte Systematik mit dem OVF-Interrupt ist ja die gleiche ich teste das jetzt. Danke noch mal :) gee
gee schrieb: > ... mhm.. die 20Mhz werden wohl auch hier einen OVF verursachen.. Eigentlich nicht. Bei 20 MHz Takt und 1 ms Signalperiode sollte der Zähler bis 20000 kommen. Ziehst du den Startwert ab bzw. setzt bei der ersten Flanke den Zähler auf 0?
Hi, ich setze den Startwert mit TCNT0= 0x00 ja eigentlich zurück oder ? Habe noch mal im Dateianhang meine Quelldatei. Habe versucht alles so genau wie möglich zu Kommentieren. Vielen Dank das ihr mir so helft ich versuche so viel wie möglich alleine zu programmieren, aber ich bin gerade an einer Stelle wo ich ohne Hilfe nicht weiterkomme -.- ..bzw. keine Ideen mehr habe -> zu wenig Erfahrung. gee
Bei der Berechnung der Gesamtzeit ist deine Frage im Kommentar berechtigt. Entweder Multiplikation mit 2^8=256 oder 8-mal nach links schieben. Gesamt = i+TCNT0; // Gesamtzeit // wenn der Timer0 z.B 68 OVF hatte // muss ich dann nicht die Anzahl der OVF ´ // mit 255 multiplizieren und das ganze // mit dem geraden Zählerwert von T0 addieren // also (i*255)+TCNT0 ??????????? 1. Die Gesamtzahl muß eine 16-Bit Variable sein (char hat nur 8) 2. Gesamt = (i*255)+TCNT0 oder Gesamt = i<<8 + TCNT0 wäre richtig.
Hallo uC-Community, mein Programm für die PWM-Abtastung lauft soweit ganz gut,vielen Dank noch mal an alle Helfer ;), nur leider ist jetzt ein weiteres komplexes Problem hinzugekommen. Und zwar habe ich natürlich seit der Entwicklung der Software weitere Softwareteile hinzugefügt. Jetzt habe ich folgendes Problem: Ich habe meine PWM-Abtastung(die PWM 1kHz aus einem Steuergerät) durch den Timer0 realisiert. Dadurch habe ich das Verhaeltnis errechnet dieses wiederum für ein normales PWM-Signal für einen BL-Motor verwendet wird. Nun bin ich an einer fortgeschrittenen Stelle, in der ich mehrere Programmteile zusammengefügt habe. Durch das Gesamtprogramm verändert sich nach jedem Zyklus die Zeit meines Programmdurchlaufs. Dadurch bekomme ich obwohl ich die PWM am Steuergerät nicht ändere (sagen wir 5% DutyCycle) jeden Zyklus anderes PWM-Verhältnis (meist über 100% -.-) dadurch wird auch mein Motor extrem belastet, schwingt und quietscht ... So an dieser Stelle brauche ich eure Hilfe habe keinen besonderen Lösungsansatz. Ideen wären: 2 uC verwenden, den einen für die Berechnung des PWM-Signal aus dem Steuergerät, den anderen für die Ausführung des restlichen Programms. Sonst fällt mir nichts mehr ein, danke für eure Hilfe.. dennis
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.