Forum: Mikrocontroller und Digitale Elektronik Benötige Hilfe bei Timer/Counter 0/1 im ATTINY87


von OnkelTom17 (Gast)


Lesenswert?

Codevision AVR Version 2.05.4
AVR Studio 4.19 Build 730
Windowes XP Professional

Hallo zusammen, benötige Hilfe beim Initialisieren der Timer 0 und 1 im 
ATTINY87 / 167.
Folgendes benötige ich:
Timer 0 8bit timer mit interrupt bei overflow
Timer 1 8bit PWM (0xFF) phase-correct an Pin OC1AX (Port B.6) (ohne 
Interrupt, einfach PWM Ausgang)

Habe die Timer folgendermaßen initialisiert, ber weder timer 0 macht 
einen interrupt noch kommt bei timer 1 eine PWM an PB6 raus.
Hat irgendjemand eine Idee, was ich falsch mache?
1
// Timer/Counter 0 initialization
2
// Clock source: System Clock
3
// Clock value: 125,000 kHz
4
// Mode: Normal top=0xFF
5
// OC0A output: Disconnected
6
// OC0B output: Disconnected
7
TCCR0A=0x00; // normal operation, non PWM mode, OC0A disconnected
8
TCCR0B=0x03; // clkT0S/32 (From prescaler)
9
TCNT0=0x55;  // TimerCounter Register Value
10
OCR0A=0x00;  // no output compare used
11
ASSR = 0x00; // TC0 clocked from the I/O clock
12
GTCCR = 0;   // 
13
// Timer/Counter 0 Interrupt(s) initialization
14
TIMSK0=0x01; // TCo Overflow interrupt enable
15
16
17
// Timer/Counter 1 initialization
18
// Clock source: System Clock
19
// Clock value: 125,000 kHz
20
// Mode: Ph. correct PWM top=0x00FF
21
// OC1A output: Non-Inv.
22
// OC1B output: Discon.
23
// Noise Canceler: Off
24
// Input Capture on Falling Edge
25
// Timer1 Overflow Interrupt: Off
26
// Input Capture Interrupt: Off
27
// Compare A Match Interrupt: Off
28
// Compare B Match Interrupt: Off
29
TCCR1A=0x81;  //PWM, Phase Correct, 8-bit
30
TCCR1B=0x03;  //clkI/O/64 (From prescaler)
31
TCNT1H=0x00;
32
TCNT1L=0x33;  // testvalue for tesing PWM
33
ICR1H=0x00;
34
ICR1L=0x00;
35
OCR1AH=0x00;
36
OCR1AL=0x00;
37
OCR1BH=0x00;
38
OCR1BL=0x00;
39
40
//check
41
TCCR1C=0x00;
42
TCCR1D=0x08;  // The OC1Ai bits enable the Output Compare pins of Channel A
43
44
// Timer/Counter 1 Interrupt(s) initialization
45
TIMSK1=0x00;   // no interrupt used

Außerdem ist im Hauptprogramm die globale Interrupt-Freigabe gesetzt:
// Global enable interrupts
#asm("sei")

Irgendeiner eine Idee? Habe die Initialisierung mehrfach gepüft, kriege 
aber die Kurve nicht? Vielleicht habe ich irgendwo einen Knoten im Hirn 
oder Kartoffeln auf den Augen.

Danke für eure Hilfe
OT17

von spess53 (Gast)


Lesenswert?

Hi

>Habe die Timer folgendermaßen initialisiert, ber weder timer 0 macht
>einen interrupt noch kommt bei timer 1 eine PWM an PB6 raus.
>Hat irgendjemand eine Idee, was ich falsch mache?

