Forum: Mikrocontroller und Digitale Elektronik ATTINY84 16-Bit PWM mit wählbarer Frequenz


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Max (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
kann mir jemand weiterhelfen?
Ich versuche auf dem Attiny84 ein PWM-Signal mit einstellbarer Frequenz 
zu erzeugen.
Dazu benutze ich den 8-bit Timer der über Timer Interrupts beim Compare 
Register A einen Port anschaltet und beim Compare Register B wieder aus.
Zusätzlich wird dann noch der Timer zurückgesetzt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
int main(void)
5
{
6
DDRA=0xFF;
7
sei();//enable global interrupts
8
TIMSK0|=(1<<OCIE0A);//enable OCR0A interrupt
9
TIMSK0|=(1<<OCIE0B);//enable OCR0A interrupt
10
//TCCR0B|=(1<<CS00);//no prescaler
11
TCCR0B|=(1<<CS01);//prescaler 8
12
OCR0A=50;//offtime
13
OCR0B=200;//ontime+offtime
14
15
while (1)
16
{
17
}
18
19
}
20
21
ISR(TIM0_COMPA_vect)//compare register A interrupt
22
{
23
PORTA=0xFF;//turn on Port A
24
}
25
26
ISR(TIM0_COMPB_vect)//compare register A interrupt
27
{
28
PORTA=0x00;//Turn off Port A
29
TCNT0=0;//reset Timer 1
30
}

Das funktioniert auch ohne Probleme, jedoch reicht für meine Anwendung 
die Auflösung nicht, weshalb ich jetzt versuche das ganze über den 
16-Bit Timer zu realisieren. Dazu verwende ich einen ähnlichen Code mit 
angepassten Registern.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
int main(void)
5
{
6
7
       DDRA=0xFF;//Port A output
8
9
       OCR1AL=0xFF;//offtime low bit
10
       OCR1AH=0x01;//offtime high bit
11
12
       OCR1BL=0xFF;//ontime+offtime low bit
13
       OCR1BH=0xFF;//ontime+offtime high bit
14
15
       //TCCR1B|=(1<<CS10);//no prescaler
16
       TCCR1B|=(1<<CS11);//prescaler 8
17
18
       TIMSK1|=(1<<OCIE1A);//enable OCR1A interrupt
19
       TIMSK1|=(1<<OCIE1B);//enable OCR1B interrupt
20
21
       sei();//enable global interrupts
22
23
       while (1)//wait
24
       {
25
       }
26
27
}
28
29
ISR(TIM1_COMPA_vect)//compare register A interrupt
30
{
31
       PORTA=0xFF;//turn Port A on
32
}
33
34
ISR(TIM1_COMPB_vect)//compare register B interrupt
35
{
36
       PORTA=0x00;//turn Port A off
37
       cli();//disable global interrupts just to be sure
38
       TCNT1L=0;//reset counter1 low bit
39
       TCNT1H=0;//reset counter1 high bit
40
       sei();//enable global interrupts just to be sure
41
}

Dieser Code funktioniert allerdings nicht. Egal welche Werte ich 
einstelle bekomme ich immer etwa 50% PWM.
Ich vermutete das Problem bei den 16-Bit Vergleichsregistern also lies 
ich mir deren Werte über LEDs ausgeben.
Es scheint, als würden die High Register nicht funktionieren. OCR1AH ist 
immer 0 und OCR1BH ist immer 0b01000011 egal welchen Wert ich in die 
Vergleichsregister schreibe. Die Interrupts werden natürlich auch zum 
falschen Zeitpunkt ausgelöst.

Liebe Grüße und Danke schonmal im Voraus,
Max

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Beim Schreiben von Registern gilt: erst H, dann L, s.a. Datenblatt unter 
'Accessing 16-bit Registers'. Aber in C geht das doch besser ohne H und 
L, um die Reihenfolge kümmert sich der Compiler.

von Jacko (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wenn du nicht den gesamten PortA umschalten musst, geht
das auch automatisch über PortA-5 (OC1B) im fast PWM-Mode 14.

Dann genügt ein Interrupt (T1-Overflow) um die Gesamtperiode
(ICR1) und die aktive Zeit (OCR1B) zu ändern.

Die Polarität für die aktive/nichtaktive Zeit wählst du mit
COM1B1/0.

von Max (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die schnelle Hilfe.
Ich habe jetzt das Register direkt mit einem 16-Bit Wert beschrieben und 
den Compiler die genaue Zuordnung erledigen lassen und es funktioniert 
problemlos.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.