Arduino Nano fast PWM mit Registern

OP #5538301
Lesenswert?

Hi,

Ich habe mich schon eine Weile nicht mehr mit einem AVR befasst und nun 
möchte ich gerne fast PWM mit 2s periode implementieren auf einem 
ATmega328a (Arduino Nano). Also habe ich den Timer 1 genommen (16 bit) 
und mal was gemacht, jedoch scheint der irgendwie nicht 16 bit zu sein, 
sondern nur 8 bit. Sobald ich OCR1A > 0xFF wähle passiert nichts mehr. 
Jemand eine Idee, warum der Timer 1 sich hier nur wie ein 8 bit Timer 
verhält?

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

Klappt:
1
  DDRB |= (1 << DDB1); //PB1 = PIN9 = OUTPUT
2

3
  ICR1 = 0x00FF;
4
    
5
  OCR1AL = (0x007F & 0xFF);
6
  OCR1AH = (0x007F>>8);
7
  
8
  TCCR1A=(1<<COM1A1) | (1<<WGM11);  //Fast PWM with ICR1 as TOP
9
  TCCR1B=(1<<WGM12) | (1<<WGM13) | (1<<CS12) | (1<<CS10); //1024 prescaler

Klappt nicht (bleibt nach einmal toggeln auf HIGH):
1
  DDRB |= (1 << DDB1); //PB1 = PIN9 = OUTPUT
2

3
  ICR1 = 0x79F4; //2000ms period
4
    
5
  OCR1AL = (0x3CFA & 0xFF);
6
  OCR1AH = (0x3CFA>>8);
7
  
8
  TCCR1A=(1<<COM1A1) | (1<<WGM11);  //Fast PWM with ICR1 as TOP
9
  TCCR1B=(1<<WGM12) | (1<<WGM13) | (1<<CS12) | (1<<CS10); //1024 prescaler
OP #5538454
Lesenswert?

Marc V. schrieb:
> Marc V. schrieb:
> High Byte muss zuerst geschrieben werden, kein Wunder dass es nicht
>  funktioniert.
>
>  Probiere es mal mit:  OCR1A = 0x3CFA;

Funktioniert leider auch nicht. Das Schreiben vom High Byte zuerst 
spielt hier auch keine Rolle, da der Duty nur einmal vor dem Starten des 
Timers gesetzt wird.

Timer 1 sollte auch beim Arduino unbenutzt sein, so wie ich das sehe, 
daher macht mir das noch wenig sinn.

AlterHase schrieb:
> Welches Register definiert den TOP (also Höchstwert, den der Timer
> annimmt? ICR1 oder OCR1A)? Und welches Register (ICR1 oder OCR1A) stellt
> das Tastverhältnis ein?

Top wird durch ICR1 definiert und Ouput Compare durch OCR1A.

Top schent auch zu gehen, zumindest kommt manchmal wie berechnet ein 
Puls alle 2s, jedoch ist der Duty nie grösser als durch einen 8bit timer 
definiert und nur die Periode nimmt den 16bit Wert an.
#5538820
Lesenswert?

Bert S. schrieb:
>
1
>   OCR1AL = (0x007F & 0xFF);
2
>   OCR1AH = (0x007F>>8);
3
> ... 
4
>   OCR1AL = (0x3CFA & 0xFF);
5
>   OCR1AH = (0x3CFA>>8);

Was soll der Schwachsinn, H- und L-Byte eines 16-Bit Hardware-Registers 
in einem C(!) Programm separat zu beschreiben?

Marc V. schrieb:
> High Byte muss zuerst geschrieben werden, kein Wunder dass es nicht
> funktioniert.

Programmierer mit mehr als einer Hirnzelle überlassen solche Details dem 
Compiler. Wozu hat man denn Abstraktionen wie Datentypen breiter als die 
ALU oder 16-bittige Register, wenn man sie nicht nutzt?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren