Forum: Mikrocontroller und Digitale Elektronik Timer Tiny25/45


von Harry S. (littlegonzo)


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?
1
void init_timer( void )
2
{
3
//  PLLCSR =(1<<PCKE);
4
  TCCR1 = (1<<CS10)|(1<<CTC1);      // divide by 1
5
  OCR1A = 0;
6
  TCNT1 = -1;
7
  second = 0;
8
  prescaler = 0;
9
10
  TIMSK = 1<<OCIE1A;
11
}

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

von Johann L. (gjlayde) Benutzerseite


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
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define IRQS_PER_SECOND        125
5
#define PRESCALE 8
6
7
static void ioinit(void); 
8
static void timers_init(void);
9
10
// Will be decremented every 8 milliseconds, if not already zero
11
volatile uint8_t count_8ms;
12
13
/*****************************************************************/
14
15
// Initialize Timer0 to make PWM  @ F_CPU/256 i.e. ~ 1kHz
16
// Initialize Timer1 to make IRQs @ 125kHz    i.e. every 8ms
17
void timers_init (void)
18
{
19
    // Timer1 in CTC-Mode and prescaled 8
20
    TCCR1 = (1 << CTC1) | (1 << CS12); 
21
    
22
    // PoutputCompare for desired Timer1 frequency
23
    OCR1C = (uint8_t) ((uint32_t) F_CPU / IRQS_PER_SECOND / PRESCALE -1);
24
    OCR1B = 0;
25
    
26
    // OutputCompare-Interrupt B for Timer 1
27
    TIMSK = (1 << OCIE1B);
28
    
29
    // PWM @ F_CPU/PWM_RESOLUTION at OC0A (PORT_PWM)
30
    TCCR0A = (1 << WGM00) | (1 << COM0A1);
31
    TCCR0B = (0 << CS01) | (1 << CS00); // Prescale = 1
32
}
33
34
/*****************************************************************/
35
36
// This ISR executes every 8 ms 
37
// and decrements `count_8ms' if it is not already zero
38
SIGNAL (SIG_OUTPUT_COMPARE1B)
39
{
40
    uint8_t val = count_8ms;
41
        
42
    if (val)
43
        count_8ms = val-1;
44
}

von Harry S. (littlegonzo)


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.

von Anon Y. (avion23)


Lesenswert?

Hier mal Code wie ich es gemacht habe. Mit der Methode komme ich 
übrigens gut voran:
1
void initTimer1(void){
2
  //cs13:cs10 = 0010 for 125kHz
3
  //cs13:cs10 = 0001 for 250kHz
4
  //cs13:cs10 = 0000 for disabled pwm
5
  //TCCR1 |= (1<<CTC1);    // Clear timer/counter on compare match
6
  TCCR1 |= (1<<PWM1A);    // Pulse width modulator A enable
7
  TCCR1 |= (1<<COM1A1);    // comparator A mode select
8
  //TCCR1 |= (1<<COM1A0);    // OC1x cleared on compare match. Set when TCNT1 = $00.
9
                // OC1x not connected.
10
  //TCCR1 |= (1<<CS13);      // clock select, prescaler
11
  //TCCR1 |= (1<<CS12);
12
  //TCCR1 |= (1<<CS11);
13
  TCCR1 |= (1<<CS10);
14
15
  //GTCCR = 0;
16
  //GTCCR |= (1<<PWM1B);      // enable PWM B
17
  //GTTCR |= (1<<COM1B1);      // comparator B mode select
18
  //GTTCR |= (1<<COM1B0);
19
  //GTTCR |= (1<<FOC1B);    // force output compare match
20
  //GTTCR |= (1<<FOC1A);    // force output compare match
21
  //GTTCR |= (1<<PSR1);      // Reset the prescaler
22
23
  OCR1A = 0;
24
  OCR1B = 0;
25
  OCR1C = 255;        // maximum value for pwm
26
  //TIMSK |= (1<<OCIE1A);    // Output compare match a interrupt enable
27
  PLLCSR |= (1<<PLLE);    // enable PLL before enabling it as source for timer1
28
  _delay_us(100);        // wait 100us for pll to stabilize
29
  //PLLCSR |= (1<<LSM);     // low speed mode
30
31
  // lock detection
32
  // Blocks until lock is detected, i.e. PLOCK = 1
33
  while(!(PLLCSR & (1<<PLOCK)))
34
      ;
35
36
  PLLCSR |= (1<<PCKE);    // enable PLL as timer1 clock source
37
38
  // init dead times
39
  //DTPS1 |= (1<<DTPS11);       // dead time prescaler
40
  //DTPS1 |= (1<<DTPS10);      // 00 = 1, 11 = 8
41
/*
42
  // amount of dead cycles coded in binary
43
  DT1A |= (1<<DT1AH3);
44
  DT1A |= (1<<DT1AH2);
45
  DT1A |= (1<<DT1AH1);
46
  DT1A |= (1<<DT1AH0);
47
  DT1A |= (1<<DT1AL3);
48
  DT1A |= (1<<DT1AL2);
49
  DT1A |= (1<<DT1AL1);
50
  DT1A |= (1<<DT1AL0);
51
*/
52
}
Und noch für timer0, weil der einfacher ist:
1
// for 10ms ISR
2
void initTimer0(void){
3
4
  // Timer/Counter Interrupt Mask Register
5
  TIMSK |= (1<<OCIE0A);    // Output compare match a interrupt enable
6
  //TIMSK |= (1<<OCIE0B);
7
  //TIMSK |= (1<<TOIE0);    // Timer0 overflow interrupt enable
8
9
10
11
  // TCCR0A Register. Sets PWM Mode and Waveform
12
  //� Bit 7:6 � COMnA1:0: Compare Output Mode for Channel A
13
  //� Bit 5:4 � COMnB1:0: Compare Output Mode for Channel B
14
  TCCR0A = 0;
15
  // none set means normal pin functionality
16
//  TCCR0A |= (1<<COM0A1);   // Channel A compare mode
17
//  TCCR0A |= (1<<COM0A0);
18
  // 10 means clear on compare match, set at bottom
19
  // 11 means inverted mode, clear at bottom
20
  TCCR0A |= (1<<COM0B1);  // Channel B compare mode
21
  TCCR0A |= (1<<COM0B0);
22
23
  // WGM = 011 fast pwm
24
  TCCR0A |= (1<<WGM01);
25
  TCCR0A |= (1<<WGM00);
26
27
28
  // Initialization of TCCR0B. This sets Waveform, Clock and Noise canceler
29
  TCCR0B = 0;
30
  //TCCR0B |= (1 << WGM02);
31
32
  // CS = 011 = 1/64
33
  //TCCR0B |= (1 << CS12);      // Clock select - see datasheet, table 62
34
  TCCR0B |= (1 << CS11);      // Bits don't represent a rightshift by 2!
35
  TCCR0B |= (1 << CS10);      // prescaler here is 64
36
37
  OCR0A = 156;
38
}
Immer her mit der Kritik :)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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

Johann

von Harry S. (littlegonzo)


Lesenswert?

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