PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : warum läuft der motor nur in der "for-schleife"



pebisoft
06.03.2005, 18:29
hallo woran liegt das?
wenn ich direkt mit "OCR1A = ii,OCR1B = ii" beschreibe geht der motor nicht ("ii=254")
in der endlosschleife. wo das bild ist steht for(2xsemicolon){ usw.....
ich habe es mit "volatile" und "const" ausprobiert.


#include <stdint.h>
#include <avr/io.h>
#include <pwm_init.c>
#include <simple_delayroutinen.c>

int main(void) {

DDRC=0xff;
cbi (PORTC,PC0);
sbi (PORTC,PC1);
sbi (PORTC,PC2);
cbi (PORTC,PC3);

uint8_t ii = 254;

pwm_init ();

for (;;) {

OCR1A = ii;
OCR1B = ii;

}

}



wenn die innere schleife steht, läuft der motor wie er soll, endlos.


int main(void) {

DDRC=0xff;
cbi (PORTC,PC0);
sbi (PORTC,PC1);
sbi (PORTC,PC2);
cbi (PORTC,PC3);

uint8_t i = 0;
pwm_init ();

for (;;) {

for (i=254; i<254; i++) {
OCR1A = i;
OCR1B = i;
}
}

}

mfg pebisoft

muraad
07.03.2005, 12:16
Ich denke es geht nicht da er die ganze Zeit sofrt wieder ii in OCR1X schreibt und ihm nie Zeit bleibt das dann auch auszufüren. Er schreibt ja sofort wieder nen neuen Wert in OCR1X, nur das der Wert der gleiche wie der alte ist. Probier mal in dein erstes Beispiel eine Delay Funktion einzubauen die nach OCR1B=11; vielleicht 1Sekunde wartet.
So ähnlich wie hier: (von mc-projekt)


#include <avr/io.h>
#include <pwm_init.c>
#include <simple_delayroutinen.c>

int main(void) {

unsigned char i = 0;
pwm_init ();

for (;;) {

for (i=0; i<254; i++) {
OCR1A = i;
OCR1B = i;
delay_us (10000);
}
}
}

Wenn du das Beispiel sowieso von da hast? Wieso hast du dann die delay Funktion rausgenommen?
Gruß Muraad

pebisoft
07.03.2005, 13:12
hallo, in der 2.schleife mit 254 laufen die motorn ja gleich mit der vorgegebenen geschwindigkeit gut ohne delay. die delay war nur als dimmer für dioden gedacht die er eingebaut hatte.
neues thema:
ich habe jetzt deine pwm ausprobiert, wunderbar. läuft ohne for-schleife auch. eine frage, wie kann ich jetzt dimmen, das die motoren von 0 bis 255 gestellt werden können. ich habe mal die zahlen von 0 bis 100 ausprobiert, die motoren laufen immer gleich schnell, der einzige unterschied ist, wenn die zahlen verschieden sind, das sie dann zeitversetzt anlaufen.
:

#include "pwm.h"


int main(void) {

PWMchannel_init;
PWM8bit_init;
PWM1upcounting;
PWM2upcounting;
Timer2_prescaler_256;
PWMdisable;
//Timer2_stop;

DDRC=0xff;
clbit (PORTC,PC0);
sebit (PORTC,PC1);
sebit (PORTC,PC2);
clbit (PORTC,PC3);

pwm8bit(25.0,0);
pwm8bit(25.0,1);

}

mfg pebisoft

muraad
07.03.2005, 13:30
Was meinst du mit zeitversetzt anlaufen?
Ich versteh in deim Code nicht wieso du nach der ganzen initialisierungs Phase bis Timer2_prescaler_256; danach schon PWMdisable; aufrufst und dann aber die pwm8bit() Funktion verwendest (PWM ist ja mit PWMdisable wieder aus). Lass das PWMdisable einfach weg und füg nach pwm8bit(25.0,1); vielleicht noch ne Endlosschleife for( ; ; ) ein.
Gruß Muraad

EDIT: ohne die Leerzeichen in der for Schleife mach er nen Smily draus

pebisoft
07.03.2005, 14:18
hallo, endloschleife kann ich nicht machen, weil das programm noch weiterarbeiten soll nachdem die motoren laufen und daten über den adc auswerten muss.
wenn ich "PWMdisable;" rausnehme, läuft nur noch ein motor.
wenn ich das "PWMdisable" reinnehme, laufen beide motoren wieder.
zeitversetzt heisst: 1. motor läuft , nach ca 1,5sec fängt der 2. motor
an zu laufen.
mfg pebisoft

muraad
07.03.2005, 14:51
Sorry Pepisoft ich verstehs grad garnicht. PWMdisable mach nichts anderes als TCCR1A = ~(1<<WGM10) & ~(1<<WGM11); dann dürfte PWM garnicht mehr gehen.
Und was machst du da:
DDRC=0xff;
clbit (PORTC,PC0);
sebit (PORTC,PC1);
sebit (PORTC,PC2);
clbit (PORTC,PC3);

pebisoft
07.03.2005, 15:13
hallo, clbit (clearbit)und sebit(setbit) sind zum setzen der bits in portc bestimmt, habe ich aus einem forum, weil es im neuem winavr diese nicht mehr gibt. am l293d liegt der portc mit 4 leitungen an. diese bestimmen am l293d die laufrichtung der motoren, haben keinen einfluss auf den ocr1a und ocr1b. je motor 2 pinc, 1 für vorwärts und 1 für rückwärts.
"PWMdisable" hat aber einfluss auf den 2. motor, wenn ich es rausnehme, läuft er nicht. komisch...
mf gpebisoft

muraad
07.03.2005, 15:28
Ich hab jetzt nochmal im Datenblatt nach den WGM´s Bits geschaut. Weist du was der Unterschied zwischen "Phase Correct PWM" also und "Fast PWM" ist?
Mit meinen Defines ist auf Phase Correct PWM eingestellt, ich weis aber nicht obs daran liegt.
Und clbit() und sebit sind doch nur die abgeänderten Defines von
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) // Setzt bit im gewünschten Register
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) // Löscht bit in ADDRESS
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) // Prüfft ob bit gesetzt ist
oder sind die jetzt offiziell in WinAVR?
Gruß Muraad

