Forum: Compiler & IDEs If Problem Sekundenänderung


von Matthias T. (matthias_199)


Lesenswert?

Servus,

Ich baue grad an meiner Uhr und habe ein sehr stranges Problem.

Ich bekomme den AVR nicht überredet das er wenn sich die sekunde ändert 
er doch bitte meinen counter erhöht und alles in meinen Latch schiebt.

Das Finde ich extrem seltsam.

Wenn ich das aus der mein nehmen und für die ISR anpasse macht er genau 
das was ich will.

das ist aber nicht sinn der Sache.

MFG Matthias
1
[#ifndef F_CPU
2
#define F_CPU 1000000UL
3
#endif
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <stdint.h> 
7
#include <avr/interrupt.h>
8
9
const uint8_t bib[] = {95,12,155,158,204,214,215,28,223,222};
10
  
11
uint8_t sekunden = 0;
12
uint8_t alte_sekunden = 0;
13
uint16_t milisekunden = 0;  
14
uint8_t counter = 0;  
15
16
17
void Latch_Serialout(volatile uint8_t* Port ,uint8_t SER,uint8_t SCK,uint8_t DATEN);
18
void Latch_Setoutput(volatile uint8_t* Port,uint8_t RCK);
19
uint8_t Int_to_bcd(uint8_t Zahl ,uint8_t Pointflag);
20
21
22
23
24
int main(void)
25
{
26
  sei(); //Interrupts erlaube
27
  DDRD  = 0xFF;
28
  PORTD = (0<<PD0) | (0<<PD1)| (0<<PD2);
29
  
30
  DDRB |= (1<<PB1); // Port OC1A mit angeschlossener LED als Ausgang
31
  TCCR1A = (1<<WGM10) | (1<<COM1A1); // PWM, phase correct, 8 bit.
32
  TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10); // Prescaler 1 = Enable counter 1
33
  OCR1A = 200; // Duty cycle 50% (Anm. ob 128 oder 127 bitte prüfen)
34
  
35
  
36
  //DDRB |= (1<<PB2); // Port OC1B mit angeschlossener LED als Ausgang 
37
  //TCCR1A |= (1<<COM1B1); //Starte zweites PWM
38
  //OCR1B = 127;
39
  
40
  TCCR0 = (0<<CS02) | (1<<CS01) | (0<<CS00); // Prescaler 8 = Enable counter 0
41
  TIMSK |= (1<<TOIE0); //Interrupt ennabelen
42
  TCNT0 = 133; //Timer Preloaden
43
  
44
45
  
46
    
47
  while(1)
48
  {
49
    if(alte_sekunden != sekunden)
50
    {
51
      alte_sekunden = sekunden;
52
        Latch_Serialout(&PORTD,(1<<PD0),(1<<PD1),Int_to_bcd(counter,0));
53
        Latch_Setoutput(&PORTD,(1<<PD2));
54
        Latch_Serialout(&PORTD,(1<<PD0),(1<<PD1),0);
55
        Latch_Setoutput(&PORTD,(1<<PD2));  
56
      counter++;    
57
      if (counter > 9)
58
      {
59
        counter = 0;
60
      }
61
    }          
62
    //for (uint8_t x = 0;x <= 254;x++)
63
    //{
64
    //    OCR1A --;
65
    //  _delay_ms(500);
66
    //}
67
    //_delay_ms(1000);    
68
    //for (uint8_t x = 0;x <= 254;x++)
69
    //{
70
    //  OCR1A ++;
71
    //  _delay_ms(500);
72
    //}
73
    //_delay_ms(100);
74
75
    
76
    
77
  }
78
}
79
80
uint8_t Int_to_bcd(uint8_t Zahl, uint8_t Pointflag)
81
{
82
  if ((Zahl > 9) || (Zahl < 0))
83
  {
84
    return 0;
85
  }
86
  if (Pointflag > 0)
87
  {
88
    return bib[Zahl] + 32;
89
  }
90
  return bib[Zahl];   
91
}  
92
93
void Latch_Serialout(volatile uint8_t* Port ,uint8_t SER,uint8_t SCK,uint8_t DATEN)
94
// Die Funktion gibt ein Datenbyte an ein Latch (Schieberegister) weiter.
95
// SER pin 14 am Latch
96
// SCK pin 11 am Latch
97
// VORISCHT! Datenbyte würd umgedreht! Q0 = Q7 , Q1 = Q6 ..... usw
98
// Beispielaufruf Latch_Serialout(&PORTD,(1<<PD0),(1<<PD1),255);
99
{
100
  *Port &= ~SCK; //Serial clock ausmachen
101
  for (uint8_t x = 0;x < 8;x++) // Schleife für 8 bit = 1 Byte
102
  {
103
    if ((DATEN & 1) == 1){ // Wenn DATEN und Bitmaske (1) gleich sind
104
      *Port |= SER; //Setze SER Port High
105
    }
106
    *Port |= SCK; //SCK High setzen damit das Bit an Ser übernommen wird
107
    *Port &= ~SCK; //SCK Low setzen damit nichts mehr übernommen wird
108
    *Port &= ~SER; //SER Low Setzen da er schon übernommen wurde
109
    DATEN = (DATEN >> 1); // Schiebe die Daten um 1 nach rechts für die nächste stelle
110
  }
111
}
112
113
114
void Latch_Setoutput(volatile uint8_t* Port,uint8_t RCK)
115
// Die Funktion gibt ein Übernahme Signal an ein Latch (Schieberegister) weiter.
116
// RCK pin 12 am Latch
117
// Beispielaufruf Latch_Setoutput(&PORTD,(1<<PD2));
118
{
119
  //*Port &= ~RCK; // RCK auf 0 Setzen nur aktivieren falls es probleme gibt
120
  *Port |= RCK; // RCK auf High setzen damit die bits ins Output Register kommen
121
  *Port &= ~RCK; // RCk wieder low setzen
122
}
123
124
ISR (TIMER0_OVF_vect) //Timer 0 Überlauf Funktion
125
{
126
  TCNT0 = 133; // eigendlich 133
127
  PORTD ^= (1<<PD4); //toggeln
128
  milisekunden ++ ;
129
  if (milisekunden > 999)
130
  {
131
    sekunden++;
132
    milisekunden = 0;
133
  }
134
  //if  (PIND & (1<<PIND4))
135
  //{
136
  //  Latch_Serialout(&PORTD,(1<<PD0),(1<<PD1),255);  
137
  //}
138
  //else
139
  //{
140
  //  Latch_Serialout(&PORTD,(1<<PD0),(1<<PD1),0);
141
  //}
142
  //Latch_Setoutput(&PORTD,(1<<PD2));
143
}

