Forum: Compiler & IDEs LCD funktioniert ab 4Mhz nicht mehr


von Tobias R. (mumum)


Lesenswert?

Ich habe ein Atmega 8 mit einem LCD (HD44780) im 4 Bit Modus.
Es Funktioniert auch alles super blos wenn ich den Internen Takt von
1 MHZ auf 4MHZ stellen will läuft das Programm normal aber mein LCD 
zeigt nur noch wirres Zeug.
Hintergrund ist das ich dan mal einen 8Mhz Quarzoszillator anschließen 
will damit meine Uhrzeit genau ist. Aber es Funktioniert ja noch 
nichtmal mit dem Internen 8 Mhz Takt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "lcd-routines.c"
4
#include <util/delay.h>
5
6
extern int sprintf(char *__s, const char *__fmt, ...);       //Umwandeln einer Zahl in einen String
7
8
volatile int timer=0;
9
volatile int z=0;                          // Toggle Variable für Sekunden
10
int  stunden=23, minuten=59, sekunden=0;             //hier bitte die Uhrzeit einstellen
11
int min_on=0, std_on=0;
12
int min_of=0, std_of=1;
13
char minutenstring[3], stundenstring[3];            //, sekundenstring[3];
14
char std_on_string[3], min_on_string[3], std_of_string[3], min_of_string[3];
15
16
17
ISR(TIMER1_OVF_vect){
18
  TCNT1 = 34286;
19
  timer++;
20
  z++;
21
  PORTB ^= (1<<PB0);  // PB0 ist Status-LED Ausgang
22
}
23
//###########################FENSTER_1##################################################################################
24
void FENSTER_1(void){
25
int x=1;
26
  lcd_clear();
27
  set_cursor (3, 1); lcd_string ("Uhrzeit");
28
  sprintf(stundenstring, "%d", stunden);
29
        set_cursor (3, 2);
30
        if (stunden<10) lcd_string ("0");
31
        lcd_string (stundenstring);
32
  sprintf(minutenstring, "%d", minuten);
33
        set_cursor (6, 2);
34
        if (minuten<10) lcd_string ("0");
35
        lcd_string (minutenstring);  
36
37
38
while (x){
39
40
if ((sekunden!=timer) && (PINC &(1<<PINC5) )) {      //Zeiteinstellschalter nicht gedrückt
41
42
      if (z<=1)   {set_cursor (5, 2);lcd_string (":");}    // Toggle den Sekundendoppelpunkt
43
      else     {set_cursor (5, 2);lcd_string (" ");z=0;}
44
45
      sekunden=timer;
46
      
47
      if (sekunden==60)      {          //Sekunde bis 60 Zählen dan 0
48
        timer=0;  sekunden=0; minuten++;
49
        
50
        if (minuten==60)  {            //Minute bis 60 Zählen dan 0
51
          minuten=0; 
52
          stunden++;
53
          if (stunden==24) stunden=0;
54
                  }
55
        
56
        sprintf(minutenstring, "%d", minuten);
57
        set_cursor (6, 2);
58
        if (minuten<10) lcd_string ("0");
59
        lcd_string (minutenstring);
60
          
61
        sprintf(stundenstring, "%d", stunden);
62
        set_cursor (3, 2);
63
        if (stunden<10) lcd_string ("0");
64
        lcd_string (stundenstring);
65
                    }
66
67
      if ((std_on==stunden)&&(min_on==minuten)) PORTD &= ~(1<<PD7);
68
      if ((std_of==stunden)&&(min_of==minuten)) PORTD |=  (1<<PD7);
69
                                             
70
                        }    
71
            
72
                
73
        
74
if (!(PINC &(1<<PINC5) ))             {  //Schalter für Zeiteinstellung 
75
76
      set_cursor (5, 2);lcd_string (":");
77
        
78
      if (!(PINC &(1<<PINC3) ))  {      //Stundeneinstellung
79
        stunden++;
80
        if (stunden==24) stunden=0;  
81
        sprintf(stundenstring, "%d", stunden);
82
        set_cursor (3, 2);
83
        if (stunden<10) lcd_string ("0");
84
        lcd_string (stundenstring);
85
        _delay_ms(255);
86
                    }
87
      if (!(PINC &(1<<PINC2) ))  {      //Minuteneinstellung
88
        minuten++;
89
        if (minuten==60) minuten=0;
90
        sprintf(minutenstring, "%d", minuten);
91
        set_cursor (6, 2);
92
        if (minuten<10) lcd_string ("0");
93
        lcd_string (minutenstring);
94
        _delay_ms(255);
95
                    }
96
      timer=0;
97
                        }
98
if (!(PINC &(1<<PINC1) )) x=0; 
99
      }
100
    }
