www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer Tiny25/45


Autor: Harry S. (littlegonzo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich bekomme es nicht gebacken. Möchte die 1-Wire Routine von Peter auf 
einen ATTiny25 portieren (ohne Serial unterstützung) aber scheitere 
schon am Timer1 vom Tiny. Er läuft einfach nicht los..
Bisher habe ich folgendes, wo steckt mein Fehler?
void init_timer( void )
{
//  PLLCSR =(1<<PCKE);
  TCCR1 = (1<<CS10)|(1<<CTC1);      // divide by 1
  OCR1A = 0;
  TCNT1 = -1;
  second = 0;
  prescaler = 0;

  TIMSK = 1<<OCIE1A;
}

Ich dachte immer wenn der Teiler >0 dann rennt der Timer los...nix tut 
sich.
Zumindest in AVR Studio. Wenn ich die Original-Routine nehme (Mega8) 
rennt er sofort los und zählt. Das mit PLLCSR war nur ein versuch, ich 
weiß das man damit die Taktquelle umschaltet...

Gruß
Harry

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Harry S. schrieb:
> Hallo Leute,
> ich bekomme es nicht gebacken. Möchte die 1-Wire Routine von Peter auf
> einen ATTiny25 portieren (ohne Serial unterstützung) aber scheitere
> schon am Timer1 vom Tiny. Er läuft einfach nicht los..
> Bisher habe ich folgendes, wo steckt mein Fehler?
Sieht so als, als wolltestdu für einen ATmega8 oder so initialisieren...

Hier mal kommentarlos ein ATtiny25-Schnippel
#include <avr/io.h>
#include <avr/interrupt.h>

#define IRQS_PER_SECOND        125
#define PRESCALE 8

static void ioinit(void); 
static void timers_init(void);

// Will be decremented every 8 milliseconds, if not already zero
volatile uint8_t count_8ms;

/*****************************************************************/

// Initialize Timer0 to make PWM  @ F_CPU/256 i.e. ~ 1kHz
// Initialize Timer1 to make IRQs @ 125kHz    i.e. every 8ms
void timers_init (void)
{
    // Timer1 in CTC-Mode and prescaled 8
    TCCR1 = (1 << CTC1) | (1 << CS12); 
    
    // PoutputCompare for desired Timer1 frequency
    OCR1C = (uint8_t) ((uint32_t) F_CPU / IRQS_PER_SECOND / PRESCALE -1);
    OCR1B = 0;
    
    // OutputCompare-Interrupt B for Timer 1
    TIMSK = (1 << OCIE1B);
    
    // PWM @ F_CPU/PWM_RESOLUTION at OC0A (PORT_PWM)
    TCCR0A = (1 << WGM00) | (1 << COM0A1);
    TCCR0B = (0 << CS01) | (1 << CS00); // Prescale = 1
}

/*****************************************************************/

// This ISR executes every 8 ms 
// and decrements `count_8ms' if it is not already zero
SIGNAL (SIG_OUTPUT_COMPARE1B)
{
    uint8_t val = count_8ms;
        
    if (val)
        count_8ms = val-1;
} 

Autor: Harry S. (littlegonzo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super vielen Dank, ging ja fix.
Sind also noch diverse andere Einstellungen nötig.... Das mag ich an den 
Atmel Datenblättern, man ist nur am hin und herspringen um sich die 
Daten rauszusuchen um 1 Funktion zu nutzen, grr.

Autor: Anon Ymous (avion23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal Code wie ich es gemacht habe. Mit der Methode komme ich 
übrigens gut voran:
void initTimer1(void){
  //cs13:cs10 = 0010 for 125kHz
  //cs13:cs10 = 0001 for 250kHz
  //cs13:cs10 = 0000 for disabled pwm
  //TCCR1 |= (1<<CTC1);    // Clear timer/counter on compare match
  TCCR1 |= (1<<PWM1A);    // Pulse width modulator A enable
  TCCR1 |= (1<<COM1A1);    // comparator A mode select
  //TCCR1 |= (1<<COM1A0);    // OC1x cleared on compare match. Set when TCNT1 = $00.
                // OC1x not connected.
  //TCCR1 |= (1<<CS13);      // clock select, prescaler
  //TCCR1 |= (1<<CS12);
  //TCCR1 |= (1<<CS11);
  TCCR1 |= (1<<CS10);

  //GTCCR = 0;
  //GTCCR |= (1<<PWM1B);      // enable PWM B
  //GTTCR |= (1<<COM1B1);      // comparator B mode select
  //GTTCR |= (1<<COM1B0);
  //GTTCR |= (1<<FOC1B);    // force output compare match
  //GTTCR |= (1<<FOC1A);    // force output compare match
  //GTTCR |= (1<<PSR1);      // Reset the prescaler

  OCR1A = 0;
  OCR1B = 0;
  OCR1C = 255;        // maximum value for pwm
  //TIMSK |= (1<<OCIE1A);    // Output compare match a interrupt enable
  PLLCSR |= (1<<PLLE);    // enable PLL before enabling it as source for timer1
  _delay_us(100);        // wait 100us for pll to stabilize
  //PLLCSR |= (1<<LSM);     // low speed mode

  // lock detection
  // Blocks until lock is detected, i.e. PLOCK = 1
  while(!(PLLCSR & (1<<PLOCK)))
      ;

  PLLCSR |= (1<<PCKE);    // enable PLL as timer1 clock source

  // init dead times
  //DTPS1 |= (1<<DTPS11);       // dead time prescaler
  //DTPS1 |= (1<<DTPS10);      // 00 = 1, 11 = 8
/*
  // amount of dead cycles coded in binary
  DT1A |= (1<<DT1AH3);
  DT1A |= (1<<DT1AH2);
  DT1A |= (1<<DT1AH1);
  DT1A |= (1<<DT1AH0);
  DT1A |= (1<<DT1AL3);
  DT1A |= (1<<DT1AL2);
  DT1A |= (1<<DT1AL1);
  DT1A |= (1<<DT1AL0);
*/
}
Und noch für timer0, weil der einfacher ist:
// for 10ms ISR
void initTimer0(void){

  // Timer/Counter Interrupt Mask Register
  TIMSK |= (1<<OCIE0A);    // Output compare match a interrupt enable
  //TIMSK |= (1<<OCIE0B);
  //TIMSK |= (1<<TOIE0);    // Timer0 overflow interrupt enable



  // TCCR0A Register. Sets PWM Mode and Waveform
  //� Bit 7:6 � COMnA1:0: Compare Output Mode for Channel A
  //� Bit 5:4 � COMnB1:0: Compare Output Mode for Channel B
  TCCR0A = 0;
  // none set means normal pin functionality
//  TCCR0A |= (1<<COM0A1);   // Channel A compare mode
//  TCCR0A |= (1<<COM0A0);
  // 10 means clear on compare match, set at bottom
  // 11 means inverted mode, clear at bottom
  TCCR0A |= (1<<COM0B1);  // Channel B compare mode
  TCCR0A |= (1<<COM0B0);

  // WGM = 011 fast pwm
  TCCR0A |= (1<<WGM01);
  TCCR0A |= (1<<WGM00);


  // Initialization of TCCR0B. This sets Waveform, Clock and Noise canceler
  TCCR0B = 0;
  //TCCR0B |= (1 << WGM02);

  // CS = 011 = 1/64
  //TCCR0B |= (1 << CS12);      // Clock select - see datasheet, table 62
  TCCR0B |= (1 << CS11);      // Bits don't represent a rightshift by 2!
  TCCR0B |= (1 << CS10);      // prescaler here is 64

  OCR0A = 156;
}
Immer her mit der Kritik :)

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum interrupten reicht das aber alles noch nicht. Iregdwo muss auch ein
sei();
stehen ;-)

Johann

Autor: Harry S. (littlegonzo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, wow, gleich soviel. Der Code von Anon läuft direkt. Nutze jetzt 
Timer0 scheint einfacher 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.