PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM signale am Oszilloskop sehen nicht gut aus. Warum?



mucahith
28.03.2007, 16:16
Ich habe das folgende Programm geschrieben um die Geschwindigkeit eines Motors anzusteuern. Das problem ist,dass die Signale am Oszilloskop nicht so korrekt aussehen,wenn ich an PortA angeschlossene Poti drehe.Die PWM Signale sind durcheinander.
Ist das normal oder nicht ?
Ich glaube das Problem liegt bei for-Schleife.

kann jemand mir helfen?

Ich nutze ein Atmega16.


#include <avr/io.h>

uint8_t t=0;
uint8_t c = 0;

void init_io(void)
{
DDRD |= (1<<PD4); //PortD wird als Ausgang definiert
DDRA &= ~(1<<DDA0); /* Pin PA0 als Eingang */
PORTA |= (1<<PA0); //Pullup-Wiederstand von PortA Pin0 wird aktiviert
}

uint16_t readADC(uint8_t channel) {
uint8_t i;
uint16_t result = 0;

// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

// Kanal des Multiplexers waehlen
ADMUX = channel;
// Interne Referenzspannung verwenden (also 2,56 V)
ADMUX |= (1<<REFS1) | (1<<REFS0);

// Den ADC initialisieren und einen sog. Dummyreadout machen
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));

// Jetzt 3x die analoge Spannung and Kanal channel auslesen
// und dann Durchschnittswert ausrechnen.
for(i=0; i<3; i++) {
// Eine Wandlung
ADCSRA |= (1<<ADSC);
// Auf Ergebnis warten...
while(ADCSRA & (1<<ADSC));

result = ADCL;
result += (ADCH<<8);

}

// ADC wieder deaktivieren
ADCSRA &= ~(1<<ADEN);

result /= 3;

return result;
}


void main(void)
{
init_io(); //Ruft die Funktion init_io() auf


while(1)
{

t=0;
c = readADC(0); //lese analogen wert aus channel 0 in c
for(t=0;t<c;t++){ //zählt..
if (PINA & (1<<PINA0)) //wenn PINA0 an is
PORTD = PIND ^(1 << PD4); //wechsle den status von PIND4 (Motor dreht)
else PORTD &= ~(1<<PD4); //wenn PINA0 nich an bleibt, Motor aus
} }
}

s.o.
28.03.2007, 18:04
Hallo,

entschuldige jetzt bitte die Antwort. Aber mich wundert's nicht. Du verwendest ja keinen Timer. Wenn ich mich recht erinnere braucht der ADC etwas länger Zeit, und dann gleich 3x. Das braucht natürlich schon mehr Zeit. Und somit wird dein PWM-Sig verfälscht. Besser wäre es, es mit einem Timer zu realisieren, somit hättest du kein Problem mit der Verzögerung...

Grüße

mucahith
29.03.2007, 02:09
Danke für die Hilfe.Aber Ich bin ein Anfänger . ich weiss nicht wie ich den Timer verwenden kann. Kannst du vielleicht einen Beispielcode geben für mein Programm. Es wäre nett.

Superhirn
29.03.2007, 19:04
mal mein senf:

*adc auslesen mit result = ADC; damit du keine probleme mit den 16bit hast.
* result = ADCL;
result += (ADCH<<8);
setzt den adcl auf den aktuellen wert. also kein aufaddieren. somitkannst du keinen mittelwert bilden. verwende besser:
result += ADC; ist eine einzige zeile, funktioniert und ist eleganter.
* while(ADCSRA & (1<<ADSC)); wird wegoptimiert. da sie ja nix tut. du kannst das wegoptimieren mit:
while(ADCSRA & (1<<ADSC)) { ; } verhindern.