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
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
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
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
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.
Alle sind unzufrieden - und alle machen weiter wie bisher.
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
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.
Lesezeichen