Forum: Mikrocontroller und Digitale Elektronik simples blink programm fehler


von Richard X. (synq1e)


Lesenswert?

an dem attiny2313 hängen 3 treiber und 6 LEDS im multiplex betrieb auf 
8MHZ

ziel ist es die einzelnen reihen mit einem 1 sekunden ON OFF 
durchzuschalten

irgendwie passt das timing aber nicht

sie leuchten zwar auf aber undefiniert

die volatile variable ist gesetzt wegen speicherzugriff im main und ISR 
passt doch oder ?

1
#include <avr/io.h>
2
#define F_CPU 8000000
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
6
void blink_(void);
7
volatile uint8_t second_tick;
8
9
10
11
int main(void)
12
{
13
  DDRB = 0b00111111; // LED output
14
  DDRD = 0b00000111; //treiber ausgang
15
  
16
  PORTD = 0xFF;   //treiber active low AUS
17
  PORTB = 0xFF;   //active low leds aus
18
  TCCR0B |= ( _BV(CS00) | _BV(CS02) ) ;   //timer start @ prescaler 1024
19
  TIMSK |= _BV(TOIE0); //timer overflow interrupt enable
20
  sei();
21
  
22
  while(1) //infinite loop
23
  {
24
    
25
    
26
    PORTD = 0b11111110;
27
    blink_();
28
    PORTD = 0b11111101;
29
    blink_();
30
    PORTD = 0b11111011;
31
    blink_();
32
    
33
    
34
  }
35
}
36
37
ISR(TIMER0_OVF_vect){
38
  static uint16_t cnt= 0;
39
  
40
  cnt++;
41
  
42
  if (cnt == 7812){
43
    cnt=0;
44
    second_tick = 1;
45
  }
46
  
47
}
48
49
void blink_(void){
50
  
51
  PORTB= 0x00; //Turns on All LEDs
52
  while(!second_tick);
53
  second_tick=0;
54
  
55
  PORTB = 0xFF;   //turn off all leds
56
  while(!second_tick); //wait till time is over
57
  second_tick=0;
58
  
59
  
60
}

von Stefan F. (Gast)


Lesenswert?

Finde erstmal mit einem einfacheren Programm heraus, ob deine Sekunden 
richtig gezählt werden. Lass dazu eine einfache LED (ohne 
Matrix-Schaltung) blinken.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Warum zum Teufel so ein Gemurkse? Warum machst du es nicht entweder 1. 
vernünftig in der Hauptschleife ohne die dabei zu blockieren oder 2. 
komplett in der ISR?

: Bearbeitet durch User
von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Achja und das Timing ist auch falsch:

F_CPU = 8.000.000 Hz
Timer Prescaler = 1024

8.000.000 Hz / 1024 = 7.812,5 Hz Timer Frequenz

Timer Überlauf bei 256 weil es ein 8 Bit Timer ist:
7.812,5 Hz / 256 = 30,5 Hz

Counter Compare Frequenz: 30,5 Hz / 7812 = 0,0039 Hz -> 256 Sekunden

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Tim T. schrieb:
> Warum zum Teufel so ein Gemurkse?

damit ist eigentlich schon alles gesagt!


Richard _. schrieb:
> volatile variable ist gesetzt wegen speicherzugriff im main und ISR

du hast ja echt den durchblick, ist aber trotzdem unsinn.

Richard _. schrieb:
> static uint16_t cnt= 0;

unnötig, da schon initialisiert.

Richard _. schrieb:
> if (cnt == 7812){

warum nicht gleich if (cnt == 42){ oder vielleicht doch besser 
symbolisch abbilden mit

F_CPU, prescaler?, ...

Richard _. schrieb:
> cnt=0;
> second_tick = 1;

warum man hier zwei variablen braucht bleibt wohl dein geheimnis?!

Richard _. schrieb:
>   PORTB= 0x00; //Turns on All LEDs
>   while(!second_tick);
>   second_tick=0;
>
>   PORTB = 0xFF;   //turn off all leds
>   while(!second_tick); //wait till time is over
>   second_tick=0;

das sieht nicht nur behindert aus ..., bäh!

dafür aber jetzt wieder intensiv frage-antwort spielchen ..., ich 
verstehe NICHT warum hier zeit investiert wird.


mt

von Peter D. (peda)


Lesenswert?

Richard _. schrieb:
> multiplex betrieb

Multiplex macht man grundsätzlich im Timerinterrupt und nicht anders.
Das Main bereitet nur die LED-Muster vor und schreibt sie in ein Array. 
Der Timerinterrupt gibt dann das Array mit der gewünschten 
Wiederholfrequenz aus, typisch >100Hz.

von Stefan F. (Gast)


Lesenswert?

Tim T. schrieb:
> Warum zum Teufel so ein Gemurkse? Warum machst du es nicht entweder 1.
> vernünftig in der Hauptschleife ohne die dabei zu blockieren oder 2.
> komplett in der ISR?

Vielleicht möchte er einfach ein bisschen experimentieren und die 
Vor-/Nachteile unterschiedlicher Ansätze erforschen. Ich glaube, du 
würdest den TO mit einer Antwort auf seine Frage wesentlich glücklicher 
machen.

Ich freue mich schon, dass er sich nicht auf delay() versteift hat.

von Stefan F. (Gast)


Lesenswert?

Peter D. schrieb:
> Multiplex macht man grundsätzlich im Timerinterrupt und nicht anders.

Das sollte man wohl begründen.

Der Grund ist, dass bei komplexeren Programmen die Schleife im 
Hauptprogramm nicht immer gleich lange für einen Durchlauf braucht. Bei 
einer gemultiplexten Anzeige führt dies zu unregelmäßigem Timing, was 
man als Flackern wahrnimmt.

von Gähn (Gast)


Lesenswert?

Apollo M. schrieb:
> das sieht nicht nur behindert aus ..., bäh!

Sehr nett

Apollo M. schrieb:
> dafür aber jetzt wieder intensiv frage-antwort spielchen ..., ich
> verstehe NICHT warum hier zeit investiert wird.

Dann lass es doch, dein Unfugsbeitrag vermisst wahrlich keiner. 100% 
Narzissmus 0% Hilfe.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Tim T. schrieb:
>> Warum zum Teufel so ein Gemurkse? Warum machst du es nicht entweder 1.
>> vernünftig in der Hauptschleife ohne die dabei zu blockieren oder 2.
>> komplett in der ISR?
>
> Vielleicht möchte er einfach ein bisschen experimentieren und die
> Vor-/Nachteile unterschiedlicher Ansätze erforschen. Ich glaube, du
> würdest den TO mit einer Antwort auf seine Frage wesentlich glücklicher
> machen.
>
> Ich freue mich schon, dass er sich nicht auf delay() versteift hat.

Naja, ich bin mir eigentlich sicher das der TO nur sein aktuelles 
Problem gelöst haben will, den Willen zum Experimentieren sehe ich da 
nirgendwo, ist anscheinend aus der Mode gekommen. Und was das delay 
angeht, klar könnte man sich freuen das nicht stumpf Takte verbraten 
werden, doch blöderweise hat er mit seinen blockierenden while 
Konstrukten noch was deutlich bescheuertes gebaut. Die delay Leute 
wissen eventuell nix von Timern und Interrupts, er aber schon und 
veranstaltet damit noch mehr Bockmist.

: Bearbeitet durch User
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.