10-bit-counter attiny 261/461/861

#3842618
Lesenswert?

Hi,

laut Datenblatt sollte der attiny861 einen 10bit-Timer/Counter1 haben. 
Nur bekomme ich ihn beim besten Willen nicht dazu, weiter als bis 255 zu 
zählen.

Ich habe den Code zu Testzwecken komplett abgespeckt, eigentlich zähle 
ich nur noch (langsam) und gebe den Wert aus:
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include "lcd.h"
5

6
int main (void) {
7
    char buf[9];
8
    // slow down
9
    CLKPR = (1<<CLKPCE);
10
    CLKPR =  (1<<CLKPS1)| (1<<CLKPS1);
11

12
    TC1H = 0x01;
13
    TCNT1 = 0xFF;
14
    TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12)|(1<<CS13); // prescale 16384
15

16
    lcd_init(LCD_DISP_ON);
17

18
    uint16_t tmp;
19
    uint8_t tmphigh;
20

21
    for(;;) {
22
        tmp = TCNT1;
23
        tmphigh = TC1H;
24
        tmp |= (tmphigh<<8);
25
        itoa(tmp, buf, 10);
26
        lcd_clrscr();
27
        lcd_puts(buf);
28
        itoa(tmphigh, buf, 10);
29
        lcd_gotoxy(0,1);
30
        lcd_puts(buf);
31
        _delay_ms(20);
32
    }
33
}

Hat jemand einen Tipp für mich, oder habe ich irgendein Parameter im 
Datenblatt übersehen?

Danke
Moritz
#3842642
Lesenswert?

der alte Hanns schrieb:
>> CLKPR =  (1<<CLKPS1)| (1<<CLKPS1);
> Was soll da wirklich stehen?

Das ist eigentlich egal, so ist es nur 4x-Prescaler, warscheinlich 
dachte ich mal an (1<<CLKPS0)|(1<<CLKPS1) für 8x-Prescaler. Der 4x war 
aber genug um die Zahlen auf dem LCD lesbar zu bekommen.

der alte Hanns schrieb:
> Und wenn ich Ahnung von c hätte, wüsste ich, ob das funktioniert:

Das funktioniert.
#3842662
Lesenswert?

Dietrich L. schrieb:
> Moritz A. schrieb:
>
> Hier setzt Du CLKPCE:
>
>> CLKPR = (1<<CLKPCE);
>
> und hier löschst Du CLKPCE gleich wieder:
>
>>     CLKPR =  (1<<CLKPS1)| (1<<CLKPS1);

Ja, das gehört so.

> To avoid unintentional changes of clock frequency, a special write procedure
> must be followed to change the CLKPS bits:
> 1. Write the Clock Prescaler Change Enable (CLKPCE) bit to one and all other
> bits in CLKPR to zero.
> 2. Within four cycles, write the desired value to CLKPS while writing a zero to
> CLKPCE.

Wieso schaut ihr eigentlich alle so genau auf das 
Clock-Prescale-Register und nicht auf den eigentlichen Timer?
(Firma: guloshop.de) #3842664
Lesenswert?

Werner M. schrieb:
> der alte Hanns schrieb:
> Da tmphigh nur 8 Bit hat, wird (tmphigh<<8) auch nur 8 Bit haben ;-)

Ich bin mir da nicht sicher, es könnte sein, dass << generell als int 
ausgeführt wird. Moritz hat schon Recht, das funktioniert in der Praxis. 
Wie es in der Theorie definiert ist, weiß ich nicht, da müsste man sich 
mal durch den C-Standard wühlen...
Gast #3842727
Lesenswert?

The Timer/Counter Output Compare Register C contains data to be 
continuously compared with Timer/Counter1, and a compare match will 
clear TCNT1. This register has the same function in Normal mode and PWM 
modes.

Folglich muss zu Beginn OCR1C auf $3FF gesetzt werden.
#3842813
Lesenswert?

der alte Hanns schrieb:
> The Timer/Counter Output Compare Register C contains data to be
> continuously compared with Timer/Counter1, and a compare match will
> clear TCNT1. This register has the same function in Normal mode and PWM
> modes.
>
> Folglich muss zu Beginn OCR1C auf $3FF gesetzt werden.

Oh man, das ist aber echt gut versteckt.

Ich habe mich mal kurz gewundert, dass es zwar OCR1C gibt, aber keine 
OC1C/!OC1C-Pins. Dass dieser entscheidende Fakt dann da so versteckt in 
der Beschreibung drinsteht.

Danke für den Hinweis, so tut es. Und die erste Antwort war auch nicht 
zu knapp, ich saß bloß nicht die ganze Zeit mit dem Finger auf F5 am 
Rechner :)

Grüße
Moritz
#3842836
Lesenswert?

der alte Hanns schrieb:
> Kann der Compiler, in Analogie zu z.B. ADCW, nicht so etwas wie TCNT1W
> bzw. OCR1CW?

Habe ich nichts gefunden, aber das ist ja auch etwas "komplizierter", da 
es ja keine "16bit-Register" aus zwei 8bit-Registern sind, sondern bit 
9+10 für alle Timer-Register aus TC1H gelesen werden, sobald das 
Register beschrieben wird, bzw andersherum beim Lesen.

Aus diesem Grund müssen auch zB Interrupts, sofern die Routinen 
ebenfalls TC1H verwenden, für den Zugriff deaktiviert werden – sonst 
kann in TC1H ein falscher Wert stehen.
Moderator #3843438
Lesenswert?

Moritz A. schrieb:
> Habe ich nichts gefunden, aber das ist ja auch etwas "komplizierter", da
> es ja keine "16bit-Register" aus zwei 8bit-Registern sind

Auch ein 16-Bit-Zugriff (der ja prinzipiell in Ordnung wäre, da die
oberen 8 Bits von TC1H unbenutzt sind) geht nicht, weil die beiden
8-Bit-Register nicht an aufeinanderfolgenden Adressen liegen.
Gast #3843490
Lesenswert?

Schon klar, die Frage war auch eher provokant gemeint, denn:

Da schrieb mir doch mal einer, man könne mit c einfach losrennen, wo 
sich andere mit Assembler auf allen Vieren fortbewegten. Und nun bleibt 
man doch an solchen HW-Nicklichkeiten hängen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren