Forum: Mikrocontroller und Digitale Elektronik Atmel328p: warum funktioniert dieser Code nicht?


von Enno M. (mcenno)


Lesenswert?

Hallo,


ich versuche, mit einem Atmel328p eine PWM mit mehr als 8 Bit zu 
erzeugen. Als Ausgangspunkt habe ich Code von 
http://www.embedds.com/programming-16-bit-timer-on-atmega328 kopiert und 
hochgeladen - funktioniert:
1
#include <avr/io.h>
2
void InitPort(void)
3
{
4
//Init PB1/OC1A and PB2/OC1B pins as output
5
DDRB|=(1<<PB1)|(1<<PB2);
6
}
7
void InitTimer1(void)
8
{
9
//Set Initial Timer value
10
TCNT1=0;
11
//set non inverted PWM on OC1A pin
12
//and inverted on OC1B
13
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0);
14
//set top value to ICR1
15
ICR1=0x00FF;
16
//set corrcet phase and frequency PWM mode
17
TCCR1B|=(1<<WGM13);
18
//set compare values
19
OCR1A=0x0064;
20
OCR1B=0x0096;
21
}
22
void StartTimer1(void)
23
{
24
//Start timer with prescaller 64
25
TCCR1B|=(1<<CS11)|(1<<CS10);
26
}
27
int main(void)
28
{
29
InitPort();
30
InitTimer1();
31
StartTimer1();
32
    while(1)
33
    {
34
        //do nothing
35
    }
36
}

Danach habe ich versucht, das ganze in die mir bekannte Struktur von 
setup()- und loop()-Funktionen zu schreiben, was aber dann nicht mehr 
funktioniert:
1
void setup(){
2
3
  //Init PB1/OC1A and PB2/OC1B pins as output
4
  DDRB|=(1<<PB1)|(1<<PB2);
5
  
6
  //Set Initial Timer value
7
  TCNT1=0;
8
  //set non inverted PWM on OC1A pin
9
  //and inverted on OC1B
10
  TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0);
11
  //set top value to ICR1
12
  ICR1=0x00FF;
13
  //set corrcet phase and frequency PWM mode
14
  TCCR1B|=(1<<WGM13);
15
  //set compare values
16
  OCR1A=0x0064;
17
  OCR1B=0x0096;
18
19
  //Start timer with prescaller 64
20
  TCCR1B|=(1<<CS11)|(1<<CS10);
21
22
}
23
24
void loop(){
25
}

Alles wird artig kompiliert und hochgeladen, aber es kommt kein 
PWM-Signal aus dem entsprechenden Pin.

Warum nicht? Andere Programme, die setup() und loop() enthalten, und die 
ich per make kompiliere, laufen doch auch.

Das Makefile enthält

BOARD_TAG    = nano
include ../Arduino.mk


Enno


PS: Ok, das wäre ein guter Punkt, das Arduino-Gedöns hinter sich zu 
lassen, aber trotzdem möchte ich gerne verstehen, was da passiert.

von Peter II (Gast)


Lesenswert?

eventuell verwendet ja das  Arduino-Gedöns den Timer intern ohne das du 
es sieht?

von Philipp K. (philipp_k59)


Lesenswert?

Vielleicht Pinmode setzen..wobei das konfiguriere öfter schiefgeht.

von S. Landolt (Gast)


Lesenswert?

Wie schon öfter in letzter Zeit: es könnte sein, dass das 
"Arduino-Gedöns" die Timer-SFRs vorbesetzt hat, und dann ist es eine 
ganz schlechte Idee, diese per OR ("|=") initialisieren zu wollen.

von Philipp K. (philipp_k59)


Lesenswert?


von Enno M. (mcenno)


Lesenswert?

Ok, danke an alle. Ich werde in der Richtung weiter suchen.


Gruß,

Enno

von U. C. (Gast)


Lesenswert?

S. Landolt schrieb:
> und dann ist es eine
> ganz schlechte Idee, diese per OR ("|=") initialisieren zu wollen.

Gerade beide Varianten mit der Arduino IDE getestet:
Dem ist so!

von Michael U. (amiga)


Lesenswert?

Hallo,

ich sage es mal so: wenn man eigenen Code auf unterster Ebene mit dem 
"Arduino-Gedöns" kombinieren will, wird man nicht umhin kommen, das 
Umfeld des "Arduino-Gedöns" einzuplanen.

Die Informationen dazu sind meiner Meinung nach schön im Web verstreut 
unbd teilweise schwer zu finden. Manchmal hilft dann nur der Blick in 
den Source des "Arduino-Gedöns".

Ds war eben ursprünglich nicht die Zielgruppe von Arduino.

PS: ich halte es nicht für "Gedöns", es ist nur etwas anders. Letztlich 
es es auch nur ein GCC, etliche eigene Klassen und Makros un ein 
Preprozessor, der ein paar Sachen etwas anders macht, wenn er "Arduino" 
sieht.

Ohne benimmt er sich nicht anders als wennd er Code im AVR-Studio o.ä. 
mit dem GCC compiliert wird, sonst hätte sein erster Versuch nicht 
geklappt.

Gruß aus Berlin
Michael

von Enno M. (mcenno)


Lesenswert?

Hallo,

Michael U. schrieb:
> ich sage es mal so: wenn man eigenen Code auf unterster Ebene mit dem
> "Arduino-Gedöns" kombinieren will, wird man nicht umhin kommen, das
> Umfeld des "Arduino-Gedöns" einzuplanen.
>
> Die Informationen dazu sind meiner Meinung nach schön im Web verstreut
> unbd teilweise schwer zu finden. Manchmal hilft dann nur der Blick in
> den Source des "Arduino-Gedöns".
>
> Ds war eben ursprünglich nicht die Zielgruppe von Arduino.

Ja, das ist mir bewusst. Da ich aber eben mit dem Arduino-Umfeld 
begonnen habe, tauchen bei meinem Umstieg (bzw langsamen Übergang) eben 
solche Effekte auf.

For the record: die folgenden zwei Zeilen am Anfang von setup() haben 
meinen Code dann lauffähig gemacht:

  // clear whatever Arduino libs have set this to
  TCCR1A=0x0000;
  TCCR1B=0x0000;


Vielen Dank für Deine Antwort,

Enno

von S. Landolt (Gast)


Lesenswert?

Warum schreiben Sie nicht gleich

 TCCR1A=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0);
 TCCR1B=(1<<WGM13);
?
Wer hat bloß diesen Unsinn mit dem 'oder' bei der Erstzuweisung 
aufgebracht.

von Du, Du liegst mir im Herzen (Gast)


Lesenswert?

S. Landolt schrieb:
> Warum schreiben Sie nicht gleich....

Wer hat bloß diesen Unsinn mit dem "Sie" bei der Erst-Zurechtweisung 
aufgebracht?

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.