PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM am Atmega8535



RoboPunk
27.10.2007, 21:09
Hallo,

ich habe einen Atmega8535 und will einen Motor über den Ausgang OC0 und PC0/PC1 ansteuern. PWM Mode: Fast PWM, Frequenz: 256.
Als "Versuchsmotor" benutze ich eine LED mit 100Ohm Vorwiderstand über den Schaltkreis L298. Ich bringe sie aber leider nicht zum Leuchten!
Hier mal mein Code:


/* ************************************************** ******
PWM

PWM-Ausgang: OC0/PB4
I/O-Pins: PC0/PC1
************************************************** *** */
#include <avr/io.h>
#include <stdint.h>


// Funktion zur Steuerung der Motoren
// speed[-255-255]=Motorgeschwindigkeit/Vorwärts-/Rückwärtsdrehen
int motor(int speed)
{
if (speed<0)
{
PORTC |= ( 1 << PC0 ); // Linksdrehen
PORTC |= ( 0 << PC1 );
OCR0 = -speed; // Vergleichswert festlegen=Geschwindigkeit einstellen(0-255)
}

if (speed>=0)
{
PORTC |= ( 0 << PC0 ); // Rechtsdrehen
PORTC |= ( 1 << PC1 );
OCR0 = speed;
}
PORTC |= ( 0 << PC0 );
PORTC |= ( 1 << PC1 );
OCR0 = speed;
}

// PWM initialisieren
int pwm_init(void)
{
DDRC = 0x11000000;
DDRB = 0x000010000;
TCCR0 = (0<<WGM01)|(1<<WGM00)|(1<<COM01)|(0<<COM00)|(1<<CS02)|(0<<CS01)|(0<<CS00); // Fast-PWM-Mode, toogle at Top
}


int main(void)
{
pwm_init();
while(1)
{
motor(160);
}
}

Kann es sein dass ich noch einen Fehler im Programm übersehen hab oder liegt es sicher an der Hardware?

Gruß

Bene

CsT
27.10.2007, 22:08
Hi,
also folgende Fehler sind mir auf die schnelle aufgefallen:

Bits löschen nicht so:

PORTC |= ( 0 << PC0 );
sondern so:

PORTC &= ~(1 << PC0);

Warum und weswegen lässt sich in verschiedensten Tutorials nachlesen.

Weiterhin hast du in deiner Funktion Motor zunächst Prüfung ob speed < 0 oder >= 0 ist, dann setzt du aber danach egal wie speed ist eh und je PORTC nochmal, dass muss raus.
Hier mal die berichtigte Funktion:


void motor(int speed)
{
if (speed<0)
{
PORTC &= ~(1 << PC0); // Linksdrehen
PORTC |= ( 1 << PC1 );
OCR0 = -speed; // Vergleichswert festlegen=Geschwindigkeit einstellen(0-255)
}

if (speed>=0)
{
PORTC |= ( 1 << PC0 ); // Rechtsdrehen
PORTC &= ~(1 << PC1);
OCR0 = speed;
}
}

Die Unterschiede kannst du dir ja selbst anschauen .. weiterhin gibt die Funktion ja keinen Wert zurück, deswegen void als Rückgabetyp.

In deiner pwm_init setzt du auch DDRC falsch. Die Bits werden von hinten an gezählt .. also

DDRC = 0x00000011;

Damit PC0 und PC1 auf Ausgang gestellt sind.

Dein TCCR0 hab ich mir jetzt nicht angeschaut, hast du ja bestimmt irgendwo rauskopiert?



So, das waren erstmal alle Fehlerchen, die ich auf Anhieb gefunden habe.

Viele Grüße CsT

EDIT:
ein

return 0;

gehört noch ans Ende deiner main-Funktion! Hinter der while-Schleife!

RoboPunk
27.10.2007, 22:24
Hi,
danke für die Antworten! Den Fehler in der funktion motor() hab ich nur zu testzwecken dringehabt und des andre dann auskommentiert, habs wohl beim post vergessen^^
Des TCCR0 ist nicht iwo rauskopiert hab ich alles selbst nachgeschaut, kann also auch Fehler beinhalten, ich hab mich nur beim Prinzip an des Tutorial bei microcontroller.net gehalten.

Die anderen Verbesserungen setz ich mal gleich um!

Danke

Bene

//edit:

Optimal die LED blinkt jetzt! Ich probier dann mal noch die verschiedenen Geschwindigkeiten aus.

Vielen Dank für deine Hilfe!

RoboPunk
27.10.2007, 23:03
Hi,

kaum ist das eine Problem gelöst, taucht schon das nächste auf.
Wenn ich die LED auf dem Steckbrett umpole und dazu auch die Richtung im Programm ändere, dann müsste sie ja trotzdem leuchten, oder?
Leider funktionieren nur Geschwindigkeiten von-255 bis -1.

Ich versteh das nicht, wenn ich auf eine positive Geschwindigkeit schalte dann tut sich nichts.

Hier das Programm so wie es jetzt aussieht:


/* ************************************************** ******
PWM

PWM-Ausgang: OC0/PB4
I/O-Pins: PC0/PC1
************************************************** **** */
#include <avr/io.h>
#include <stdint.h>


// Funktion zur Steuerung der Motoren
// speed[-255-255]=Motorgeschwindigkeit/Vorwärts-/Rückwärtsdrehen
int motor(int speed)
{
if (speed<0)
{
PORTC |= ( 1 << PC0 ); // Linksdrehen
PORTC &= ~(1 << PC1);
OCR0 = -speed; // Vergleichswert festlegen=Geschwindigkeit einstellen(0-255)
}

if (speed>=0)
{
PORTC &= ~(1 << PC0); // Rechtsdrehen
PORTC |= ( 1 << PC1 );
OCR0 = speed;
}
}

// PWM initialisieren
int pwm_init(void)
{
DDRC = 0xff;
DDRB = 0xff;
TCCR0 = (0<<WGM01)|(1<<WGM00)|(1<<COM01)|(0<<COM00)|(1<<CS02)|(0<<CS01)|(0<<CS00); // Fast-PWM-Mode, toogle at Top
}


int main(void)
{
pwm_init();
while(1)
{
motor(255);
}
return 0;
}

Was hab ich jetzt noch falsch gemacht?

Bene

//edit:

Jetzt funktioniert es auf einmal, es muss wohl an irgendeinem Wackelkontakt auf dem Steckbrett gelegen haben.

BASTIUniversal
28.10.2007, 12:09
FALSCHES FORUM!

Verschoben!

MfG
Basti