PWM Mit Atmel Microcontroller
-
Hallo
Ich möchte in C (nicht ansi C) einen Atmel Controller Programmieren
Nun die frage:
Wie kann ich ein PWM signal an port PB0 des Attiny11 ausgeben?
liebe grüsse
Claudio
-
Was hat das jetzt mit dem standard C++ zu tun ?
Welches OS welcher Compiler welche Libs ?
-
Es gibt ja keine "C" kategorie fürMikorocontroller
Ich benutze WINAVR um den Code zu einem hex file zu compilieren und
danach mit dem AVR Studio und dem STK500 das hex in den Controller zu flashen
-
Wo ist dein Problem?
- Wie man es in C realisiert?
- Wie PWM funktioniert?Ganz grob:
- Timer0 anwerfen (siehe Doku ab Seite 41)
- in der Interruptfunktion ggf. PORTB.0 toggeln, etwa so:volatile uint8_t pwm_high, pwm_low; void timer(void) interrupt(...) { // genau syntax vergessen static uint8_t pwm_status = 0, pwm_count = 0; if(pwm_status ? pwm_high : pwm_low > pwm_count) { togglebit(PORTB, 0); pwm_status = 1 - pwm_status; pwm_count = 0; } } void main(void) { // verteilung 3 takte zu 5 takte, ca 3.1V an pb.0 pwm_high = 5; pwm_low = 3; /* interrupts an */ while(1); }
-
if heißen
if(pwm_count > pwm_status ? pwm_high : pwm_low) {
-
kann ich auch mit 0 - 255 arbeiten? wobei 255 das maximum ist
und 0 das minimum?danke
-
Klar theoretisch geht das. Das senkt eben die Frequenz des PWM-Signals, dafür steigt die Genauigkeit. Wenn du den Timer ohne Prescaler laufen lässt kommst du bei 255/255 auf eine Frequenz von (wenn ich grade richtig überschlagen hab) ~2,5kHz - was für eine Ausgangsfrequenz du benötigst hängt natürlich von der Schaltung ab, die mit dem PWM-Signal beliefert wird. Das ganze lässt sich über div. Verfahren auch noch glätten.
-
und es muss heißen:
if(++pwm_count > pwm_status ? pwm_high : pwm_low) {
Ich glaub nun hab ichs -.-
-
also es geht um die helligkeit einer LED
Ich möchte eben einen Würfel bauen der bei jedem würfeln eine neue Farbe hat.
Die farben sollen mit einer RGB LED erzeugt werden deren Farben von einem Attiny gesteuert werden sollen.
Kann ich auch einen Zuffalsgenerator einbauen?
Ich kenne mich eben noch so gut wie überhaupt nicht mit dem C Für AVRs aus
danke für die hilfe
-
Klar geht das, rand() gibts in der avrlib, nur die Initalisierung wird spannend. Ich denke der Würfel wird durch einen Schalter gestartet. Dann nimmst du einfach zur Initalisierung beim ersten Tastendruck den Wert im Timerregister (TCNT0).
-
hmmm köntet ihr mir dabei helfen?
Ich möchte gerne mit diesem experiment das mit den AVRs lernen aber den Code selbst hinzubekomment das hab ich selbst nicht geschafft auch mit der google hilfe nicht.
Also bitte nicht böse sein aber könntet ihr mir mit dem gesamten code helfen?
Ich mache so gut mit wie es geht
EDIT:
Ja durch einen TastendruckGibt es 3 Timerregister? weil ich habe ja auch drei farben.
-
Dieser Code funktioniert bei mir irgendwie nicht.
#include <avr/io.h> void init(void) { DDRB = 0xff; // PortB als Ausgang deklarieren PORTB = 0x00; // Ports auf LOW schalten } volatile uint8_t pwm_high, pwm_low; void timer(void) interrupt(...) { // genau syntax vergessen static uint8_t pwm_status = 0, pwm_count = 0; if(++pwm_count > pwm_status ? pwm_high : pwm_low) { togglebit(PORTB, 0); pwm_status = 1 - pwm_status; pwm_count = 0; } } void main(void) { // verteilung 3 takte zu 5 takte, ca 3.1V an pb.0 pwm_high = 5; pwm_low = 3; /* interrupts an */ while(1); }
-
http://www.mikrocontroller.net/articles/AVR-Tutorial
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial+ Dokumentations zu DEINEM Controller (findest du auf www.atmel.de)
Beim tiny gibts nur ein Timer, der reicht aber völlig! Wenn du es einfach haben willst kannst du einen mega nehmen, da kann der Hardwaretimer die PWM von ganz alleine machen, beim tiny musst du es per Software lösen.
Ich gehe davon aus, du hast 3 Ausgänge (R,G,B) und ein Eingang (Taster)?
Dann mach zuerst ein Würfel mit 8 Möglichkeiten, also 001, 010, 011... ohne PWM.
-
Natürlich geht der Code nicht, ist ja auch unvollständig.
-
Gute idee
Werd ich machen
wens dan klappt werd ich einfach n Mega nehmen
kannst du mir beim code noch helfen so das ich wie eine grundlage habe?
Ich weiss aus erfahrung das ich aus beispielen vielmehr lerne als aus dem gelesenen
-
#include <avr/io.h> #include <avr/interrupt.h> #include <stdint.h> #include <stdlib.h> // legt fest ob wir den zufallsgenerator initalisiert haben uint8_t srand_done = 0; ISR(INT0_vect) { if(!srand_done) { srand(TCNT0); srand_done = 1; } /* Taste gedrückt, hier musst DU zufällige Werte in PB.2 bis PB.5 schreiben */ /* Hier Entprellcode einfügen */ } ISR(TIMER0_OVF_vect) { /* hier brauchen wir vorerst nichts tun, erst später bei der pwm */ } void main(void) { DDRB = /* binär: 00111000 , taste auf INT0, rgb auf PB.2 bis PB.5 */ PORTB = 0; /* hier musst DU den Timer initalisieren */ while(1); }
mehr gibts net!
pb.1 = taster
pb.2 = r
pb.3 = b
pb.4 = g
-
vielen dank
damit werd ich sicher mal einiges anstellen können
-
Was soll an diesem Code falsch sein?
#include <avr/io.h> #include <avr/interrupt.h> #include <stdint.h> #include <stdlib.h> // legt fest ob wir den zufallsgenerator initalisiert haben uint8_t srand_done = 0; ISR(INT0_vect) { if(!srand_done) { srand(TCNT0); srand_done = 1; } /* Taste gedrückt, hier musst DU zufällige Werte in PB.2 bis PB.5 schreiben */ /* Hier Entprellcode einfügen */ } ISR(TIMER0_OVF_vect) { /* hier brauchen wir vorerst nichts tun, erst später bei der pwm */ } void main(void) { DDRB = (0 << DDB0) | (0 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4); /* binär: 00111000 , taste auf INT0, rgb auf PB.2 bis PB.5 */ PORTB=2; /* hier musst DU den Timer initalisieren */ while(1); }
EDIT:
Weil so LED 2,3,4 Leuchtet (auf dem STK500)
Hmmm irgendwie weiss ich nicht wie man richtig etwas ausgibt
-
2 ist binär 10, und dieser Pin ist der Eingang für den Interrupt, da musst du nichts dran fummeln. Die LEDs leuchten weil die AFAIR low-aktiv sind (also bei 0 leuchten).
Lies die Tutorials die ich gepostet hab und du wirst lernen...