Forum: Mikrocontroller und Digitale Elektronik PWM Attiny trotz verschiedener Vergleichswerte Frequenz konstant


von Ralf G. (sense)


Lesenswert?

Ich versuche mir mit einem ATtiny2313 mir einen PWM-Controller zu 
basteln, der via uart steuerbar ist.
Der Befehl zum Steuern soll so aussehen:
1.Byte 0xFF
2.Byte 0xEE
3-6. Byte jeweils das Byte für OCR0A, OCR0B, OCR1A und OCR1B

Allerdings hab ich jetzt, dass Problem das alle 4 LEDS, die an OC0A - 
OC1B hängen, konstant gleich leuchten. Auf den jeweiligen Pins messe ich 
mit meinem Multimeter eine Frequenz von ca. 225Hz. Ich initialisiere 
aber im Controller die Timer und setze jeweils einen anderen 
Vergleichswert, somit dürfte nicht bei allen 4 die gleiche Frequenz 
messen. Daher die Frage wo liegt mein Fehler ?
Hier mein Quelltext. Die UART-Lib ist von Peter Fleury. Quarzfrequenz 
ist 3,6864 Mhz.
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include"uart.h"
4
#ifndef F_CPU
5
#define F_CPU 3686400UL
6
#endif
7
8
#define UART_BAUD_RATE      38400
9
#define RX_BUFFER_SIZE  4
10
volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
11
void init_pwm (void)
12
{  
13
  
14
  // Timer 0 PWM Init
15
16
  TCCR0A = (1 << WGM00)
17
       | (1 << WGM01)
18
     | (1 << COM0A1)
19
     | (1 << COM0B1);
20
  TCCR0B = (1 << CS00)
21
     | (1 << CS01);
22
23
24
  // OC0A PWM Port
25
26
  DDRB   |= (1 << PB2);
27
28
  OCR0A = 16;
29
30
31
  // OC0B PWM Port
32
  
33
  DDRD   |= (1 << PD5);
34
35
  OCR0B = 32;
36
  
37
38
  // Timer 1 PWM Init
39
40
  TCCR1A = (1 << WGM10)
41
     | (1 << COM1A1)
42
     | (1 << COM1B1);
43
  TCCR1B = (1 << WGM12)
44
     | (1 << CS10)
45
     | (1 << CS11);
46
47
48
  // OC1A PWM Port
49
50
  DDRB   |= (1 << PB3);
51
       
52
  OCR1A = 64;
53
54
55
  // OC1B PWM Port
56
57
  DDRB   |= (1 << PB4);
58
       
59
  OCR1B = 128;
60
61
}
62
int main(void)
63
{
64
  init_pwm();
65
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
66
  sei();
67
  while(1)
68
  {
69
    while(uart_getc()!=0xFF)
70
    {uart_putc('w');}
71
    if(uart_getc() == 0xEE)
72
    {
73
      for(uint8_t get= 0; get < RX_BUFFER_SIZE;get++)
74
      {
75
        rx_buffer[get] = uart_getc();
76
      }
77
      OCR0A = rx_buffer[0];
78
      OCR0B = rx_buffer[1];
79
      OCR1A = rx_buffer[2];
80
      OCR1B = rx_buffer[3];
81
      uart_puts("read\n");
82
    }
83
84
  }
85
}

von holger (Gast)


Lesenswert?

>        rx_buffer[get] = uart_getc();

uart_getc() wartet nicht bis etwas empfangen wurde.
Deshalb bekommst du für alle LEDs den gleichen Wert.

von Ralf G. (sense)


Lesenswert?

Okay, das wäre eine Erklärung warum das mit den Befehlen nicht 
funktioniert. Ich hatte allerdings schon mal alles in der while(1){} 
auskommentiert und hatte wieder überall die selbe Frequenz. Mir leuchtet 
nur nicht ein warum.

von spess53 (Gast)


Lesenswert?

Hi

Außerdem wird bei PWM nicht die Frequenz, sondern das Tastverhältnis 
verändert.

MfG Spess

von Hc Z. (mizch)


Lesenswert?

> hatte wieder überall die selbe Frequenz

Dir ist aber schon klar, dass bei PWM sich die Frequenz nicht ändert?

von holger (Gast)


Lesenswert?

>und hatte wieder überall die selbe Frequenz. Mir leuchtet
>nur nicht ein warum.

Weil PWM nicht die Frequenz verstellt, sondern das Tastverhältnis.

von Ralf G. (sense)


Lesenswert?

Okay, dann war das ein Denkfehler meinerseits sorry. Letztendlich 
leuchten die 4 LEDS aber konstant, die müssten aber ja nach init_pwm() 
verschieden hell leuchten oder steh ich jetzt völlig am Schlauch ?

von Hc Z. (mizch)


Lesenswert?

Als Nächstes würde ich prüfen, ob die CPU überhaupt an der Stelle 
vorbeikommt, an der die OCRs gesetzt werden (LED toggeln o.ä.).

Ich würde darauf tippen, dass sie nie dort vorbeikommt.  Denn (wenn 
uart_getc()) sofort zurückkehrt, auch wenn kein Zeichen verfügbar ist) 
zwischen den einzelnen Zeichen wird immer eine Pause sein müssen, so 
dass nie 2 gültige Zeichen in zwei direkt aufeinanderfolgenden Aufrufen 
von uart_getc() gemeldet werden können.

Also scheitert's schon an der Präambel: nach FF kommt „kein Zeichen“ und 
nicht EE (und zwar mindestens 1/4 ms lang bei 38.4 kBd)-- und schon geht 
es von vorne mit Warten auf FF los.

P.S. Ich halte FF für eine schlechtes Einleitungszeichen - ein einziger 
Störimpuls, der gerade lang genug ist, dass er als gültiges Startbit 
erkannt wird, erzeugt genau das.

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.