www.mikrocontroller.net

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


Autor: Ben (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
    OCR1A = motorSpeed1;
 so vielleicht?

;-) Jörg

Autor: Ben (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ben (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Jörg X. (Gast)
Datum:

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

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

hth. Jörg

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.