Forum: Mikrocontroller und Digitale Elektronik Attiny Timer1 Soft-PWM


von Jürgen (Gast)


Lesenswert?

Hallo,

ich verscuhe grade auf einem Attiny25 mit dem Timer 1 ein PWM Signal zu 
erzeugen um eine (rote) LED zu dimmen.
Leider blinkt diese nur undefiniert vor sich hin. Es wäre echt klasse, 
wenn sich jemand mal meinen code ansehen könnte, da ich das erste mal 
mit einem Tiny arbeite.
Außerdem wundert es mich, dass ich den code nicht im AVR-Studio 
simulieren kann - warum ist das so ? Mit einem Atmega funktioniert die 
Simulation.
Wenn ich versuche den ATtiny simulieren will, zählt er nicht die 
Timerregister hoch und ich kann die Variablen nciht beobachten.

Hier nun mein code:

[c]#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define rot_an    PORTB |= (1 << PB1)
#define rot_aus    PORTB &= ~(1 << PB1)

// Variablen definieren
volatile uint8_t rot;
volatile uint16_t timer;

uint16_t Helligkeit[64] = {  0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5,
              5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17,
              19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55,
              61, 68, 76, 85, 94, 105, 117, 131, 146, 162,
              181, 202, 225, 250, 279, 311, 346, 386, 430,
              479, 534, 595, 663, 739, 824, 918, 1023};

// ***** Timer1-Overflow-Interrupt ******
ISR (TIMER1_OVF_vect){
// zähle die timer von 0-1023
timer++;
if (timer > 1023) {timer = 0;}
}

// ***** Timer0-Overflow-Interrupt ******
ISR (TIMER0_OVF_vect){
rot++;
if (rot > 63) {rot = 0;}

}

// ***** Hauptprogramm *****
int main(void){

// Variablen setzen
rot = 0;
timer = 0;


// PortB 345 zu Ausgängen und auf 0
DDRB |= (1<<DDB3)|(1<<DDB4)|(1<<DDB1);
PORTB &= ~(1<<PB3)|(1<<PB4)|(1<<PB1);

// Timer 0 konfigurieren: Prescaler 1024
TCCR0B |= (1<<CS00)|(1<<CS02);
// Overflow Interrupt Timer 0 aktivieren
TIMSK |= (1<<TOIE0);

// Timer 1 konfigurieren: Clock = PCK // PCK = 64Mhz -> 64Mhz  256  
1024 = 244,14 Hz
TCCR1 |= (1<<CS10)|(1<<CS12);

//Overflow Interrupt Timer 1 aktivieren
TIMSK |= (1<<TOIE1);

// Global Interrupts aktivieren
sei();

// ***** Endlosschleife *****
while(1){
if (timer < Helligkeit[rot]) {rot_an;}
else {rot_aus;}

} //eof while

} //eof main[\c]

Vielen Dank für eure Mühe!

P.S.: Habe ich das richtig verstanden, dass PCK 64 Mhz beträgt - stimmt 
damit meine PWM-Frequenz ? (also: PCK = 64Mhz -> 64Mhz  256  1024 = 
244,14 Hz)

von Stefan E. (sternst)


Lesenswert?

Jürgen schrieb:
> Habe ich das richtig verstanden, dass PCK 64 Mhz beträgt

Ja.

> stimmt damit meine PWM-Frequenz ?
> (also: PCK = 64Mhz -> 64Mhz  256  1024 = 244,14 Hz)

Nein, weil du
a) nirgendwo PCK als Clock-Source einstellst
und
b) den Prescaler auf 16 einstellst, was in deiner Rechnung ja gar nicht 
vorkommt.

Deine aktuelle PWM-Frequenz ist also eher:
1
8MHz / 16 / 256 / 1024 = 1,9 Hz

von Jürgen (Gast)


Lesenswert?

Danke, ich sehe grade, dass ich mich da vertan habe.

Allerdings stelle ich doch nicht den prescaler auf 16 sondern wähle mit 
der zeile
1
TCCR1 |= (1<<CS10)|(1<<CS12);

CK (ohne Prescaler) ?

Um PCK einzustellen müsste ich nach meinem Verständnis anstatt CS10 und 
CS12 zu setzten nur CS10 setzten - also:
1
TCCR1 |= (1<<CS10);

Allerdings scheint auch dies Vorgehen nicht zu stimmen.
Was mache ich noch falsch?

Grüße
Jürgen

von Jürgen (Gast)


Lesenswert?

Außerdem habe ich noch verscuht mit der codezeile
1
PLLCSR |= (1<<PLLE);

den schnelleren Timertakt freizuschalten.
Allerdings bringt das acuh keine Besserung.
Ich weiss nciht weiter, wäre super, wenn mir jemand helfen könnte.
Danke !

von Stefan E. (sternst)


Lesenswert?

Jürgen schrieb:
> Allerdings stelle ich doch nicht den prescaler auf 16 sondern wähle mit
> der zeile
> TCCR1 |= (1<<CS10)|(1<<CS12);
> CK (ohne Prescaler) ?
>
> Um PCK einzustellen müsste ich nach meinem Verständnis anstatt CS10 und
> CS12 zu setzten nur CS10 setzten - also:
> TCCR1 |= (1<<CS10);

Wenn du den Tiny25 im Tiny15-Mode laufen lässt, dann ja. Hast du den 
Tiny15-Mode ausgewählt? Wenn nein, dann schau dir die richtige Tabelle 
im richtigen Kapitel im Datenblatt an.

Jürgen schrieb:
> Außerdem habe ich noch verscuht mit der codezeile
> PLLCSR |= (1<<PLLE);
> den schnelleren Timertakt freizuschalten.

So einfach geht das auch nicht. Schau nochmal genauer ins Datenblatt. Du 
scheinst diesbezüglich ziemlich schludrig zu sein.

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.