101
//#########################FENSTER_2###########################################################################################
102
void FENSTER_2(void) {
103
char x=1;              // Fenster_Bit
104
char y=0;              // ON / OF Bit
105
106
107
108
  lcd_clear();
109
110
  while (x)  {
111
112
    sekunden=timer;
113
      
114
    if (sekunden==60)      {          //Sekunde bis 60 Zählen dan 0
115
      timer=0;  sekunden=0; minuten++;
116
        
117
      if (minuten==60)  {            //Minute bis 60 Zählen dan 0
118
        minuten=0; 
119
        stunden++;
120
        if (stunden==24) stunden=0;
121
                }  }
122
123
    set_cursor (3, 1); lcd_string ("Schaltzeit");
124
    set_cursor (6, 2);lcd_string ("bis");
125
    sprintf(std_on_string, "%d", std_on);  
126
    sprintf(min_on_string, "%d", min_on);        
127
    sprintf(std_of_string, "%d", std_of);
128
    sprintf(min_of_string, "%d", min_of);
129
130
    if (!(PINC &(1<<PINC5) )) {_delay_ms(200);y++;}
131
132
    //Zeige Einschaltzeit Stunde
133
    set_cursor (0, 2);
134
    if (std_on<10) lcd_string ("0");
135
    lcd_string (std_on_string);
136
137
    //Doppelpunkt
138
    set_cursor (2, 2);lcd_string (":");set_cursor (13, 2);lcd_string (":");
139
140
    //Zeige Einschaltzeit Minute
141
    set_cursor (3, 2);
142
    if (min_on<10) lcd_string ("0");
143
    lcd_string (min_on_string);
144
145
    //Zeige Ausschaltzeit Stunde
146
    set_cursor (11, 2);
147
    if (std_of<10) lcd_string ("0");
148
    lcd_string (std_of_string);
149
150
    //Zeige Ausschaltzeit Minute
151
    set_cursor (14, 2);
152
    if (min_of<10) lcd_string ("0");
153
    lcd_string (min_of_string);
154
155
      if (y==1)       {            //Einschaltzeit
156
        if (z<=1)   {set_cursor (2, 2);lcd_string (":");}    // Toggle den Sekundendoppelpunkt
157
        else     {set_cursor (2, 2);lcd_string (" ");z=0;}
158
        if (!(PINC &(1<<PINC3) ))  {      //Einschalt Stunde
159
          std_on++;
160
          _delay_ms(255);
161
          if (std_on==24) std_on=0;
162
                      }
163
                        
164
        if (!(PINC &(1<<PINC2) ))  {      //Einschalt Minute
165
          min_on++;
166
          _delay_ms(255);
167
          if (min_on==60) min_on=0;
168
                      }      
169
                }
170
171
      if (y==2)       {            //Ausschaltzeit
172
      if (z<=1)   {set_cursor (13, 2);lcd_string (":");}    // Toggle den Sekundendoppelpunkt
173
      else     {set_cursor (13, 2);lcd_string (" ");z=0;}
174
        if (!(PINC &(1<<PINC3) ))  {      //Ausschalt Stunde
175
          std_of++;
176
          _delay_ms(255);
177
          if (std_of==24) std_of=0;
178
                      }      
179
180
        if (!(PINC &(1<<PINC2) ))  {      //Ausschalt Minute
181
          min_of++;
182
          _delay_ms(255);
183
          if (min_of==60) min_of=0;
184
                  }      
185
            }
186
      if (y==3)  y=0;  
187
                    
188
          
189
      if (PINC &(1<<PINC1) ) {y=0;x=0;}
190
      }
191
  }
