Forum: Mikrocontroller und Digitale Elektronik Motoren mit ATmega8 ansteuern


von Thomas (Gast)


Lesenswert?

Morgen,
hab mal ein Programm für eine ansteuerung eines Motors 
geschrieben(unten).möchte jetzt nochmal einen zweiten Motor darüber 
laufen lassen.bin mir aber nicht ganz sicher ob der ATmega8 2 
PWM-Signale ausgeben kann und weiß nicht wie ich das Programm ändern 
soll damit beide darüber laufen??

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

void adc_init(void)
{
  ADMUX = 0;
  ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS0);
}
void timer_init(void)
{
  DDRB = (1 << PB1 );

  TCCR1A = (1<<COM1A1) | (1<<WGM11);
  TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);

  ICR1 = 0x0080;
}

int main()
{
  uint16_t buffer;

  timer_init();                      // Timer initialisieren

  adc_init();                        // A/D - Wandler initialisieren

  OCR1A = 0x0000;
  /*
    Compare Wert
    Wenn der Zähler diesen Wert erreicht, wird mit
    obiger Konfiguration der OC1A Ausgang abgeschaltet
    Sobald der Zähler wieder bei 0 startet, wird der
     Ausgang wieder auf 1 gesetzt
  */

  while( 1 )
  {
  ADCSRA |=(1<<ADSC);

  while ( !(ADCSRA & (1<<ADIF)) )
          ;

    Buffer=ADC;
OCR1A=(buffer>>3) ;                  // PWM Auflösung von 10bit auf 8bit 
transformieren,
                              // da buffer_Register 10bit groß ist

   }
}

von Jasson J. (jasson)


Lesenswert?

Hi,

ja der Mega8 kann zwei PWM über Timer1 ausgeben und ein weiteres über 
Timer2. Eigentlich hast du die Lösung auch schon gebaut. Dein Timer 
läuft ja schon im Modus 14,also mit ICR als TOP, welches du ja auch 
richtig geladen hast.
Eigentlich müsste es von alleine gehen, wenn du im DDRB mit dem 
Bitmuster 0b0110000 lädst und neben OCR1A auch OCR1B mit Werten lädst.
Und natürlich das Bit "COM1B1" nicht vergessen zu setzten.

Nehms mir nicht übel, wenn ich frage. Du fängst gerade an, oder? Ohne 
implzieren zu wollen, dass es für deine Anwendung besser ist (die ich ja 
auch gar nicht kenne) kann man auch sog. "Software PWM" auf Basis einer 
Compare Match Interrupt Servcie Routine (ISR) machen.

Nachteil: verbraucht CPU Zeit
Vorteil: man kann viel mehr als 2 oder 3 PWM erzeugen. (wenn man´s denn 
braucht)

von Thomas (Gast)


Lesenswert?

Vielen Dank für die schnelle Antwort.
Ja ich bin gerade am Anfang in der c-programmierung!
hab jetzt alles soweit geändert,außer DDRB. Soll ich da anstelle von 
DDRB = (1 << PB1 ); einfach DDRB = 0xb0110000; schreiben?? wie gesagt 
ich bin Anfänger!!

von Thomas (Gast)


Lesenswert?

und was bedeutet das b in 0b0110000??

von Baron (Gast)


Lesenswert?

Byteschreibweise?!

von M. K. (sylaina)


Lesenswert?

Thomas schrieb:
> und was bedeutet das b in 0b0110000??

0b... bedeutet für den Compiler, dass die nachfolgende Ziffernfolge eine 
binäre Zahl ist.

Eine Zahl mit führender 0 sagt dem Compiler, dass diese Zahl eine oktale 
Zahl ist.

Grundlagen C.

von Thomas (Gast)


Lesenswert?

Das mit dem DDRB hab ich jetzt realisiert! nun muss ich doch auch noch 
das ADMUX Register verändern damit ich einen Motor über PC0 und den 
anderen über PC1 steuern kann??

von PICfan (Gast)


Lesenswert?

Thomas schrieb:
> Soll ich da anstelle von
> DDRB = (1 << PB1 ); einfach DDRB = 0xb0110000; schreiben??

fast.

0x ist für hex zahlen
0b ist für binär zahlen (und nicht 0xb wie oben)
   >> beachte:  msb zuerst (bit7,bit6,...,bit0)
dezimal zahlen kann mann ohne vorzeichen schreiben.

Also richtig wäre z.B.:

DDRB = 0b00110000;  // (setzt bits 4 und 5, sonst alle 0)

von Thomas (Gast)


Lesenswert?

Danke für die schnelle Antwort.habe dies eben auch gefunden.bleibt 
immernoch folgende Frage:
nun muss ich doch auch noch das ADMUX Register verändern damit ich einen 
Motor über PC0 und den anderen über PC1 steuern kann??

von Walter S. (avatar)


Lesenswert?

was bedeutet wohl ADMUX,

ich sage Mal du hast Null Ahnung,
das ist erst Mal noch kein Problem.
Aber Du solltest dir erst Mal ein paar Grundlagen erarbeiten bevor du 
andere für dich arbeiten lässt,
das hilft dir indem du wirklich was lernst und den anderen stiehlst du 
nicht die Zeit

von Karl H. (kbuchegg)


Lesenswert?

Thomas schrieb:

> nun muss ich doch auch noch das ADMUX Register verändern damit ich einen
> Motor über PC0 und den anderen über PC1 steuern kann??

In Ergänzung zu dem was Walter gesagt hat.

Vor allen Dingen musst du anfangen die Dinge zu trennen.
Auf der einen Seite sind deine beiden Motoren
Die werden durch jeweils eine PWM angesteuert.

Auf der anderen Seite ist die Fragestellung: Wo kommt die Vorgabe für 
die PWM her?

Bei dir ist es offenbar so, dass du jeden Motor mit einem Poti, und 
damit mit einem ADC Eingang ansteuern möchtest.

Das sind aber trotzdem 2 verschiedene Paar Schuhe, die erst mal nichts 
miteinander zu tun haben. Denn das muss ja nicht so sein. Die beiden PWM 
könnten unabhängig voneinander ja auch zb durch SChalter eingestellt 
werden oder durch Lichtschranken oder was auch immer.

D.h. du hast in deinem Programm erst mal 2 voneinander getrennte 
Fragestellungen:

 wie kann ich 2 ADC Kanäle einlesen

 wie kann ich 2 PWM Ausgänge realisieren

Und erst dann, wenn beide Fragestellungen unabhängig voneinander gelöst 
sind, dann werden sie insofern verknüpft, dass der eine ADC Wert die 
eine PWM ansteuert und der andere die andere.


Für den ADC findest du im AVR-GCC-Tutorial genügend Material (und auch 
Funktionen) die mehrere ADC Kanäle (hintereinander) auslesen können.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.