Forum: Mikrocontroller und Digitale Elektronik Timer 1 OC1A Pin taktet nicht (ATtiny841)


von Veit D. (devil-elec)


Lesenswert?

Hallo,

bin mir sicher das alles stimmt, aber irgendwas muß ich übersehen.
Gehäuse Pin 5 (PB2) oder 7 (PA6) sollte eigentlich mit 500Hz takten.
Macht er jedoch nicht.
Warum?
Bin jedoch nicht sicher ob das überhaupt die richtigen Pins sind vom 
OC1A.
Im Datenblatt finde ich keinen Namen mit Pin Funktion OC1A. Habe nur ein 
widersprüchliches Pinout gefunden. Aber selbst wenn ich Port.A und 
Port.B komplett auf Ausgang setze tut sich nichts.

ATtiny 841
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
 
4
#define F_CPU 8000000UL  
5
6
/* *** Funktion Deklarationen *** */
7
void set_Timer1();
8
9
10
int main(void)
11
{  
12
  //DDRB |= (1 << PA6);   // Timer-Pin OC1A Ausgang
13
  DDRA = 0xFF;
14
  DDRB = 0xFF;
15
  set_Timer1();
16
  
17
    while (1) 
18
    {
19
    
20
    }
21
}
22
23
24
/* *** Funktionen *** */
25
26
void set_Timer1()   //  CTC, Mode 4
27
{
28
  cli();         // Interrupts ausschalten
29
  TCCR1A = 0;    // Reset TCCR1A Register
30
  TCCR1B = 0;    // Reset TCCR1B Register
31
  TIMSK1 = 0;    // Reset TIMSK1 Register 
32
  TCNT1 = 0;     // Start 0
33
  OCR1A = 624;   // TOP Wert bestimmt mit Prescaler Takt, 500Hz
34
  TCCR1A = (1<<COM1A0);    // Toggle OC1A Pin on compare match
35
  TCCR1B = (1<<WGM12) | (1<<CS11) | (1<<CS10);    // Prescaler 64
36
  sei();         // Interrupts einschalten
37
}  // end Funktion

: Bearbeitet durch User
von HildeK (Gast)


Lesenswert?

So wie ich das auf den ersten Blick dem Datenblatt entnehme, musst du 
auch das Timer/Counter Output Compare Pin Mux Selection Registers 
entsprechend setzen und mit  Timer/Counter Output Compare Pin Mux 
Channel Output Enable auch aktivieren.
Kapitel 12.12.4 und 12.12.5 im Datenblatt.
Erst dann  wirst du Signale an den TOCCx-Pins sehen können.

von H.Joachim S. (crazyhorse)


Lesenswert?

Der Tiny841 hat einen etwas andere Timer als üblich.
U.a. kann und muss man das Signal auf einen tatsächlichen Pin routen.
Die betreffenden Register: TOCPMxx

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>Im Datenblatt finde ich keinen Namen mit Pin Funktion OC1A. Habe nur ein
>widersprüchliches Pinout gefunden. Aber selbst wenn ich Port.A und
>Port.B komplett auf Ausgang setze tut sich nichts.

Wie wäre es mit dem Ausgangsmultiplexer:

Table 12-7. Selecting Timer/Counter Compare Output for TOCCn Pins

auf S.116?

MfG Spess

von Veit D. (devil-elec)


Lesenswert?

Hallo,

das habe ich wirklich nicht gelesen. Dachte kennste einen kennste alle, 
aber ne, beim ATtiny gibts was neues. Scheint ein Feature zu sein zur 
freien Pinauswahl. Auch nicht schlecht.

Danke für den Hinweis. Schau ich mir genau an.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

so ganz blicke ich noch nicht durch.
Freie Pinwahl hat man erstmal nicht wie ich dachte.

Ich muß also im Register TOCPMSA0 das Bit TOCC1S1 aktivieren.
1
TOCPMSA0 = (1<<TOCC1S1);  // OC1A Select

Aber was macht das TOCPMCOE Register?
Vielleicht
1
TOCPMCOE = (1<<TOCC1OE);

