PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM Problem



Finwe0815
27.09.2007, 18:18
Hy zusammen,

ich hab nen kleines Problem mit dem PWM Mode meines Atmeg8, und zwar versuche ich durch drücken eines Tasters ne LED heller zu machen, bzw. wenn ein best. Wert errericht ist die LED wieder erlöschen zu lassen. Eigentlich funktioniert auch alles, ausser dass die LED nie wirklich ganz aus ist!? (Bei OCR1A sollte dass doch aber sein, oder?)
Nur warum funktioniert es nicht???

Auch wenn ich direkt OCR1A=0 setze ist die LED auch nicht (ganz) aus, ich schätze das hängt vielleicht mit der Initialisierung zusammen???

Noch was zur Hardware PB1 --> PWM Ausgabe
PB0 --> Taster einlesen
PC0 --> Test LED (bei Tastendruck)

Hier mal der Quellcode:


// Test PWM

#include <avr/io.h>
#include <util/delay.h>


int main (void)
{

DDRB &= ~( 1 << PB0 ); //set PB0 input
PORTB |= ( 1 << PB0 ); //set PB0 Pull up on

DDRB |= (1 << PB1); //set PB1 output
PORTB |= ( 1 << PB1 ); //set PB1 Pull up on

DDRC |= ( 1 << PC0 ); //set PC0 output

TCCR1A = (1 << WGM11); // mode 14, fast pwm, update at top
TCCR1B = (1 << WGM13) // tov1 flag set on top
| (1 << WGM12) // top = ICR1
| (1 << CS11) // clock select clk/64
| (1 << CS10);
ICR1 = 255;


TCCR1A |= (1 << COM1A1); //don´t invert
OCR1A = 0; //start value

while(1)
{

/*Test automatic inrementation of OCR1A
OCR1A ++;
_delay_ms(10);
if (OCR1A >=255)
{
OCR1A = 0;
}
*/

if (!(PINB & (1 << PB0))) //if PB0 is low then (bec. PB0 --> Pull up)
{
PORTC |= (1 << PC0); //set PC0 high
OCR1A = OCR1A+1; //inc OCR1A
_delay_ms(1000); //delay time for switch
}//if (!(PINB & (1 << PB0)))
else //else
{
PORTC &= ~(1 << PC0); //set PC0 low
}//else if (!(PINB & (1 << PB0)))
if (OCR1A >=10) //if OCR1A is 255 then
{
OCR1A =0; //reset OCR1A
}//if (OCR1A >=255)


}//while(1)
return 0;
}//int main (void)



Noch ne Frage: Kann ich bei dieser Programmierung davon ausgehen, dass die Spannung bei jedem Tastendruck jetzt um (5/255)[V] Schritten erhöht wird?

Vielen Dank im Voraus
Gruß Finwe0815

Finwe0815
28.09.2007, 13:22
Hy Leute,

ich hab noch was festgestellt, und zwar, dass auch nie annähernd 5V am Ausgang anliegen?!

Also ich will später mit 2 PWM Ausgängen arbeiten für ne Motorsteuerung, aber leider bekomm ich ja noch nicht mal einen hin :-s ...

Hat von euch jemand nen leicht verständlichen Code in dem 2 PWM´s erzeugt werden also von 0-5 V ???

Danke im Voraus
Gruß Finwe0815

P.S. ich hab auch schon hier im Forum und im Netz gesucht aber ich hab das alles nicht so wirklich verstanden.

Finwe0815
28.09.2007, 16:44
So ich bins nochmal...

und 4 Stunden (und einem Atmega8 weniger) später funzt es...ich hab es jetzt hinbekommen alle 3 PWM Ausgänge ins Laufen zu bekommen...also bei mir funzt es mal. Ich hab alles sehr einfach gehalten, dass wenn noch jemand Probleme hat er sich vielleicht daran orientieren kann, falls es denn richtig ist. Vielleicht könnte ja mal der Ahnung hat drüberschauen und nen Statement abgeben....

Hier der KOT

/* PWM on Atmega8
Enjoy it :-)
Hardware:
Atmega8 PDIP
Switch at PB0
1 x switch at PB0 for dimming and test
1 x LED at PB1 for (OCR1A)
1 x LED at PB2 for (OCR1B)
1 x LED at PB3 for (OCR2)
1 x LED at PC0 for Switch (when switching LED on, no need!)
*/

#include <avr/io.h>
#include <util/delay.h>


int main (void)
{
DDRB &= ~(1<<PB0); //set PB0 input (switch)
PORTB |= (1<<PB0); //set PB0 Pull up on

DDRB |= (1<<PB1); //set PB1 output (PWM OCR1A)
PORTB |= (1<<PB1); //set PB1 Pull up on

DDRB |= (1<<PB2); //set PB2 output (PWM OCR1B)
PORTB |= (1<<PB2); //set PB2 Pull up on

DDRB |= (1<<PB3); //set PB3 output (PWM OCR2)
PORTB |= (1<<PB3); //set PB3 Pull up on

DDRC |= (1<<PC0); //set PC0 output (LED)

// Timer1 init for PWM on Pin PB2 and PB1
TCCR1A = 0x00; // stop T/C1
TCCR1A = (1<<WGM10) //set PWM phase correct mode 8 bit
|(1<<COM1A1) //clear OCR1A on compare match when up-counting
|(1<< CS10) //no prescaler, start timer1/A-L
|(1<<COM1B1); //clear OCR1B on compare match when up-counting
TCCR1B = (1<< CS10); //no prescaler, start timer1/B-H

// Timer2 init for PWM on Pin PB3
TCCR2 = 0x00; //stop T/C2
TCCR2 = (1<<WGM20) //set PWM phase correct mode 8 bit
|(1<< CS20) //no prescaler, start timer2
|(1<<COM21); //clear OC2 on compare match when up-counting

OCR1A = 0; //start value of OCR1A
OCR1B =10; //start value of OCR1B
OCR2 = 0; //start value of OCR2

while(1)
{
if (!(PINB & (1 << PB0))) //if PB0 is low then (switch)
{
PORTC |= (1 << PC0); //set PC0 high (LED on)
OCR1A ++; //inc OCR1A
OCR1B --; //dec OCR1B
OCR2 ++; //inc OCR2
_delay_ms(1000); //delay time for switch
}
else //else
{
PORTC &= ~(1 << PC0); //set PC0 low (LED off)
}

// reset procedure* (*I know I need no 3 queues but...)
if (OCR1A >=10)
{
OCR1A = 0;
}
if (OCR1B <=0)
{
OCR1B = 10;
}
if (OCR2 >=10)
{
OCR2 = 0;
}
}//while(1)
return 0;
}//int main (void)



Danke
Finwe0815