Forum: Mikrocontroller und Digitale Elektronik Programm zur Ansteuerung 4 Motoren über PWM


von Ben (Gast)


Lesenswert?

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;
}

von Jörg X. (Gast)


Lesenswert?

1
    OCR1A = motorSpeed1;
 so vielleicht?

;-) Jörg

von Ben (Gast)


Lesenswert?

....
OCR1A=motorSpeed1;
OCR1B=motorSpeed2;
OCR1C=motorSpeed3;
OCR3A=motorSpeed4;
....

Wenn ich das so mit deiner Variante simuliere (in AVR Studio) wird OCR1A 
zwar noch korrekt beschrieben, OCR1B aber schon nicht mehr! Der Wert von 
OCR1B wird in das H-Register geschrieben! Bei OCR1C und OCR3A wird dann 
gar nichts mehr geschrieben!

von Jörg X. (Gast)


Lesenswert?

Ist im Simulator der richtige Controller eingestellt?
(muss du ja noch mal extra machen)
 Außerdem sind die 16Bit-Register im Simulator mit Vorsicht zu genießen, 
siehe "Help"->"Simulator"->"Known Issues".

Zu deiner main() im ersten Post: mach das sei() am besten erst als 
letztes vor der Endlosschleife, dann können die Interrupts nicht in die 
Initialisierung reinspielen.

hth. Jörg

von Ben (Gast)


Lesenswert?

hier nochmals das fertige Programm (COM Register korrigiert!) wäre froh 
wenn das mal jemand simulieren könnte und die OCRA1 Register usw 
beobachten ! passiert einfach nicht wirklich das was hier programmiert 
ist! liegt das wirklich am avr studio?


#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;
}

von Jörg X. (Gast)


Lesenswert?

Ist wohl ein Simulatorproblem: der erzeugte Assembler Code sieht korrekt 
aus.
1
void setMotorSpeed(uint8_t motorSpeed1, uint8_t motorSpeed2,
2
           uint8_t motorSpeed3, uint8_t motorSpeed4)
3
{
4
  ce:  ef b7         in  r30, 0x3f  ; 63
5
  uint8_t sreg;
6
  //store global interrupt flag
7
  sreg=SREG;
8
  //turn off interrupts
9
  cli();
10
  d0:  f8 94         cli
11
  OCR1A=motorSpeed1;
12
  d2:  99 27         eor  r25, r25
13
  d4:  9b bd         out  0x2b, r25  ; 43
14
  d6:  8a bd         out  0x2a, r24  ; 42
15
  OCR1B=motorSpeed2;
16
  d8:  77 27         eor  r23, r23
17
  da:  79 bd         out  0x29, r23  ; 41
18
  dc:  68 bd         out  0x28, r22  ; 40
19
  OCR1C=motorSpeed3;
20
  de:  55 27         eor  r21, r21
21
  e0:  50 93 79 00   sts  0x0079, r21
22
  e4:  40 93 78 00   sts  0x0078, r20
23
  OCR3A=motorSpeed4;
24
  e8:  33 27         eor  r19, r19
25
  ea:  30 93 87 00   sts  0x0087, r19
26
  ee:  20 93 86 00   sts  0x0086, r18
27
  SREG=sreg;
28
  f2:  ef bf         out  0x3f, r30  ; 63
29
  f4:  08 95         ret

Das wirst du wohl in Hardware testen 'müssen' ;)

hth. Jörg

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.