Hallo Community, da mir Google keine Antwort auf meine Frage liefern konnte, stelle ich sie mal hier. Es geht darum, dass ich mit einem AtMega8 ein Tonsignal (ca. 1kHz, Rechtecksignal) erzeugen möchte, das auf einem Lautsprecher ausgegeben werden soll. Dies macht man ja im Normalfall mit einem der Timer im PWM-Modus. Es ist aber so, dass ich keinen Timer mehr frei habe, weshalb ich eine Möglichkeit suche, das Signal anderweitig zu erzeugen. Kann man hierzu einfach einen normalen I/O Pin schnell hintereinander an- und ausschalten, um das Signal zu erzeugen? Und wenn ja, was nehme ich als Zeitbasis? Mfg AVR-Toaster
Du wirst einen Timer mit Compareregister brauchen. Im Wiki gibt es einen Artikel über Softwarepwm. Die dort optimierteste Methode wird wahrscheinlich nötig sein. Es wird jedoch nicht einfach werden. Versuch lieber einen Timer freizubekommen, das ist sicher möglich. Liste mal für was die Timer benötigt werden. Welche Sprache programmierst du?
AVR-Toaster schrieb im Beitrag #2407792: > Kann man hierzu einfach einen normalen I/O Pin schnell hintereinander > an- und ausschalten, um das Signal zu erzeugen? Und wenn ja, was nehme > ich als Zeitbasis? Du nimmst einfach einen deiner schon benutzten Timer, der einen Interrupt auslöst, zählst in der ISR eine Variable rauf und toggelst einen Portpin, wenn diese den passenden Wert erreicht hat. Wenn das dann 900 oder 1100 Hz sind, stört das sicherlich auch keinen grossen Geist. mfg.
> Kann man hierzu einfach einen normalen I/O Pin schnell > hintereinander an- und ausschalten Nstürlich kann man while(1) { PORTB|=1; _delay_us(500); PORTB&=~1; _delay_us(500); } aber da dein Prozessor wohl dazwischen noch was zu tun hat, wirst du dir mehr Gedanken um parallele Abläufe machen müssen.
Vergiss mein kompliziert, bei konstantem Signal wird es leicht werden.
Der Code ist in C geschrieben. Ich nutze den 16-bit Timer1 im CTC-Modus, der Überlauf findet im 200Hz Takt statt. Timer0 (Überlauf ca. alle 10ms) ist für das Auslesen und Entprellen der Taster verantwortlich und Timer2 generiert aktuell das PWM-Signal für die Soundausgabe. Das funktioniert soweit auch alles. Nun möchte ich aber noch die Hintergrundbeleuchtung eines LCDs per PWM regeln, wozu ich gerne Timer2 nutzen würde.
Timer1: 200Hz Timer0: 100Hz lässt sich in einen Timer schreiben:
1 | volatile uint8_t counter = 1; |
2 | |
3 | ISR(TIMER1_COMPA_vect) |
4 | {
|
5 | if(counter-- == 0) |
6 | {
|
7 | counter = 1; |
8 | //wird im 100Hz Takt aufgerufen
|
9 | //key_update();
|
10 | }
|
11 | }
|
Man kann auch mehrere Funktionalitäten eines Timers gleichzeitig nutzen: Timer2 kann das Soundsignal erzeugen und gleichzeitig über einen (anderen) PWM-Kanal die Leds dimmen. Die Frequenz ist dabei auf 1Khz festgelegt. Es wäre auch möglich mit einem Timer alles zu erledigen. Die Frequenz wäre der gemeinsame Nenner (1kHz). Darin verschachtelt ein 5er Teiler und ein 2er Teiler.
In einem anderen Thread nannte jemand die Seite www.romanblack.com Dort sind ein paar interessante Elektronik- und µC-Projekte. Unter anderem auch eine Umwandlung von WAV-Dateien in das sog. 1-Bit Format und wie man das 1-Bit-Format auf einer einfachen Hardware abspielt: http://www.romanblack.com/picsound.htm
AVR-Toaster schrieb im Beitrag #2407816: > Nun möchte ich aber noch die Hintergrundbeleuchtung eines LCDs per PWM > regeln, wozu ich gerne Timer2 nutzen würde. Dafür braucht man keinen Timer. volatile unsigned char nPwmCt = 0; void Backlight(unsigned char nPwm) { if (nPwm <= nPwmCt++) PortAus(); else PortAn(); } Das rufst du regelmässig im Hauptprogramm auf. Die Frequenz ist der LED-Beleuchtung egal. Kannst aber auch noch einen Prescaler davor setzen. Dann schaltet der Port nicht so oft. volatile unsigned char nPwmCt = 0; volatile unsigned char nPrescaler = 0; void Backlight(unsigned char nPwm) { if(!nPrescaler++) { if (nPwm <= nPwmCt++) PortAus(); else PortAn(); } } mfg.
Thomas Eckmann schrieb: > Das rufst du regelmässig im Hauptprogramm auf. Das kann ins Auge gehen, wenn das Hauptprogramm mal länger arbeiten muss.
Samuel K. schrieb: > Das kann ins Auge gehen, wenn das Hauptprogramm mal länger arbeiten > muss. Paranoia. Solange die Beleuchtung dabei nicht sichtbar flackert, ist das völlig egal. mfg.
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.