Irgendwie alles mehr verwirrend als was es bringt?

Den Pin PA2 muß ich ja dennoch extra auf Ausgang setzen.

Was hat die ganze Selektiererei für einen Vorteil?

von H.Joachim S. (crazyhorse)


Lesenswert?

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Toggle on compare match
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 5 ms
// Output Pulse(s):
// OC1A Period: 10 ms Width: 5 ms
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (1<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | 
(0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | 
(1<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x02;
OCR1AL=0x70;
OCR1BH=0x00;
OCR1BL=0x00;



// Timer/Counter Compare Outputs signals routed to TOCCn pins:
// Nothing -> TOCC0
// OC1A -> TOCC1
// Nothing -> TOCC2
// Nothing -> TOCC3
// Nothing -> TOCC4
// Nothing -> TOCC5
// Nothing -> TOCC6
// Nothing -> TOCC7
TOCPMSA0=(0<<TOCC3S1) | (0<<TOCC3S0) | (0<<TOCC2S1) | (0<<TOCC2S0) | 
(0<<TOCC1S1) | (1<<TOCC1S0) | (0<<TOCC0S1) | (0<<TOCC0S0);
TOCPMSA1=(0<<TOCC7S1) | (0<<TOCC7S0) | (0<<TOCC6S1) | (0<<TOCC6S0) | 
(0<<TOCC5S1) | (0<<TOCC5S0) | (0<<TOCC4S1) | (0<<TOCC4S0);
TOCPMCOE=(0<<TOCC7OE) | (0<<TOCC6OE) | (0<<TOCC5OE) | (0<<TOCC4OE) | 
(0<<TOCC3OE) | (0<<TOCC2OE) | (1<<TOCC1OE) | (0<<TOCC0OE);

von Veit D. (devil-elec)


Lesenswert?

Hallo,

okay, bis auf das hier habe/hatte ich das so.
TOCPMSA0 = (1<<TOCC1S1);  // OC1A Select

Habe es geändert und sehe 514Hz statt 500Hz
TOCPMSA0 = (1<<TOCC1S0);  // OC1A Select

Nur warum das Bit TOCC1S0 und nicht TOCC1S1 für OC1A?
In der Tabelle auf Seite 116 steht OC1A doch in Spalte Bit 01?
Da komme ich nicht mit.
Oder müßte das besser TOCC1S01  heißen?

1
void set_Timer1()   //  CTC, Mode 4
2
{
3
  cli();         // Interrupts ausschalten
4
  TCCR1A = 0;    // Reset TCCR1A Register
5
  TCCR1B = 0;    // Reset TCCR1B Register
6
  TIMSK1 = 0;    // Reset TIMSK1 Register 
7
  TCNT1 = 0;     // Start 0
8
  OCR1A = 124;   // TOP Wert bestimmt mit Prescaler Takt, 500Hz
9
  TOCPMSA0 = (1<<TOCC1S0);  // OC1A Select
10
  TOCPMCOE = (1<<TOCC1OE);  // TOCC1 Output enable
11
  TCCR1A = (1<<COM1A0);    // Toggle OC1A Pin on compare match
12
  TCCR1B = (1<<WGM12) | (1<<CS11) | (1<<CS10);    // Prescaler 64
13
  sei();         // Interrupts einschalten
14
}  // end Funktion

: Bearbeitet durch User
von Ingo L. (corrtexx)


Lesenswert?

Du musst offenbar in den TOCPMSA0/1 Registern den Timeroutput auf den 
dazugehörigen Pin routen und anschließend noch im TOCPMCOE Register den 
Ausgang freigeben... Nettes kleines Feature

von Ingo L. (corrtexx)


Lesenswert?

Veit D. schrieb:
> In der Tabelle auf Seite 116 steht OC1A doch in Spalte Bit 01?
Da steht 01. Die 0 steht für das TOCC1S1 Bit und die 1 für das TOCC1S0 
Bit.

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Hallo,

vielleicht noch als Ergänzung,

die Pins heißen TOCCn und sind unter S.63f
/Table 10-3. Alternative Functions of Port A/
aufgeführt.

Für Timer1 OC1A ergibt sich dann aus S.116f
/Table 12-7. Selecting Timer/Counter Compare Output for TOCCn Pins/

TOCC1 -- OC1A für TOCC1S[1:0] = 0b01
TOCC3 -- OC1A für TOCC3S[1:0] = 0b01
TOCC5 -- OC1A für TOCC5S[1:0] = 0b01
TOCC7 -- OC1A für TOCC7S[1:0] = 0b01

Über das Register TOCPMCOE muss dann noch einer der TOCCn Pins 
eingeschaltet werden:
1
TOCPMCOE |= (1<<TOCC1OE);
2
TOCPMCOE |= (1<<TOCC3OE);
3
TOCPMCOE |= (1<<TOCC5OE);
4
TOCPMCOE |= (1<<TOCC7OE);

von Ingo L. (corrtexx)


Lesenswert?

Ich muss sagen ich finde die neuen Tiny x41 echt cool, SPI kann man 
ummappen, Timer kann man ummappen und der ADC ist auch mit mehreren 
internen Referenzen ausgestattet. "Echtes" USART und SPI sind auch toll. 
Bei mir ersetzt er den Tiny x4 auf jeden Fall in der Bastelkiste.

EDIT: n echtes TWI hat er ja auch noch

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Hi Ingo,

ja das ist alles den zu "wenigen" Ausgabepins geschuldet.

Hast Du dir schon mal den Attiny1634 angesehen ?

# 
http://www.atmel.com/Images/Atmel-8303-8-bit-AVR-Microcontroller-tinyAVR-ATtiny1634_Datasheet.pdf

von Veit D. (devil-elec)


Angehängte Dateien:

Lesenswert?

Hallo,

verstehe es immer noch nicht.
Die Datenblätter werden scheinbar undurchsichtiger.
Es gibt doch insgesamt 2 Bits. Für 00, 01, 1x
Und OC1A steht in Spalte 01.
Verstehe immer noch nicht wie man dann auf die 0 kommt.

von Veit D. (devil-elec)


Angehängte Dateien:

Lesenswert?

Hallo,

ich hänge nochmal die "nackte Tabelle" ran zum einmalen für euch.
Vielleicht verstehe ich das dann besser.

Edit:
gut, dass umlegen der Timer Ausgänge auf andere Pins habe ich 
geschnallt.
Das geht ganz gut aus der Tabelle hervor.
Nur wie kommt man auf 0 in Zeile TOCC1 für OC1A.
Wenn OC1x in Spalte 01 steht?

@ Karl M.
Genauso bin ich auch rangegangen. Ist aber falsch wie sich 
herausstellte.
ich muß TOCC1S0 schreiben damit es funktioniert.
1
TOCPMSA0 = (1<<TOCC1S0);  // OC1A Select
2
TOCPMCOE = (1<<TOCC1OE);  // TOCC1 Output enable

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

nochmal.
Eigentlich steht im Tabellenkopf TOCCnSxx.

xx steht für ... Bit1  Bit0

Jetzt lese ich in der Spalte für OC1A oben "01".
Heißt für mich Bit 0 muß auf 1 gesetzt werden.
Ist aber falsch, dann taktet nichts.
Setze ich alles auf 0 taktet es wie gewünscht.
Kommt jemand hinter diese Logik?

Zudem Atmel Studio nur TOCC1S0 oder TOCC1S1 kennt, also farbig markiert.
Die rechte Spalte für OC2A müßte ja 10 oder 11 sein, kennt es aber 
nicht.

Außerdem ist im Register TOCPMSAx jeweils immer nur eine Bitstelle 
vorgesehen. Wie will man überhaupt den 3. Timerausgang aktivieren laut 
Tabelle unten drunter rechte Spalte?

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Veit D. schrieb:

> Zudem Atmel Studio nur TOCC1S0 oder TOCC1S1 kennt

Nö. Das kennt TOCCnS0 und TOCCnS1 mit n=0..7.

> Die rechte Spalte für OC2A müßte ja 10 oder 11 sein, kennt es aber
> nicht.

Was meinst du mit "kennt es nicht"?

> Außerdem ist im Register TOCPMSAx jeweils immer nur eine Bitstelle
> vorgesehen. Wie will man überhaupt den 3. Timerausgang aktivieren laut
> Tabelle unten drunter rechte Spalte?

OMG, du hast das Prinzip absolut nicht kapiert, dabei ist es wirklich 
ganz einfach.

Also: Es gibt acht Port-Pins, über die man die insgesamt sechs 
OC-Signale der drei Timer schicken kann. Da es vielfältig einstellbar 
ist, welches davon auf welchem Pin landen soll, gibt es das klassische 
Mapping der "alternate port functions" (OCnX) mit n: Timernummer und 
X:OC-Kanal) hier nicht, statt dessen werden acht symbolische Signale 
eingeführt, nämlich TOCCn. Es gibt eine direkte unveränderliche 
Beziehung zwischen jedem TOCCn-Signal und dem dazu gehörenden Port-Pin. 
Die findet man sowohl in den Pinouts ab Seite 2 des DB als auch in 
Tabellenform ab Seite 63 für Port A bzw. ab Seite 68 für PortB.

Du wolltest im OP entweder PB2 oder PA6 haben, ich vereinfache mir mal 
die Erklärung und lege fest, dass du PA6 haben willst. Das entspricht 
nach o.g. Quellen dem symbolischen OC-Signal TOCC5.

Nachdem du das nun weisst, gehst du in die MUX-Tabelle, die du schon 
gefunden hast und dort in die entsprechende Zeile für TOCC5. Da siehst 
du, welche realen Timersignale du auf TOCC5 (und damit auf PA6) routen 
kannst. Möglich ist an diesem Pin also jeweils OC-Kanal A der drei 
vorhandenen Timer (Kanal B ginge nicht). In deinem OP wolltest du OC1A 
haben, das geht also.

> Jetzt lese ich in der Spalte für OC1A oben "01".

Genau. Du musst also TOCC5S1:TOCC5S0 in TOCPMSA1 auf 01 setzen. Beachte: 
das sind nicht Bit 0 und 1 in diesem Register, sondern die Bits 3 und 
2!!!
Zusätzlich musst du auch noch TOCC5OE in TOCPMCOE setzen.

Also kommen für das Mapping folgende Anweisungen raus:

TOCPMSA1 |= (1<<TOCC5S0)
TOCPMCOE |= (1<<TOCC5OE)

> Außerdem ist im Register TOCPMSAx jeweils immer nur eine Bitstelle
> vorgesehen. Wie will man überhaupt den 3. Timerausgang aktivieren laut
> Tabelle unten drunter rechte Spalte?

Wenn du meine Erklärung verstanden hast, solltest du dir die Frage jetzt 
selbst beantworten können. Nur noch als Anmerkung: Man kann alle sechs 
OC-Kanäle gleichzeitig nach aussen führen. Und: man kann auch einen 
einzelnen Kanal auf bis zu vier Pins routen. Und nein, das ist nicht 
nutzlos, denn damit kann man nämlich den vierfachen Strom treiben...

von Veit D. (devil-elec)


Lesenswert?

c-hater schrieb:
>> Jetzt lese ich in der Spalte für OC1A oben "01".
>
> Genau. Du musst also TOCC5S1:TOCC5S0 in TOCPMSA1 auf 01 setzen.

Hallo Assembler Vergötterer,

genau die Schreibweise hat nun bei mir Klick gemacht.
Sieht vielleicht für euch auch nicht anders aus wie die schon 
geposteten, aber für mich eben doch.
Wobei ihr aber auch zugeben müßt das diese Tabelle doof gemacht ist.
Ich meine die anderen mit Prescaler und Timer Mode versteht auch jedes 
Kind auf Anhieb. Aber ich will jetzt nicht weiter meckern.

Vielen Dank das du dich nochmal erbarmt hast für die Erklärung.

Und Danke auch den anderen für die verzweifelten Mühen.
Habs jetzt gerafft.

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.