Forum: Mikrocontroller und Digitale Elektronik Attiny2313 Timer0 klappt nicht


von abc (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute, ich probiere gerade, an einer kleinen Bargraphanzeige mit 
10 LEDs im Multiplexing herum. Doch irgendwie klappt das bei mir mit dem 
Timer0 des Attinys nicht so recht.

Die Schaltung habe ich angehängt und hier mein Quellcode:
1
//µC: Attiny2313
2
//Taktfrequenz: 1 MHz
3
4
//Taktfrequenz setzen
5
#define F_CPU 1000000
6
7
//Includes
8
#include <avr/io.h>
9
#include <util/delay.h>
10
#include <avr/interrupt.h>
11
12
13
//Variablen
14
int NumberPortD[11] = {0x00,0x20,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60};//Bitmuster für die Zahlen für PortD
15
int NumberPortB[11] = {0x00,0x00,0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF};//Bitmuster für PortB
16
int BarRight = 5;        //rechter Bargraph Wert
17
int BarLeft = 5;        //linker Bargraph Wert
18
int b = 0;            //Bargraphnummer für Multiplexing
19
int bw = 0;            //Bargraphwert
20
21
//Funktionen
22
void init();
23
24
int main(void) {
25
26
  //Initialisierung
27
  init();
28
29
  //Hauptschleife
30
  while(1) {
31
32
  }
33
34
  return 0;
35
36
}
37
38
//Initfunktion
39
void init() {
40
41
  //Ports setzen
42
  DDRB = 0xFF;
43
  DDRD = 0xFF;
44
45
  //Timer0 konfigurieren Prescaler 8
46
  TCCR0A = (1<<CS01);
47
  
48
  //Overflowinterrupt erlauben
49
  TIMSK |= (1<<TOIE0);
50
51
  //Global Interrupts aktivieren
52
  sei();
53
}
54
55
56
//Timer0 Interrupt
57
ISR (TIMER0_OVF_vect)
58
{
59
  b++;            //b = 0 --> linker Bargraph
60
  if (b == 2) {b = 0;};  //b = 1 --> rechter Bargraph
61
  
62
  //Ports ausschalten
63
  PORTD = 0x00;
64
  PORTB = 0x00;
65
  
66
  if (b == 0) {
67
    bw = BarLeft;
68
  } else {
69
    bw = BarRight;
70
  };
71
  
72
  //Bitmuster in Ports schreiben
73
  PORTB = NumberPortB[bw];
74
  PORTD = NumberPortD[bw];
75
76
  //Bargraph einschalten
77
  if (b == 0) {
78
    PORTD &= 0x08;
79
  } else {
80
    PORTD &= 0x04;
81
  }
82
}

von Karl H. (kbuchegg)


Lesenswert?

So

  if (b == 0) {
    PORTD &= 0x08;
  } else {
    PORTD &= 0x04;
  }


wirst du aber nicht die erforderliche 1 am Pin zustande bringen, die 
einen der beiden Transistoren zum durchschalten bringt


  if (b == 0) {
    PORTD |= 0x08;
  } else {
    PORTD |= 0x04;
  }

Wieso eigentlich 0x08 und 0x04? Laut deinem SChaltplan hängen die 
Transistoren an PD3 und PD4

Schreib das doch so ...

  if (b == 0) {
    PORTD |= 1 << PD3;
  } else {
    PORTD |= 1 << PD4;
  }

... und lass dein Compiler ausrechnen, was das für eine Hex-Zahl ist. 
Dann gibt es keine Fehler, weil du dich bei der Umrechnung der Pin 
Nummer in eine Hex-Zahl vertan hast. Denn du schreibst dann die Pin 
Nummer selber hin und der Compiler erledigt das Umrechnen. Und der weiß, 
dass bei 0 angefangen wird zu zählen.

von abc (Gast)


Lesenswert?

Ok, das mit den Transistoren hab ich mal verbessert, aber es leuchtet 
immer noch nichts. Schreibe ich nur
1
  PORTD |= (1<<PD4);
2
  PORTB |= (1<<PB0);
 in die Timerroutine so leuchtet auch nichts. An beiden Pins liegt so 0V 
an. Ich denke ich hab da was mit der Timerinitialisierung falsch 
gemacht.

von Abc (Gast)


Lesenswert?

keiner eine idee?

von Karl H. (kbuchegg)


Lesenswert?

Keine Compilerwarnings?


OK. Dann Multimeter raus und an den µC Pins messen, ob sie auf High 
sind.


Wenn nicht: Testprogramm, dass völlig ohne Timer auskommt
1
int main()
2
{
3
  DDRD = 0xFF;
4
  DDRB = 0xFF;
5
6
  PORTD = (1<<PD4);
7
  PORTB = (1<<PB0);
8
9
  while( 1 )
10
  {
11
  }
12
}

wieder messen. Wenn die Pins immer noch nicht 1 sind, dann läuft dein µC 
nicht. Wenn die Pins 1 sind und trotzdem nichts leuchtet: Leiterbahnen 
verfolgen und auf Unterbrechungen absuchen. Transistoren an der Basis 
checken. Ist die 1 da? Haben die LED Spannung an der Anode? Gibt es eine 
Unterbrechung in den Leiterbahnen? etc. etc.

von Abc (Gast)


Lesenswert?

also ich kann sagen, dass es aufjedenfall nicht an der Schaltung liegt. 
Habe es mal mit Bascom blinken lassen und es hat funktioniert, auch am 
Anfang in ( in der main blinken lassen und es hat funktioniert. 
Irgendwie läuft aber der Timer nicht

von Karl H. (kbuchegg)


Lesenswert?

Abc schrieb:
> also ich kann sagen, dass es aufjedenfall nicht an der Schaltung liegt.
> Habe es mal mit Bascom blinken lassen und es hat funktioniert, auch am
> Anfang in ( in der main blinken lassen und es hat funktioniert.
> Irgendwie läuft aber der Timer nicht

Die Timerkonfiguration ist in Ordnung, wenn der Name der ISR stimmt. 
Drum hab ich nach Compiler Warnings gefragt, weil ich auch nicht 
auswendig weiß, ob die beim Timer 0 so heißt (auf manchen AVR heißen die 
anders)

Hast du auch das richtige Hex-File gebrannt (ist mir auch schon 
passiert. AVR-Studio 4 ist da richtiggehend fies)

Im AVR-Studio den richtigen µC eingestellt?

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Abc schrieb:
>> also ich kann sagen, dass es aufjedenfall nicht an der Schaltung liegt.
>> Habe es mal mit Bascom blinken lassen und es hat funktioniert, auch am
>> Anfang in ( in der main blinken lassen und es hat funktioniert.
>> Irgendwie läuft aber der Timer nicht
>
> Die Timerkonfiguration ist in Ordnung,

Äh, Moment.

Das CS01 Bit ist im Register TCCR0B

Datenblatt - Seite 76

Du musst bei jedem Bit kontrollieren, ob du auch im richtigen Register 
bist. Nur weil bei einem Prozessortyp das CS01 in TCCR0A ist, heißt das 
nicht, dass es bei einem anderen Prozessortyp auch dort ist.

Daher: Immer das Datenblatt zu Rate ziehen. Das ist deine einzige Bibel 
deren Autorität über allem anderen steht. Bei den Timern ist zum 
schnellen Nachschlagen immer der Abschnitt "Register Summary" im 
jeweiligen Kapitel das Interessante.

von abc (Gast)


Lesenswert?

Mit TCCR0B funktioniert es nun. Ja das mit den Registern ist so eine 
Sache. Muss mich auch erstmal reinfinden habe davor ein wenig mit BASCOM 
programmiert und PC-seitig mit Delphi und ab und zu ein wenig PHP/JS.

von abc (Gast)


Lesenswert?

Ok, ich hab noch 'ne Frage. Ich deklariere ja die Variablen BarLeft und 
BarRight für die Werte. Wenn ich diese nun bei der Deklaration gleich 
mit einem Wert initialisiere, dann wird dieser auch angezeigt. Wenn ich 
dort aber nichts zuweise und probiere in der main was zu zu weisen, dann 
passiert nichts:
1
int main(void) {
2
3
  //Initialisierung
4
  init();
5
6
  //Hauptschleife
7
  while(1) {
8
    BarLeft = 10;
9
    _delay_ms(500);
10
    BarLeft = 0;
11
    _delay_ms(500);
12
  }
13
14
  return 0;
15
16
}
Es bleibt dunkel. Hat jemand eine Idee?

von Karl H. (kbuchegg)


Lesenswert?

1
volatile int BarRight = 5;        //rechter Bargraph Wert
2
volatile int BarLeft = 5;        //linker Bargraph Wert

von abc (Gast)


Lesenswert?

Danke funktioniert nun. ;)

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.