192
//#########################MAIN#################################################################
193
int main(void){
194
195
196
    DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2);         // Ausgang
197
  DDRC &= ~(1<<PC5) | ~(1<<PC3) | ~(1<<PC2) | ~(1<<PC1);  // Eingang
198
  PORTC|= (1<<PC5) | (1<<PC3) | (1<<PC2) | (1<<PC1);     //internen Pull-Up-Widerstand einschalten
199
  DDRD |=  (1<<PD7);PORTD |= (1<<PD7);          // Ausgang und erstmal AUS
200
  
201
  //Timer 1 initialisieren:
202
  TIMSK |= _BV(TOIE1);                       //aktivieren des �berlaufinterrupts von Timer1 
203
  TCCR1B = _BV(CS12);                       //Prescaler = 256
204
  TCNT1 = 0xFFFF;                         //Z�hlregister vorladen mit FFFF zum Sofortstart 
205
  
206
  sei();                              //Interrupts aktivieren
207
  
208
  lcd_init();
209
  lcd_clear();
210
  
211
  
212
  sprintf(stundenstring, "%d", stunden);  
213
  sprintf(minutenstring, "%d", minuten);        
214
                                  //  sprintf(sekundenstring, "%d", sekunden);
215
216
  
217
  
218
  while(1){
219
220
  if (PINC &(1<<PINC1) )      FENSTER_1();
221
222
  if (!(PINC &(1<<PINC1)) )  FENSTER_2();
223
224
    }    
225
 
226
  return(0);
227
  }

von G Ast (Gast)


Lesenswert?

Dann ist wohl dein Timing zum LCD falsch.
Es reicht auch nicht nur die Fuses zu verändern, dein Programm musst du 
bei Verwendung der delay_ms() mit der korrekten Frequenz auch neu 
compiliere.

Ansonsten: lcd-routines.c fehlt.

von Mike R. (thesealion)


Lesenswert?

Also ich tippe auf eine fehlerhafte initialisierung des LCDs :-)

Für eine genauere Analyse mußt du aber ein paar mehr Informationen 
liefern.

edit
Mist zu langsam :-)

Ansonsten fällt mir gerade noch auf: Hast du die CPU Frequenz auch im 
Makefile bzw. den Projekteinstellungen angepasst? Ansosnten kann die 
delay() Funktion nicht richtig arbeiten.

von Tobias R. (mumum)


Lesenswert?

Super danke also hat gereicht im Makefile 8MHZ einzustellen. So LCD 
Funktioniert jetzt aba die delay Funktion macht noch bisschen wirres 
Zeug muss man die Frequenz noch wo anders umstellen?

von Thomas K. (muetze1)


Lesenswert?

Warum zum Teufel inkludierst du eine .c Datei?

von MeinerEiner (Gast)


Lesenswert?

> #include "lcd-routines.c"

Pfui! Macht man nicht.

Eigentlich gibts nur 2 Stellen für die CPU-Frequenz, die zusammenpassen 
müssen: Die mit den Fuses eingestellten sowie F_CPU.
(Natürlich muss die Angabe auf dem Quarz dann zu F_CPU passen, wenn denn 
so einer verwendet wird).

Damit _delay_ms() & Co. richtig arbeiten, muss auch eine Optimierung 
aktiv sein. Mit -O0 arbeiten die nicht (richtig).

von Mike R. (thesealion)


Lesenswert?

Außerdem gibt es für die delay() Funktionen Obergrenzen, bis zu welcher 
Wartezeit die bei einer bestimmten Frequenz funktionieren.

von Oliver (Gast)


Lesenswert?

>Außerdem gibt es für die delay() Funktionen Obergrenzen, bis zu welcher
>Wartezeit die bei einer bestimmten Frequenz funktionieren.

Enee. Schon seit ewigen Zeiten (speich: avrlibc-Versionen) nicht mehr. 
Wie schreibt die Doku:

"...providing delays up to 6.5535 seconds (independent from CPU 
frequency). "

Die Genauigkeit wird ab einer CPU-frequenzabhängigen Wartezeit 
reduziert, aber gewartet wird. Das sollte für eine LCD-Ansteuerung bei 
weitem ausreichen.

Oliver

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.