PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm zur ansteuerung 4 Motoren mit PWM



taylor22
17.10.2007, 23:28
Habe folgendes Programm zur Ansteuerung meiner 4 Motoren über PWM
geschrieben! Die Funkton setMotorSpeed() soll wie der Name schon sagt
die Geschwindigkeit der Motoren setzen! Das wird über den OCRnx Wert
gemacht, um so die PWM-Breiten zu verändern! Nur wie schreibe ich diesen
Wert in das 16-Bit Register OCRnx! Das OCRnxH Register ist dabei immer
0, da ich nur einen 8-Bit PWM verwende! So wie's da ist geht's irgendwie
nicht! Wie beschreibe ich diese 16-Bit Register richtig? Verwende einen
ATmega128! Besten Dank!

#include <avr/io.h>
#include <avr/interrupt.h>

//function definition
void setMotorSpeed(unsigned char motorSpeed1, unsigned char motorSpeed2,
unsigned char motorSpeed3, unsigned char motorSpeed4);

int main(void){
sei();
//setting PWM-Ports as output
DDRB|=(1<<PB7)|(1<<PB6)|(1<<PB5);
DDRE|=(1<<PE3);
// PWM,Phase correct,8-Bit mode
TCCR1A|=(1<<WGM10);
TCCR3A|=(1<<WGM30);
// Timer running on MCU clock/8
TCCR1B|=(1<<CS11);
TCCR3B|=(1<<CS31);
//set Motor Speed
setMotorSpeed(200,100,160,220);
while(1);
return 0;
}


void setMotorSpeed(unsigned char motorSpeed1, unsigned char
motorSpeed2,unsigned char motorSpeed3, unsigned char motorSpeed4){
unsigned char sreg;
//store global interrupt flag
sreg=SREG;
//turn off interrupts
cli();
OCR1AH=0;
OCR1AL=motorSpeed1;
OCR1BH=0;
OCR1BL=motorSpeed2;
OCR1CH=0;
OCR1CL=motorSpeed4;
OCR3AH=0;
OCR3AL=motorSpeed4;
SREG=sreg;
}

askazo
18.10.2007, 08:20
Prinzipiell ist alles richtig so. Du musst nur noch die COM-Bits im TCCRnA Register richtig einstellen, sonst läuft zwar der Timer, wie er soll, aber an den Ausgängen passiert gar nichts...

Du kannst übrigens 16-Bit Register auch in einem Schritt beschreiben:
Statt

OCR1AH=0xAB;
OCR1AL=0xCD;

würde genauso

OCR1A = 0xABCD;

funktionieren.

askazo

taylor22
18.10.2007, 11:04
ok vielen dank, habe jetzt die com register auch noch gesetzt! was das setzten der OCR1A usw betrifft, das geht nich immer nicht wirklich! ich denke du bist dir da schon ziemlich sicher, dass das so wirklich geht, oder? Wenn ich das nämlich im avr studi simuliere (kannst ja gern mal auch machen), wird nur OCR1A richtig gesetzt! Der Wert der ins OCR1BL sollte wird aber ins H geschrieben! Bei OCR1C und OCR3A passiert dann gar nichts mehr? Könnte das ein bug von avr studio sein?

taylor22
18.10.2007, 11:06
#include <avr/io.h>
#include <avr/interrupt.h>

//function definition
void setMotorSpeed(unsigned char motorSpeed1, unsigned char motorSpeed2,unsigned char motorSpeed3, unsigned char motorSpeed4);

int main(void){
sei();
//setting PWM-Ports as output
DDRB|=(1<<PB7)|(1<<PB6)|(1<<PB5);
DDRE|=(1<<PE3);
// PWM,Phase correct,8-Bit mode
TCCR1A|=(1<<WGM10);
TCCR3A|=(1<<WGM30);
//no-inverting PWM
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1);
TCCR3A|=(1<<COM3A1);
// Timer running on MCU clock/8
TCCR1B|=(1<<CS11);
TCCR3B|=(1<<CS31);
//set Motor Speed
setMotorSpeed(200,100,160,220);
while(1);
return 0;
}


void setMotorSpeed(unsigned char motorSpeed1, unsigned char motorSpeed2,unsigned char motorSpeed3, unsigned char motorSpeed4){

unsigned char sreg;
//store global interrupt flag
sreg=SREG;
//turn off interrupts
cli();
OCR1A=motorSpeed1;
OCR1B=motorSpeed2;
OCR1C=motorSpeed3;
OCR3A=motorSpeed4;
SREG=sreg;
}