Forum: Mikrocontroller und Digitale Elektronik PWM Frequenz


von Gast (Gast)


Lesenswert?

Hallo,

ich möchte einen kleinen Motor an einem Attiny2313 über ein L293D 
betreiben. Meine Schaltung sowie Programmierung funktioniert auf einem 
Testboard mit einem Atmega32 mit 16 Mhz Quarz.

Allerdings funktioniert der Motor nicht am Attiny (mit internem 
Oszillator). Bei 1 Mhz (also interne 8 Mhz/8), Prescaler 1 und 8-bit PWM 
bekomm ich zumindest den Motor schonmal zum Pfeifen :D.

Weiß jemand da Rat ? Wenn nicht löt ich da nochn 16Mhz Quarz dran, wie 
in der anderen Schaltung.

von STK500-Besitzer (Gast)


Lesenswert?

Wie wäre es, wenn du dein Programm posten würdest?

von Jörg B. (manos)


Lesenswert?

Schon mal die Signale mit einem Oszilloskop angesehen ob es da 
Unterschiede gibt?

von Eckhard (Gast)


Lesenswert?

Hallo,

also bei mehr als ca 5 kHz macht der L293D nicht mehr mit.
Geh mal mit der Frequenz runter und schau ob der Motor dann dreht.

Eckhard

von Gast (Gast)


Lesenswert?

Das ist das Programm:
1
void waitms(uint16_t ms)
2
{
3
  for(; ms>0; ms--)
4
  {
5
    uint16_t __c = 2000;
6
    __asm__ volatile (
7
      "1: sbiw %0,1" "\n\t"
8
      "brne 1b"
9
      : "=w" (__c)
10
      : "0" (__c)
11
    );
12
  }
13
}
14
15
16
17
/*### PWM-Routinen zur Motoransteuerung ###*/
18
19
void init_timer1(void)  //Initialisierung des Timers für Erzeugung des PWM-Signals
20
{
21
   /* normale 8-bit PWM aktivieren (nicht invertiert),
22
   Das Bit WGM10 wird im Datenblatt auch als PWM10 bezeichnet */
23
   TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
24
25
   /* Einstellen der PWM-Frequenz auf 14 kHz ( Prescaler = 1 ) */
26
   TCCR1B = (1<<CS10);
27
28
   /* Interrupts für Timer1 deaktivieren
29
   Achtung : Auch die Interrupts für die anderen Timer stehen in diesem Register */
30
   TIMSK &= ~0x3c;
31
}
32
33
34
35
void setPWMlinks(uint8_t speed) //Geschwindigkeit linker Motor
36
{OCR1AL = speed;}
37
38
39
40
void Mlinkszur(void)  //Uhrzeigersinn
41
{PORTB |= (1<<PB0); PORTB &= ~(1<<PB1);}
42
43
void Mlinksvor(void)  //mathematischer Drehsinn
44
{PORTB &= ~(1<<PB0); PORTB |= (1<<PB1);}
45
46
void Mlinksstop(void)  //aus
47
{ PORTB &= ~(1<<PB0); PORTB &= ~(1<<PB1);}
1
int main (void) {            
2
3
  DDRD |= (1 << PD6);
4
  DDRB |= (1 << PB0)|(1 << PB1)|(1 << PB3);
5
   init_timer1();
6
7
8
while(1)
9
{
10
11
  Mlinksvor();
12
13
  setPWMlinks(0);
14
15
16
  for(uint8_t i=0; i<255; i=i+5)
17
  {
18
    setPWMlinks(i);
19
    waitms(50);
20
  }
21
22
  setPWMlinks(255);
23
24
25
  for(uint8_t i=255; i>0; i=i-5)
26
  {
27
    setPWMlinks(i);
28
    waitms(50);
29
30
  }
31
32
  setPWMlinks(0);
33
34
  Mlinksstop();
35
  waitms(300);
36
37
}
38
    
39
    return 0;
40
   }

Es läuft auf dem Atmega32 mit 16Mhz Quarz. Ich vermute mal die waitms() 
Funktion hat mehr Einfluß auf die PWM Frequenz als ich denke.

Habe alle Prescaler duchprobiert, bei Prescale = 1 pfeift er wie gesagt 
und ansonsten klickt er nur, dreht aber nicht und der Controller 
resettet ständig. Am Mega32 läuft alles rund mit diesen Einstellungen + 
16 Mhz Kristall.

Wie berechnet sich denn die PWM Frequenz ? Quarzfrequenz  Prescale  
8-bit ?

Danke nochmal für eure Hilfe

von Jörg B. (manos)


Lesenswert?

Spontan sehe ich keine Prozessortakt-Anpassung in Deiner Waitms-Routine. 
Es mag ja sein, dass Dein Testboard einen 16 MHz Quarz drauf hatte, aber 
wurde der auch genutzt oder lief auf dem µC evtl. auch nur das interne 
RC-Glied?

Einfach mal beide Signale am Ausgang (Mega und Tiny) mit nem Oscar 
ansehen und schauen wie die Frequenz ist. Gibt auch einige Multimeter 
die Frequenz und PWM messen können.

von Johannes M. (johnny-m)


Lesenswert?

Wenn Du schon mit dem AVR-GCC arbeitest (was ich aus dem syntaktischen 
Zusammenhang mal annehme), warum nutzt Du nicht die _delay_ms-Funktion 
aus der util/delay.h?

von Gast (Gast)


Lesenswert?

Das habe ich überprüft, der Atmega32 nutzt den 16 Mhz. Zieht man den 
Quarz heraus, gibts auch keinen Pieps mehr von sich.

Ich bin leider Einsteige in avr-gcc und klaube mir solangsam das gesamte 
Wissen zusammen. Das Programm oben ist vom RN-Control board aus dem 
roboternetz.de .

Werd mir die _delay_ms Funktion mal anschauen und ein Oscar besorgen :).

Was ich mich noch Frage ist, wie die 14 khz zustande kommen sollen, im 
Obigen Programmiercode. Hat da vielleicht jemand eine Formel zu ?

Hab bisher gerechnet: 16 * 10^6 Mhz geteilt durch Prescaler 1 geteilt 
durch (2*512) ~ 15 khz

Wobei ich die 512 aus dem avr-gcc turorial beziehe:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_PWM-Betriebsart

Die 2 hat dabei aber keinen reellen Hintergrund, die fehlt nur damit das 
Ergebnis stimmt :).

-------

Danke schonmal für eure Hilfe, werd die Ausgänge definitiv mal messen 
müssen. Wenn ihr noch eine Idee habt bzgl. der Berechnung der PWM 
frequenz würd ich mich freuen.

Gruß

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.