pebisoft
07.03.2005, 16:05
sind selbst erstellt, weil die es in winavr nicht mehr gibt.
warum ändert sich aber die spannung nicht, wenn ich von 0-100 gehe.
FASTPWM ist eine ander einstellung, hat mit deiner nichts zu tun.
mfg pebisoft

Dino Dieter
07.03.2005, 16:44
Hallo pebisoft

Poste doch mal deine pwm.h und die pwm.c , wenn eine vorhanden.

So kann kann man ja gar nicht genau sehen, was du machst.

MFG
Dieter

pebisoft
07.03.2005, 17:38
hallo, hier sind die programme.
die pwm-geschwingkeitsregelung(spannung) geht auch nicht .

pwm.h :

#define sebit(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) // Setzt bit im gewünschten Register
#define clbit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) // Löscht bit in ADDRESS
#define chbit(ADDRESS,BIT) (ADDRESS & (1<<BIT)) // Prüfft ob bit gesetzt ist

/*PWM-
Hier kommen meine #defines und Funktionen und zur PWM Ausgabe mit Timer2(16Bit Timer)
Beim ATmega32 geschiet die PWM Ausgabe an PD4(OC1B) und PD5(OC1A). Mit den #defines stellt
man die ganze Voreinstellungen ein. Mit den Funtkionen pwmXbit() kann man dann das PWM
Ausgangssignal steuern. Mit pwm_index setzt man fest an welchen Ausgang. limit_range
unterteil den PWM Bereich in 0.0-100.0 Das ganze sieht dann so aus
z.B pwm9bit(35.0,1) damit ist PWM Ausgabe an Ausgang 2 wobei im OutputCompareRegister
35.0*327.68 = (int) 11468.8 steht
*/
#define PWMchannel_init DDRD= (1<<PD4) | (1<<PD5); // PWM Ports als ausgang deklarieren
#define PWM8bit_init TCCR1A |=(1<<WGM10) // Gewünschte PWM 8,9 oder eben 10Bit
#define PWM9bit_init TCCR1A |=(1<<WGM11)
#define PWM10bit_init TCCR1A = (1<<WGM10) | (1<<WGM11)
#define PWMdisable TCCR1A = ~(1<<WGM10) & ~(1<<WGM11) // Timer2 wieder normaler Timer
#define PWMnoCO1A TCCR1A = ~(1<<COM1A0) & ~(1<<COM1A1) // Kein PWM an Ausgang1
#define PWMnoCO1B TCCR1A = ~(1<<COM1B0) & ~(1<<COM1B1)
#define PWM1upcounting TCCR1A = (1<<COM1A0) | (1<<COM1A1) // invertierende PWM
#define PWM2upcounting TCCR1A = (1<<COM1B0) | (1<<COM1B1)
#define PWM1downcounting TCCR1A |= (1<<COM1A1) // nicht invertierend
#define PWM2downcounting TCCR1A |= (1<<COM1B1)
#define Timer2_prescaler_1 TCCR1B |= (1<<CS10) // verschiedene Prescaler
#define Timer2_prescaler_8 TCCR1B |= (1<<CS11)
#define Timer2_prescaler_64 TCCR1B = (1<<CS11) | (1<<CS10)
#define Timer2_prescaler_256 TCCR1B |= (1<<CS12)
#define Timer2_prescaler_1024 TCCR1B = (1<<CS12) | (1<<CS10)
#define Timer2_stop TCCR1B = ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10) // stopt Timer2