Wie hast du das festgestellt?

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Da dir der Codevision Wizard die Initialisierung geschrieben hat, wird 
sie wohl korrekt sein und es macht wenig Sinn für uns sie zu überprüfen. 
Das wird sicherlich stimmen, auch wenn ich solche Dinge
1
TIMSK0=0x01; // TCo Overflow interrupt enable
auf den Tod nicht ausstehen kann.
1
TIMSK0 = (1<<TOIE0); // TCo Overflow interrupt enable
ist lesbarer und ich brauch nicht wissen (bzw. kontrollieren), dass das 
TOIE0 Flag bei diesem µC das Bit 0 ist.

D.h. Der Fehler wird halt mal wieder in den Codeteilen stecken, die du 
nicht gezeigt hast.

von spess53 (Gast)


Lesenswert?

Hi

>D.h. Der Fehler wird halt mal wieder in den Codeteilen stecken, die du
>nicht gezeigt hast.

Nicht ganz. Mit diesen Comparewerten

>OCR1AH=0x00;
>OCR1AL=0x00;
>OCR1BH=0x00;
>OCR1BL=0x00;

ist nicht viel zu sehen.

Und hier

>TCNT1H=0x00;
>TCNT1L=0x33;  // testvalue for tesing PWM

scheint auf einem Verständnisproblem zu beruhen.

Mir ging es einfach darum, ob er den Simulator benutzt hat. Die 
ATTiny87/167 werden anscheinend nicht sonderlich unterstützt.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

spess53 schrieb:


> Und hier
>
>>TCNT1H=0x00;
>>TCNT1L=0x33;  // testvalue for tesing PWM
>
> scheint auf einem Verständnisproblem zu beruhen.

Da könntest du recht haben. Ist mir gar nicht aufgefallen.
Aber wer weiß schon, was er in späterer Folge im Programm sonst noch so 
alles macht? Zb. wird der PWM Pin auf Ausgang gestellt?

von spess53 (Gast)


Lesenswert?

Hi

>Zb. wird der PWM Pin auf Ausgang gestellt?

Habe ich auch vermisst. Vielleicht kommt Onkel Tom noch mal aus seiner 
Hütte.

MfG Spess

von OnkelTom17 (Gast)


Lesenswert?

Hallo zusammen,
erst einmal herzlichen Dank für eure Antworten.
War "ein paar Minuten weg".
@spess53- erste Antwort:
Ich habe für alle im ATTINY möglichen Interrupts die Service-Routinen 
geschrieben und in die Routinen je einen Breakpoint gesetzt. So konnte 
ich ausschließen, dass ich die ISR eventuell vergessen habe. Keiner der 
Breakpoints wurde durch die Timer angesprungen. Z.B,. PinChange 
Interrupts klappen aber sehr wohl.
Bei der PWM kommt halt nichts am Pin an. Habe ich mit dem Oszi 
nachgemessen.

@ Karl Heinz Buchegger - erste Antwort:
Die Initialisierung sieht nur so aus, als ob sie vom CVAVR kommt. Der 
ATTINY87 wird vom CodeWizard noch nicht unterstützt. Der Teil Code kommt 
aus dem Wizard für den ATMEGA44 und wurde Register für Register anhand 
des Datenblatts für den ATTINY87 modifiziert. Daher kann ich leider 
nicht davon ausgehen, dass er richtig ist.
Zu Deinem Tip: Ich werde mir in Zukunft (trotz Codevision Wizard) die 
von Dir bevorzugte Schreibweise aneignen. Sie ist wirklich besser 
lesbar. Danke für den Hinweis!

Zu den weiteren Antworten:
Wenn ich das Datenblatt recht verstehe, wird über
1
TCCR1D=0x08;  // The OC1Ai bits enable the Output Compare pins of Channel A
2
also besser: TCCR1D = (OC1AX << 1);
der Ausgang dem PWM zugeordnet, bzw die PWM an dem Port OC1AX = PORTB.6. 
Ist dass Korrekt?
Bei der Initzialisierung der Portpins ist dieser Pin auf Ausgang:
1
// Port B initialization
2
// Func7=In Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
3
  // State7=T State6=0 State5=T State4=T State3=T State2=H State1=H State0=H 
