Forum: Mikrocontroller und Digitale Elektronik 10-bit-counter attiny 261/461/861


von Moritz A. (moritz_a)


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

von der alte Hanns (Gast)


Lesenswert?

> CLKPR =  (1<<CLKPS1)| (1<<CLKPS1);
Was soll da wirklich stehen?

Und wenn ich Ahnung von c hätte, wüsste ich, ob das funktioniert:
>   uint8_t tmphigh;
>  tmp |= (tmphigh<<8);

von Moritz A. (moritz_a)


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.

von Werner M. (Gast)


Lesenswert?

der alte Hanns schrieb:
> Und wenn ich Ahnung von c hätte, wüsste ich, ob das funktioniert:
>>   uint8_t tmphigh;
>>  tmp |= (tmphigh<<8);

Da tmphigh nur 8 Bit hat, wird (tmphigh<<8) auch nur 8 Bit haben ;-)

von Dietrich L. (dietrichl)


Lesenswert?

Moritz A. schrieb:

Hier setzt Du CLKPCE:

> CLKPR = (1<<CLKPCE);

und hier löschst Du CLKPCE gleich wieder:

>     CLKPR =  (1<<CLKPS1)| (1<<CLKPS1);

von Moritz A. (moritz_a)


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?

von Markus W. (Firma: guloshop.de) (m-w)


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...

von der alte Hanns (Gast)


Lesenswert?

Was genau steht auf dem LCD?

von Moritz A. (moritz_a)


Lesenswert?

der alte Hanns schrieb:
> Was genau steht auf dem LCD?

Es zählt von 0 bis 255, immer im Kreis.

In der zweiten Zeile steht permanent 0.

von der alte Hanns (Gast)


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.

von der alte Hanns (Gast)


Lesenswert?

War die Antwort zu knapp, Moritz A.?

In c lautet es vermutlich
TC1H=0x03;
OCR1C=0xFF;

von Moritz A. (moritz_a)


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

von der alte Hanns (Gast)


Lesenswert?

> ich saß bloß nicht die ganze Zeit ...
Es war immerhin eine Stunde.

Kann der Compiler, in Analogie zu z.B. ADCW, nicht so etwas wie TCNT1W 
bzw. OCR1CW?

von Moritz A. (moritz_a)


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.

von Yalu X. (yalu) (Moderator)


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.

von der alte Hanns (Gast)


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.

von Moritz A. (moritz_a)


Lesenswert?

der alte Hanns schrieb:
> 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.

Da wäre man mit Assembler aber genauso hängengeblieben ;)

von der alte Hanns (Gast)


Lesenswert?

Wir wollen jetzt aber nicht darüber philosophieren, dass man ab und zu 
im Leben auf alle Viere runter muss, oder?

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.