von Timmo H. (masterfx)


Lesenswert?

1
 volatile uint8_t sekunden = 0;
und die Millisekunden kannst du auch als Static in der isr machen

von Matthias T. (matthias_199)


Lesenswert?

Das wars ^^
Aber nachts kommt mann da nimmer drauf und wenn man in c aufm pc coded 
benutzt man volatile so gut wie garnicht.


das mit dem static milisekunden ist ein guter tipp hab ich vergessen das 
mann da so schöner lösen kann.

aber dann kann ich doch auch aus
1
const uint8_t bib[] = {95,12,155,158,204,214,215,28,223,222};

in meine Int_to_bcd packen
1
static const uint8_t bib[] = {95,12,155,158,204,214,215,28,223,222};

Damit se nicht im head der File rumgammelt und später verloren geht.

MFG Matthias

von (prx) A. K. (prx)


Lesenswert?

Matthias T. schrieb:
> wenn man in c aufm pc coded benutzt man volatile so gut wie garnicht.

Doch. Wenn man multithreaded programmiert.

von Matthias T. (matthias_199)


Lesenswert?

A. K. schrieb:
> Doch. Wenn man multithreaded programmiert.

Jo hast recht aber bis jetz ist mir persöhnlich keine Anwendung 
untergekommen, und wird dir als normaler mensch wohl nicht, das es nötig 
wäre.
außer du hast vor cryengine nachzuschreiben oder ein Treiber.
aber wie gesagt wer macht das also normalo^^

von (prx) A. K. (prx)


Lesenswert?

Matthias T. schrieb:
> und wird dir als normaler mensch wohl nicht, das es nötig wäre.

Dann bin ich offensichtlich kein normaler Mensch.

> außer du hast vor cryengine nachzuschreiben oder ein Treiber.
> aber wie gesagt wer macht das also normalo^^

Programmierung mit mehreren Threads setzt nicht voraus, dass die 
Hardware auch mehrere Threads parallel ausführen kann. Das hat nicht nur 
mit Performance zu tun, sondern auch mit Ablaufstrukturen. Ich habe auch 
auf einem AVR schon mit einem RTOS-Kernel gearbeitet.

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.