4
  PORTB=0x07;
5
  DDRB=0x40;   // Only PortB.6 is output
@  Karl Heinz Buchegger: Wie würde die "bessere Schreibweise" für die 
letzte Zeile aussehen?

Zu dem Verständnisproblem bei der PWM:
In welches Register muss der Wert der PWM (0..0xFF) geschrieben werden. 
Ich dachte in das TCNT1x-Register. Daher hatte ich
[c]TCNT1L=0x33;  // testvalue for tesing PWM[c/] geschrieben, um 
überhaupt mal eine PWM zu bekommen. Ich dachte, das Einschreiben eines 
anderen Wertes in dieses Register ändert den DutyCycle der PWM. Das wird 
dann bei Bedarf in anderen Programmteilen gemacht.

Bin nachher zu hause und werde in die anderen Register auch mal Werte 
schreiben und schuen, ob sich was tut.

Ich habe sowohl mit dem ATJTACICE MKII unter AVRSTUDIO und der 
originalen Hardware getestet als auch im Suimulator des AVRSTUDIOs.

Werde nacher zu hause testen und mich dann wieder melden.
Danke für eure Tips.

Gruß OnkelTom17

von Peter D. (peda)


Lesenswert?

OnkelTom17 schrieb:
> Die Initialisierung sieht nur so aus, als ob sie vom CVAVR kommt. Der
> ATTINY87 wird vom CodeWizard noch nicht unterstützt.

Wird er denn überhaupt vom Codevision unterstützt?

Den neuen Tinys fehlen ja die unteren 16 Register und einige Befehle 
haben ne andere Bedeutung.
Deshalb kann ihn z.B. der WINAVR nicht.
Und da nützt es auch nichts, sich das Include zu basteln, der Compiler 
muß völlig anderen Code erzeugen.

Vermutlich kann man die zur Zeit erstmal nur in Assembler programmieren.


Peter

von spess53 (Gast)


Lesenswert?

Hi

>also besser: TCCR1D = (OC1AX << 1);

Nein-> TCCR1D = (1<<OC1AX);

