Problem mit einem 1sec takt

Gast #2850702
Lesenswert?

Hallo erstmal
Also zu meinem Problem ich hab ein C programm für eine Uhr mit meinen
attiny 2313 geschrieben die formel ist doch bei 8 bit prescala 256
(4194304/256)/256/64 = 1Hz
d.h: 64 überläufe
aber um einen ungefären sec takt zu erzeugen muss ich nicht sechs 
überläufe zählen sondern 16 aber warum
1
/*
2
 * LED_Display.c
3
 *
4
 * Created: 31.08.2012 18:47:22
5
 *  Author: Sausy
6
 */
7

8

9
#define XTAL 4194304
10
#define F_CPU XTAL
11

12
#define HIGH  1
13
#define LOW   0
14

15
#include <avr/io.h>
16
#include <avr/interrupt.h>
17
#include <util/delay.h>
18
#include "LED_Disp.h"
19

20
volatile int sec_temp;  // seconds counter
21
int overflow_c = 0;
22

23
ISR(TIMER0_OVF_vect)  // 1 second clock
24
{  if(overflow_c < 16)     //(4194304/256)/256 = 64 mal = 1sec
25
       overflow_c++;       //eigentlich 64 mal 
26

27
  if(overflow_c >= 16){    //für sec++
28
    overflow_c = 0;
29
    sec_temp++;
30
  }
31
}
32

33

34
int main(void)
35
{  int  hr=9, min=0, sec=0;   //set start time
36
  inite_LED_D();              //inizalisiert LED display
37

38
  DDRB &= ~(1<<PB0);
39
  PORTB &= ~(1<<PB0);
40
  DDRB |= (1<<PB1);
41

42

43
  //----[ initialize timer1 ]---
44
  TIMSK |= _BV(TOIE0);   // erlaubt overflow interupt --
45
                        //aktiviert den overflow interrupt des timer1
46
  TCCR0B |= (1<<CS02);  // prescaler = 256
47
  TCNT0 = 0x00;
48
  sei();
49

50
  while(1)
51
  {
52
    number_output (hr*100+min); // setz die Variablen
53
                                // für meinen Led display
54
    {  sec=tc;
55
      if (sec>=60)
56
      {  tc=0; sec=0; min++;
57
        if (min>=60)
58
        {  min=0; hr++;
59
          if (hr>=12) hr=0;
60
        }
61
      }
62
    }
63
    while (sec==tc)  refresh(); //refrescht das bild
64
  }
65
  return(0);
66
}
Gast #2850713
Lesenswert?

64/16 - das klingt verdächtig nach Faktor 4.194304MHz/1MHz. ∗Überprüf∗ 
mal ob der t2313 wirklich mit Quarz läuft oder nicht vielleicht doch mit 
den Standardeinstellungen (8Mhz interner RC mit CKDIV8).
Gast #2850715
Lesenswert?

>#define XTAL 4194304

Für diese "Behauptung" sollte man das Teeren und Federn wieder 
einführen.

Vermutlich wird entweder Dein Takgenerator die vierfache Frequenz 
erzeugen oder Deine Teilerfaktoren sind falsch berechnet oder falsch 
gesetzt.

Prüf' es doch einfach nach! Was meinst Du was wir machen würden? Beten? 
Einen Regentanz?
Gast #2850723
Lesenswert?

Auf die Schnelle fallen mir zwei Sachen auf:
1. Zeitverschwendung in der Interrupt Routine.
2. Guck mal nach wie groß ein int ist. Mach dein Compiler daraus 2 
Bytes, so musst Du beim Lesen "sec_temp" aufpassen dass Dir keine 
Unterbrechung zwischen das Lesen der zwei Bytes kommt. Ein unsigned char 
reicht für 0 ... 60 auf jeden Fall aus und beseitigt dieses Problem. 
Darüber hinaus sparst Du Speicherplatz.
#2851576
Lesenswert?

Sausy schrieb:
> thx für die schnellen antworten
>
> Ich werde mal das quarz überprüfen und ggf. austauschen

Austauschen kannst du dir sparen.
Aktivier ihn lieber erst mal.

Falls er aktiv ist, dann läuft der auch. Sonst würde dein µC gar nicht 
arbeiten.

Aber die Vermutung ist eher: Der Quarz hängt zwar physisch am µC, aber 
dem µC hat keiner (mittels Fuse-Bits) mitgeteilt, dass da ein Quarz 
vorhanden ist. Also benutzt er ihn auch nicht.
(Firma: matzetronics) #2851760
Lesenswert?

amateur schrieb:
> 2. Guck mal nach wie groß ein int ist. Mach dein Compiler daraus 2
> Bytes, so musst Du beim Lesen "sec_temp" aufpassen dass Dir keine
> Unterbrechung zwischen das Lesen der zwei Bytes kommt. Ein unsigned char
> reicht für 0 ... 60 auf jeden Fall aus und beseitigt dieses Problem.

Und das gilt m.E. auch für alle anderen Variablen in diesem Programm. 
uint8_t oder char reichen für alles hier. Nur etwaige Tage des Jahres 
oder das Jahr selber bräuchten words. Damit lösen sich etwaige atomic 
access Probleme in Luft auf.
Gast #2851892
Lesenswert?

@Matthias
Das stimmt zwar, aber die Anzahl an Variablen, die in der/einer 
Interruptroutine verändert werden und von außen befummelt werden, ist 
exakt gleich eins.

Sollten aber noch ein paar, hier nicht aufgeführte, da sein, so lautet 
mein Vorschlag: Optimieren sowie optimieren als auch optimieren.
Sollte das Teil aber nur Ticken und Anzeigen, so vergiss es.
#2851896
Lesenswert?

amateur schrieb:
> @Matthias
> Das stimmt zwar, aber die Anzahl an Variablen, die in der/einer
> Interruptroutine verändert werden und von außen befummelt werden, ist
> exakt gleich eins.

Es geht weniger um das Zeitproblem, sondern um das Problem des atomaren 
Zugriffs.
Gut, da seine Variablen nur Wertebereiche kleiner 255 haben, ist das 
hier im konkreten kein Problem, weil das High-Byte sowieso immer 0 ist. 
Aber generell ist man gut beraten, wenn man den kleinsten Datentyp 
nimmt, der passend ist. Wenn geht, dann uint8_t oder int8_t. Und bei ihm 
geht problemlos.

Und über die Sache mit der 1 Variable reden wir mit dem TO noch mal, 
wenn er die Sache mit dem Takt auseinanderdividiert hat. Denn in dem 
Fall ist das nicht besonders schlau. Die Minuten und Stundenerhöhung 
gehört mit in die ISR hinein. Die Uhr muss als Ganzes interruptgetrieben 
weiterlaufen. Selbst dann, wenn in der Hauptschleife 2 Millionen 
teuflisch schwierige quadratische Gleichungen zu lösen sind und 
zwischendurch 58 _delay_ms( 10000 ) gemacht werden.
Gast #2853346
Lesenswert?

Also der sec takt funktioniert jetz

@ Karl Heinz Buchegger
>Aber die Vermutung ist eher: Der Quarz hängt zwar physisch am µC, aber
>dem µC hat keiner (mittels Fuse-Bits) mitgeteilt, dass da ein Quarz
>vorhanden ist. Also benutzt er ihn auch nicht.

Du hattest recht ich hatte vergessen die fuses zu setzen

P.S.: Die größe der varialen hab ich auch gändert


thx für alle antworten

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren