PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM mit AVR Mega32 und Taster



DarkFire
21.11.2005, 06:52
Hallo,
ich wollte mit meinem Mega32 eine LED mit der Pulsweitenmodulation dimmen. Dazu habe ich folgenden Code verwendet:


int main(void)
{
uint16_t hell = 500;

PORTD = 0x00; //PORTD alle Pins low
DDRD = 0x30; //PORTD Pin 4 und 5 als Ausgang

TCCR1A = (1<<WGM10) | (1<<WGM11) |(1<<COM1A1); //10 Bit Phase Correct PWM, max Wert 0x03FF
TCCR1B = (1<<CS10) | (1<<CS11); //Takt = CPU-Takt/8

OCR1A = hell; //Vergleichswert
}


Dies funktionierte auch einwandfrei.
Nur will ich den Helligkeitswert per Taster verändern. Dazu habe ich den Code um folgendes erweitert:


while(1){
DDRB = 0x00; //Port B alle Pins Eingang

if ((PINB & (0x10))==0) //Wenn Taster 1 gedrück (Pin 2 auf low)
{
if (hell < 0x03F6)
{
hell = hell +10; //Erhöhe Helligkeit um 10
_delay_ms(1); //Verzögerung
}
}
if ((PINB & (0x20))==0) //Wenn Taster 2 gedrück (Pin 3 auf low)
{
if (hell > 0x0009)
{
hell= hell -10; //Verringere Helligkeit um 10
_delay_ms(1); //Verzögerung
}
}

//PWM-Code

}

Das Problem ist nur, dass ich zwar den Wert ändern kann, jedoch die PWM an sich nicht mehr funktioniert.

Mache ich irgendetwas falsch?

Chris

kater
21.11.2005, 16:22
Etwas funktioniert nicht wie gewollt?
Du fragst ob du etwas falsch machst?

Stolz kann ich dir antworten, JA, du machst etwas falsch. ;)

Tschoe Leute, es war fuer den Anfang eine gute Zeit hier.

DarkFire
21.11.2005, 16:48
Dann wäre ich noch dankbar, wenn mich jemand aufklären könnte was ich falsch mache.
Mit kommt vor es ist ein grundlegender Fehler, aber da ich mich in der µProzessor Programmierung noch nicht so gut auskenne, würde ich euch bitten mit meinem Problem zu helfen.
Muss ich das in meinem Fall mit Interrupts programmieren oder würde das nichts ändern?

Wurstgote
21.11.2005, 19:20
Mahlzeit!

Du könntest mal folgendes probieren:
- erstmal den PWM-Code aus der while-Schleife rausholen,
- das DDRB=hell auch vor die while-Schleife stellen,
- nach jeder Änderung des hell-Wertes OCR1A ändern,
- offensichtlich soll ein Tastendruck ja den entsprechenden PortB-Pin auf logisch null ziehen; dazu müssen aber die internen PullUp-Widerstände von PortB angeschaltet sein. Vor die while-Schleife also noch ein PORTB=0xFF packen.

Ich bin nun kein Experte, aber evtl. hilft Dir das ja weiter.

Grüße
Jens

DarkFire
21.11.2005, 20:16
Ich habe den Code jetzt einmal aus der while-Schleife herausgeholt, nur hat sich nichts geändert, bzw. die PWM funktioniert immer noch nicht, was ja meiner Meinung nach auch logisch ist, da das Programm ja immer in der while-Schleife bleibt und so die PWM bzw. der Zähler nie gestartet bzw. der Vergleichswert nie geändert wird.
Auch das mit dem aktualisieren des OCR1A-Wertes hat nichts gebracht.
Das mit den internen Pull-Up Widerständen ist überflüssig, da ich bei meinen Taster externe 10k Widerstände habe.

Chris

Wurstgote
21.11.2005, 20:42
Hmmm...

Hast Du denn irgendwo in Deinem Code die Interrupts eingeschaltet? Wenn ich das richtig sehe, mußt Du noch den Timer-Interrupt im TIMSK-Register einschalten, sowie Interrupts global mit "sei();" ermöglichen.

Grüße
Jens

SprinterSB
22.11.2005, 08:49
Nö, für PWM braucht's keinen Interrupt.
Wie sieht der Code denn jatzt aus?

Wurstgote
22.11.2005, 13:08
Mahlzeit!


Nö, für PWM braucht's keinen Interrupt.
Was soll ich sagen - wo Du Recht hast, hast Du Recht :-b

Grüße
Jens

DarkFire
22.11.2005, 19:09
Der Code sieht jetzt folgendermaßen aus:


int main(void){

uint16_t hell = 500;

PORTD = 0x00; //PORTD alle Pins low
DDRD = 0x30; //PORTD Pin 4 und 5 als Ausgang

TCCR1A = (1<<WGM10) | (1<<WGM11) |(1<<COM1A1); //10 Bit Phase Correct PWM, max Wert 0x03FF
TCCR1B = (1<<CS10) | (1<<CS11); //Takt = CPU-Takt/8

OCR1A = hell; //Vergleichswert

while(1){
DDRB = 0x00; //Port B alle Pins Eingang

if ((PINB & (0x10))==0) //Wenn Taster 1 gedrück (Pin 2 auf low)
{
if (hell < 0x03F6)
{
hell = hell +10; //Erhöhe Helligkeit um 10
OCR1A=hell;
_delay_ms(1); //Verzögerung
}
}
if ((PINB & (0x20))==0) //Wenn Taster 2 gedrück (Pin 3 auf low)
{
if (hell > 0x0009)
{
hell= hell -10; //Verringere Helligkeit um 10
OCR1A=hell;
_delay_ms(1); //Verzögerung
}
}
}