Das Problem ist/sind der/die Simulatore(n). Der Simulator2 
(AVR-Studio4.19 / AVR-Studio5 unterstützt der ATTiny87 gar nicht. Der 
Simulator(1) vom AVR-Studio4.19 anscheinend nur rudimentär. Zum ATTiny87 
gibt es keine 'Known Issues', beim grösseren Bruder, dem ATTiny167, 
findet sich der Hinweis: 'Timer/Counter0 is not simulated properly'. Das 
dürfte auch für den ATTiny87 gelten. Und da der Timer1 Funktionen hat, 
die von den üblichen 16-Bit-Timern abweichen habe ich da auch meine 
Zweifel.

MfG Spess

von spess53 (Gast)


Lesenswert?

HI

>Den neuen Tinys fehlen ja die unteren 16 Register und einige Befehle
>haben ne andere Bedeutung.

Der ATTiny87 hat 32 Register. Die einzigen mit 16 Registern, die mir im 
Moment einfallen, sind die ATTiny4/5/9/10 (SOT23-).

MfG Spess

von Peter D. (peda)


Lesenswert?

spess53 schrieb:
> Der ATTiny87 hat 32 Register.

Stimmt, der ist noch ein ganzer AVR.
Ich hab ihn mit dem ATtiny40 verwechselt.


Peter

von OnkelTom17 (Gast)


Lesenswert?

Hallo,

ja der ATINY78 und 167 werden vom CodeVision Compiler unterstützt, nur 
noch nicht vom Code Wizard des CodeVision.

[...]
Chips supported by CodeVisionAVR Standard:
    ATtiny4, ATtiny5, ATtiny9, ATtiny10, ATtiny20, ATtiny40 (reduced 
core)
    ATtiny13, ATtiny13A
    ATtiny167, ATtiny87
[...]

Die passenden Includes hat der Compiler mitgebracht, die habe ich nicht 
zusammengebastelt.

Da ich hauptsächlich mit dem Emulator, also dem JTAGICE MKII unter 
AVRSTUDIO (und nicht dem Simulator) arbeite, sollte ich doch alles 
testen können, oder?

Dass der Simulator2 den ATTINY87 nicht unterstützt, hatte ich schon 
bemerkt. daher habe ich in dem Fall auch den Simulator 1 im AVRSTUDIO 
4.19 benutzt.

Gruß OT17

von spess53 (Gast)


Lesenswert?

Hi

>Da ich hauptsächlich mit dem Emulator, also dem JTAGICE MKII unter
>AVRSTUDIO (und nicht dem Simulator) arbeite, sollte ich doch alles
>testen können, oder?

Ja.

MfG spess

von OnkelTom17 (Gast)


Lesenswert?

Hallo zusammen,

PWM läuft jetzt mit Timer 1 mit folgender Konfiguration:
1
// Timer/Counter 1 initialization
2
  TCCR1A        =((1<<COM1A1)|(1<<WGM10));  // PWM phase correct 8-bit TOP= 0xFF
3
  TCCR1B        =((1<<CS11)|(1<<CS10));     // CLKio/64
4
  TCNT1         = 0x0000;                   // 16bit access
5
  ICR1          = 0x0000;                   // 16bit access
6
  OCR1A         = 0x0055;                   // 16bit access
7
  OCR1B         = 0x0000;                   // 16bit access
8
9
  TCCR1C        = 0x00;
10
  TCCR1D        = (1<<OC1AX);                // The OC1Ai bits enable the Output Compare pins of Channel A
11
  // Timer/Counter 1 Interrupt(s) initialization
12
  TIMSK1        = 0;
und folgender interrupt service routine:
1
interrupt [TIM1_CAPT] void int6(void)
2
{     
3
OCR1A ++;
4
}
Es wird ein "gleitender" (von 0-100% duty cycle)PWM generiert. Ist erst 
einmmal für Testzwecke um zu sehen, dass überhaupt was läuft.

Das Problem war, dass OCR1A keinen Wert hatte und 0% duty Cycle nun mal 
so aussieht, als ob es nicht klappt.

Jetzt muss ich Timer0 nochmal checken. Vielleicht liegt das Problem da 
auch begraben.

Bis bald.
Nochmal danke für alle Tips. Wenn ich nicht weiterkomme, bin ich wieder 
da. Wenn ich weiterkomme, sage ich worans gelegen hat, damit nicht noch 
jemand lange suchen muss.

Gruß OT17

von OnkelTom17 (Gast)


Lesenswert?

Hallo zusamen,
so lauft auch Timer0 problemlos (mit 1KHz Interrupt-Rate bei 8MHz 
Clockfrequenz)
1
#include "tiny87.h"
2
#include "tiny167_bits.h"
3
4
unsigned char Timer0value = 0xE0;
5
void main(void)
6
{
7
  DDRB.6 = 1;             // PORTB.6 output --> toggle pin for testing
8
  TCCR0A  = 0; 
9
  TCCR0B  = ((1<<CS01)|(1<<CS00));          // clkT0S/32 (From prescaler)
10
  TCNT0   = Timer0value; 
11
  ASSR    = 0x00;
12
  GTCCR   = 0;
13
  TIMSK0  = (1<<TOIE0);  //Timer/Counter0 Overflow
14
15
  #asm("sei");
16
  while(1){};
17
18
}
19
20
// Timer 0 overflow interrupt service routine
21
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
22
{
23
  TCNT0 = Timer0value;                           
24
  PORTB.6 = ~PORTB.6;     // toggle to check with oscilloscope
25
}

Ich hoffe, es hilft jemandem.
Groß OT17

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.