www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Attiny Timer1 Soft-PWM


Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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:
8MHz / 16 / 256 / 1024 = 1,9 Hz 

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
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);

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

Grüße
Jürgen

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Außerdem habe ich noch verscuht mit der codezeile
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 !

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.