PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Erzeugung PMW in C an Motorklemme von RN 1.4



Moe
11.11.2004, 17:27
Hallo,
habe den ganzen Tag versucht herauszufinden, wie man einen Getriebemotor (4,5-15V, 1A) über PWM ansteuern kann. Ich habe das RNCONTROL 14 von roboterhardware der einen L293D integriert hat. Es gelingt mir, über die Motorklemmen Spannung auszugeben. Leider kann ich immer nur 0V oder 12 V an den Motor geben - ich möchte das gerne regelbar machen.

Im folgenden Code habe ich die von mir benutzten Befehle für das PWMen dargestellt:


#define PWM_init DDRD= _BV(PD4) | _BV(PD5);
#define upcounting TCCR1A = _BV(COM1A0) | _BV(COM1A1)
#define downcounting TCCR1A |= _BV(COM1A1)
#define T_prescaler_256 TCCR1B |= _BV(CS12)
#define T_stop TCCR1B = ~_BV(CS12) & ~_BV(CS11) & ~_BV(CS10)

void main(void){
....
outp(0xFF, DDRC); // Alle Ports von C als Output setzen
outp(0xFF, PORTC); // Alle Ports 0
outp(0xFF, DDRD); // Alle Ports von D als Output setzen
outp(0xFF, PORTD); // Alle Ports 0


PWM_init;
upcounting;

sbi(PORTC, 6);//Drehrichtung
cbi(PORTC, 7);//Drehrichtung
sbi(PORTD, 4);
//Timer2_stop;
//Timer2_prescaler_256;
for(i = 0; i > 1023; ++i){
OCR1B= i;
OCR1A= i;
ms_sleep(30);
}
....
}

Wenn ich sbi(PORTD, 4) setze, dann liegen gleich 12V an den Klemmen. Lasse ich eben diesen Befehl weg, dann messe ich nur zwischen 35 bis 75 mV und der Motor macht gar nichts.

Ich habe im Manual vom Atmega32 nachgeschaut, werde aber nicht richtig schlau daraus. Vielleicht kann mir jemand einen Tipp geben.

Für Eure Mühe schönen Dank!

Gruß!

Dino Dieter
11.11.2004, 17:34
Hallo

Du hast vergessen, den Timer auch einzuschalten.

PWM_init;
upcounting;
T_prescaler_256 ;

MFG
Dieter

Moe
11.11.2004, 17:58
Hi,

danke für die schnelle Antwort. Mein Code sieht jetzt so aus:


#define PWM_init DDRD= _BV(PD4) | _BV(PD5);
#define upcounting TCCR1A = _BV(COM1A0) | _BV(COM1A1)
#define downcounting TCCR1A |= _BV(COM1A1)
#define T_prescaler_256 TCCR1B |= _BV(CS12)
#define T_stop TCCR1B = ~_BV(CS12) & ~_BV(CS11) & ~_BV(CS10)

void main(void){
....
outp(0xFF, DDRC); // Alle Ports von C als Output setzen
outp(0xFF, PORTC); // Alle Ports 0
outp(0xFF, DDRD); // Alle Ports von D als Output setzen
outp(0xFF, PORTD); // Alle Ports 0


PWM_init;
upcounting;

sbi(PORTC, 6);//Drehrichtung
cbi(PORTC, 7);//Drehrichtung
sbi(PORTD, 4);

T_prescaler_256;
for(i = 0; i < 1023; ++i){
OCR1B= i;
OCR1A= i;
ms_sleep(30);
}
....
}

Es funktioniert aber immer noch nicht. Ich habe eine printf()-Ausgabe in ndie FOR-Schleife gesetzt, die mir den Wert von i Anzeigt. Die Schleife wird ausgeführt, es passiert aber nichts. Irgendwann läuft sie ab und es schert niemanden.
Ich hoffe, dass ich nicht irgenein Register vergessen habe.
Danke!

Frank
11.11.2004, 22:40
AVR-C ist ja nicht mein Gebiet, aber mach mal die For Next Schleife weg und gib probehalber dafür nur an:
OCR1B= 500;
OCR1A= 500;

Dreht sich dann Motor langsamer oder tut sich nix?

Moe
12.11.2004, 09:03
Hallo Frank,

die Schleife ist weg und ich habe mehrere Werte zwischen 1 und 1023 für den OCRx versucht und es passiert gar nichts. Wahrscheinlich muss ich irgendwo noch ein Registerbyte für den PORTD bearbeiten oder habe einfach eine falsche Definition (#define PWM_init DDRD= _BV(PD4) | _BV(PD5); ) o.ä. gemacht. Ich werde weiter suchen. Ich melde mich, sobald ich eine Lösung gefunden habe.
Danke für Eure Hilfe!
Gruß!

12.11.2004, 09:47
Hallo

Bei einstellen des Timers fehlt noch die WAVEFORM laut Tabelle 46 Seite 107 Datenblatt.


#define upcounting TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(WGM10) | _BV(WGM11)

für 10 Bit PWM

Im Ordner \\winavr\examples\demo ist zu dem Thema ein schönes Beispiel drin.

MFG
Dieter