PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM probleme mit ATMega32



sloti
17.03.2008, 18:32
Moin Moin,

ich möchte mit meinem ATMega32 zwei Motoren Ansteuern. Die Dafür vorgesehene PWM einstellunge krieg ich aber irgendwie nicht hin :( . Als erstes weiß ich nicht welche COM bits ich setzten soll. Für mich kland Toggle on compare Match richtig also hab ich COM1A0 und COM1B0 gesetzt. Für Fast PWM im 8bit modus hab ich WGM12 und WGM10 gesetzt. als Prescaler hab ich 8, also hab ich CS11 noch gesetzt. Aber irgendwie funktioniert das ganze noch nicht Wirklich wo ist der Fehler? Hier nochmal der Code :

#define F_CPU 11059200
#include <avr\io.h>
#include <avr\interrupt.h>
#include <inttypes.h>

void init(void)
{
DDRB = (1<<PB0) | (1<<PB1);
TCCR1A= (1<<COM1A0) | (1<<COM1B0) | (1<<WGM10);
TCCR1B= (1<<WGM12) | (1<<CS11);
}

void LEDON (void)
{
PORTB = (1<<PB0)|(1<<PB1);
}

inline void Geschwindigkeit(unsigned char left_speed, unsigned char right_speed)
{
OCR1AH = left_speed;
OCR1BH = right_speed;
}

/*inline void Richtung(unsigned char left_dir, unsigned char right_dir)
{
PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir;
PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir;
}*/


int main (void)
{
init();
while (1)
{
LEDON();
Geschwindigkeit(250,250);

}
return 0;
}

mfg
Erik

Reeper
17.03.2008, 19:00
Also:

Timer 1 -> pd.4 und pd.5
nimm doch normalen Modus

zB.:


#define F_CPU 11059200
#include <avr\io.h>
#include <avr\interrupt.h>
#include <inttypes.h>

void init(void)
{
DDRD |= (1<<4)|(1<<5);
TCCR1A = (1<<COM1A1)|/*(1<<COM1A0)*/(1<<COM1B1)|/*(1<<COM1B0)|(1<<FOC1A)|(1<<FOC1B)|(1<<WGM11)|*/(1<<WGM10);
TCCR1B = /*(1<<ICNC1)|(1<<ICES1)|(nix)|(1<<WGM13)|(1<<WGM12)|(1<<CS12)|*/(1<<CS11)/*|(1<<CS10)*/;
}

void LEDON (void)
{
PORTD |= (1<<4)|(1<<5);
}

inline void Geschwindigkeit(int left_speed, int right_speed)
{
OCR1A = left_speed;
OCR1B = right_speed;
}


int main (void)
{
init();
while (1)
{
LEDON();
Geschwindigkeit(250,250);
}
//return 0; -> wird nie erreicht (oben Endlosschleife)
}

Mal leider gerade kein Testboard liegen, hoffe es funktioniert trotzdem.

Gruß Stefan

Ceos
17.03.2008, 19:02
du solltest nicht permanent Geschwindigkeit(); aufrufen, sondern möglichst NUR DANN wenn der wert sich ÄNDERT! gut möglich das du den counter damit verwirrst, aber auf anhieb seh cih nix schlechtes bei

mh HALT
OCR1AH = left_speed;
OCR1BH = right_speed;

ouh mann ... RTFM soll heissen bitte das datenblatt ordentlich lesen, du schreibst nur in das HIGH byte ... logisch das die änderungen NIE ankommen, das HIGH byte ist double buffered und wird NUR dann geschrieben wenn auch das LOW byte geschrieben wird .... lass das H am ende BITTE ganz weg und schreib nicht getrennt in low und high byte, liess das datenblatt um zu begreifen WARUM

EDIT: ein klein wenig zu langsam, Reeper hat es richtig gemacht in seiner geschwindigkeitsfunktion .... PS reeper es ist kein problem wenn er die bits im DDR setzt, bringt aber nix, weil die pin-einstellungen des Timer die DDR vollständig überlagern

trotzdem sollte man das OCR register nur dann updaten wenn auch wirklich ein neuer wert vorhanden ist, es gibt timer-modi auf bestimmten megas die wegen sowas rumspinnen

EDITEDIT: iwie gruselig ... ich hab mir nur das datenblatt ausgedruckt und wenn mir langweilig war darin gelesen ... und es bleibt sogar hängen ... ich werde nie wieder auf druckware schimpfen auch wenn cih kein bücherfreund bin

sloti
17.03.2008, 20:18
Ok danke kapiert :)