float limit_range(float val,float low,float high)
{
if(val<low) return low;
else if(val>high) return high;
else return val;
}

void pwm8bit(float vel, unsigned char pwm_index) // pwb_index 0 für Ausgang 1, 1 für Ausgang 2
{ // für 8Bit Pwm
vel = limit_range(vel,0.0,100.0);
if(pwm_index==0)
OCR1A= (int) (163.84*vel);
if(pwm_index==1)
OCR1B= (int) (163.84*vel);
}

void pwm9bit(float vel, unsigned char pwm_index) // pwb_index 0 für Ausgang 1, 1 für Ausgang 2
{
vel = limit_range(vel,0.0,100.0);
if(pwm_index==0)
OCR1A= (int) (327.68*vel);
if(pwm_index==1)
OCR1B= (int) (327.68*vel);
}

void pwm10bit(float vel, unsigned char pwm_index) // pwb_index 0 für Ausgang 1, 1 für Ausgang 2
{
vel = limit_range(vel,0.0,100.0);
if(pwm_index==0)
OCR1A= (int) (655.36*vel);
if(pwm_index==1)
OCR1B= (int) (655.36*vel);
}
//ende


pwm.c :

#include <stdint.h>
#include <avr/io.h>
#include "pwm.h"

void main(void) {

PWMchannel_init; // aus der pwm.h
PWM8bit_init;
PWM1upcounting;
PWM2upcounting;
Timer2_prescaler_256;
//PWMdisable; // wenn ich ihn rein nehme drehen beide motoren, ohne diesen befehl nur 1 motor

DDRC=0xff; // für die drehrichtung der motoren
clbit (PORTC,PC0);
sebit (PORTC,PC1);
sebit (PORTC,PC2);
clbit (PORTC,PC3);

pwm8bit(25.0,0); // aus der pwm.h
pwm8bit(25.0,1);

}

//ende

Dino Dieter
07.03.2005, 20:17
Hallo Pebisoft

in der PWM.h waren ein paar kleine Fehler . Meist fehlende UND / ODER Verknüpfungen.

Habe die PWM8Bit mal auf Prozent Werte umgebaut.

pwm8bit(10.0,0); 10 Prozent an
pwm8bit(90.0,0); 90 Prozent an


Hoffe, das hilft

MFG
Dieter

Arexx-Henk
07.03.2005, 21:08
Hallo pebisoft,

in deinem program wird nur WGM10 hoch
dass heist: Waveform Generation Mode 1
in dieser mode is die maximale zahlerwert TOP = 255

wenn du pwm8bit(25.0,0) anrufst wird die wert die in
OCR1A geschrieben von 25.0 * 163.84 = 4096
dass ist ein viel zu hohen vergleichswert,
die soll doch maximal 255 (TOP) sein?
und sollte mann doch nur OCR1AL (Low) benutzen?


oder irre ich mich hier?

gruss

Henk

muraad
07.03.2005, 21:57
Ich denk Henk hat recht. Änder mal in der Funktion pwm8bit(), pwm9bit(),pwm10bit() sechs Zeilen so:
8Bit:
OCR1A= (char) (2.55*vel);
OCR1B= (char) (2.55*vel);
9Bit:
OCR1A= (char) (5.11*vel);
OCR1B= (char) (5.11*vel);
10Bit:
OCR1A= (char) (10.23*vel);
OCR1B= (char) (10.23*vel);

Gruß Muraad

EDIT du musst noch die Zeilen bei pwm9bit() und pwm10bit() ändern.
Und danke dir Dino Dieter jetzt funktioniert der Code wenigstens einwandfrei.

pebisoft
07.03.2005, 22:04
hallo, dino dieter, deine änderung läuft 100%. ich kann sogar die for-schleife rausnehmen, klasse. alle richtungen mit verschiedenen geschwindigkeiten laufen. hallo muraad, dino dieter hat noch 3 fehler ausgebessert (und/oder-änderung). lad oben die datei mal runter.
mfg pebisoft

muraad
07.03.2005, 23:35
Ach und ich hab nochmal nachgeschaut. Wenn man mehrere Bits auf einmal löscht/setzt braucht man vor dem ersten = also z.B. TCR1B = kein | oder & . Dann muss man im Code nur die OCR1A und OCR1B zuweisung ändern wie oben geschrieben.