Forum: Mikrocontroller und Digitale Elektronik Prog. läuft auf Mega128 aber nicht auf Mega8!


von Rush (Gast)


Lesenswert?

Hi Leute...

Ich habe da ein kleines Problem.
Undzwar habe ich eine kleine Temperaturregelung geschrieben (WinAVR). 
Das Programm läuft auch einwandfrei auf meinem mega128 Testboard.

Nun habe ich es auf einen mega8 geflasht und es tut sich leider 
garnichts.
Ich habe die Ports abgeändert, die Quarzfrequenz angepasst, aber es tut 
sich leider überhaupt nicht. Das Display zeigt auch nichts an außer 
haufen schwarze Kästchen.

Platine ist auch korrekt aufgebaut und durchgemessen.

Der mega8 ist auch in Ordnung, habe alle Ports gecheckt.

Hat jemand eine Idee woran das liegen könnte?

Gruß, Konrad

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Die Registerzuordnung und auch der Aufbau und die Anzahl der eingebauten 
peripheren Module ist bei beiden Controllern unterschiedlich. Es ist ein 
Wunder, wenn Du das Programm vom 128er für den 8er überhaupt assembliert 
bzw. kompiliert bekommst.

von Sven P. (Gast)


Lesenswert?

Travel Rec. wrote:
>wenn Du das Programm vom 128er für den 8er überhaupt assembliert
> bzw. kompiliert bekommst.

Hatter ja scheinbar auch nich, er hat einfach das HEX für den 128er auf 
den 8er gebrannt...
Ne Jungchen, das geht schief...

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Rush wrote:

> Nun habe ich es auf einen mega8 geflasht und es tut sich leider
> garnichts.

Natuerlich tut sich nichts, was hast Du erwartet?

von Sebastian (Gast)


Lesenswert?

Du musst auf jeden Fall noch das Include-File mit den 
Registerdefinitionen austauschen und den Code neu assemblieren. Sonst 
hast du keine Chance.

Viel Spass mit den Fehlermeldungen ;-)

Sebastian

von Otto (Gast)


Lesenswert?

der Aufbau der Vektortabelle ist auch inkompatibel....

Gruss Otto

von Jadeclaw D. (jadeclaw)


Lesenswert?

An die anderen: Startposting komplett gelesen?
Zitat:""Ich habe die Ports abgeändert, die Quarzfrequenz angepasst,
aber es tut sich leider überhaupt nicht. Das Display zeigt auch nichts 
an außer haufen schwarze Kästchen.""

Um das zu machen, muß man neu übersetzen.
Jetzt gibt es zwei Möglichkeiten:
Entweder falsches HEX-File erwischt oder es wurden Eigenheiten des 
Mega128 übersehen, die jetzt da noch drin sind. Wenn die Übersetzung 
über AVRStudio erfolgt, muß der CPU-Typ auch in den Projekteigenschaften 
geändert werden, bei Direktübersetzung per Makefile ist dort evtl. der 
CPU-Typ zu ändern, Austausch der Include-Datei alleine reicht da nicht. 
Also dies nochmal prüfen.

Gruß
Jadeclaw.

von Henrik J. (henrikj)


Lesenswert?

Makefile anpassen. Dann könnte das auch passen. Und dann natürlich neu 
kompilieren.

von Christian U. (z0m3ie)


Lesenswert?

Er hat noch nicht mal gesagt was für ne Sprache und schon spekulieren 
alle wild umher ohne auch nur ansatzweise das Problem zu kennen.

Beschreib mal etwas genauer was du da versuchst.

von Jadeclaw D. (jadeclaw)


Lesenswert?

Christian, es steht drin.
Ich lese folgendes aus der Frage heraus:
CPU: AVR Mega-Series, ATMega128/8
Sprache: C
Compiler: GCC mit avrlib
Toolchain: WinAVR
Display: Text, HD44780-basiert
Auch der Fehler ist klar, das Display wird entweder garnicht oder nicht 
korrekt initialisiert. HD44780-Diplays zeigen in diesem Falle genau das 
genannte Bild. Kontrasteinstellung muß ok sein, am Mega128 geht es ja, 
falls der Fragesteller da zwischenzeitlich nichts verstellt hat.

Ich gehe davon aus, daß die Initialisierung des Displays nicht korrekt 
erfolgt, entweder weil das Timing daneben ist oder der Initcode nicht 
erreicht wird, weil irgendwo noch eine Programmschleife darauf wartet, 
daß irgendeine beim ATMega8 nicht vorhandene oder anders beschaltete 
Hardware antwortet. Sowas in der Art hatte ich auch schon erlebt und mir 
echt 'nen Wolf gesucht.

Gruß
Jadeclaw.

von holger (Gast)


Lesenswert?

Man vergisst auch ganz schnell mal, das Programm
auch wirklich für einen ATMega8 zu kompilieren.

von Rush (Gast)


Lesenswert?

Also wenn ich doch schreibe dass ich das Prog unter WinAVR geschrieben 
habe müsste doch eigentlich klar sein dass ich es in C geproggt habe.

Ok, also nochmal in der Zusammenfassung was ich überhaupt gemacht habe:

- Fuses des mega8 auf Internes Quarz 8Mhz gesetzt
- defines für die Frequenz entsprechend angepasst
- defines der Ports entsprechend angepasst
- Controllertyp in den Projekteigenschaften ebenfalls auf mega8 gestellt
- in den Projekteigenschaften zusätzlich die Frequenz von 8 Mhz 
eingetragen.

Der Compiler hat außer einer Warnmeldung zu meiner delay-Funktion nichts 
anderes ausgespuckt. Darüber mal hinweggesehen. Es müsste sich 
wenigstens ein Messwert auf dem LCD zeigen.

@ Michael G.
Was erwartest du denn wenn du ein Programm auf nen Controller schiebst? 
Wohl dass es läuft!

von Sebastian (Gast)


Lesenswert?

Hier wurde geschrieben dass die Interruptvektoren nicht zusammenpassen. 
Hast du die schon geprüft?

Sebastian

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

Was meckert er denn bei deiner delay funktion? Evtl. stimmt das Timing 
nicht ?!

von Rush (Gast)


Lesenswert?

Ich verwende keine Interrupts.

Und wegen dem delay sagt der:

../TempControlMega8.c:114: warning: conflicting types for 'long_delay'

Die Funktion dazu sieht so aus:
1
void long_delay(uint16_t ms) {        
2
    for(; ms>0; ms--) _delay_ms(1);      
3
}

von holger (Gast)


Lesenswert?

>../TempControlMega8.c:114: warning: conflicting types for 'long_delay'

Da ist wohl der Prototyp für long_delay() faul, oder es gibt
bereits eine Funktion long_delay() in irgendeiner LIB.

>Die Funktion dazu sieht so aus:
>
>void long_delay(uint16_t ms) {
>    for(; ms>0; ms--) _delay_ms(1);
>}

Ich hasse solche for() Schleifen.
Mach es einfach so:

 while(ms--) _delay_ms(1);

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Die Timer des Mega128 und Mega8 verwenden ebenfalls andere 
Einstellungen.

von Rush (Gast)


Lesenswert?

Ich verwende auch keinen Timer.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Rush wrote:

> @ Michael G.
> Was erwartest du denn wenn du ein Programm auf nen Controller schiebst?
> Wohl dass es läuft!

Wenn der Code korrekt und die Target-Plattform die richtige ist, schon. 
Das ist in diesem Fall aber nicht so, daher brauchst Du auch nicht 
erwarten, dass es funktioniert. Der Grund sollte einleuchten.

von Christian U. (z0m3ie)


Lesenswert?

Sorry hatte das mit dem WinAVR überlesen.

Oft ist es bei Displays so das tatsächlich das timing nicht stimmt.
Wenn deine delay Funktion irgendwo anders deklariert wurde z.b. leer und 
die Display routinen darauf aufbaun passiert genau das beschriebene.

von Karl H. (kbuchegg)


Lesenswert?

> Der Compiler hat außer einer Warnmeldung zu meiner delay-Funktion
> nichts anderes ausgespuckt.

Welche war das?
Nicht alle Warnungen sind harmlos

> Darüber mal hinweggesehen.

Das ist bei manchen Warnungen keine gute Idee

> Es müsste sich wenigstens ein Messwert auf dem LCD zeigen.

Wenn deine LCD Routinen auf diesem delay basieren, dann nicht
unbedingt.

Am besten zeigst du mal den Code. Dann hört auch das Rätselraten
auf.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Treat Warnings as Errors ;)

von Rush (Gast)


Lesenswert?

Oje... den Code wollt ihr also sehen... aber nicht wundern, bin blutiger 
Anfänger ;)
1
// Display an PORTC
2
// MAX6675 an PORTB
3
// Taster an PORTD
4
// Output Relais an PORTD
5
6
7
#include <stdint.h>
8
#include <stdlib.h>
9
#include <string.h>
10
#include <avr/io.h>
11
#include <util/delay.h>
12
#include "lcd-routines.h"
13
14
extern void lcd_init(void);
15
extern void lcd_clear(void);
16
extern void set_cursor(uint8_t x, uint8_t y);
17
extern void lcd_string(char *data);
18
19
/* Defines MAX !!*/
20
21
#define MAX_DDR DDRB
22
#define MAX_PORT PORTB
23
#define MAX_PIN PINB
24
25
#define CS PB0
26
#define SCK PB1
27
#define SO PB2
28
// ------------------------- //
29
/* Defines Menütasten */
30
31
#define  MENU_DDR DDRD
32
#define  MENU_PIN PIND
33
#define  MENU_PORT PORTD
34
35
#define MENU_SET PD2
36
#define MENU_UP PD0
37
#define MENU_DOWN PD1
38
// ------------------------- //
39
/* Defines Relais */
40
#define REL_OUT_DDR DDRD
41
#define REL_OUT_PORT PORTD
42
#define REL_OUT PD7
43
// ------------------------- //
44
45
// ---------- Temp. holen -----------
46
uint16_t gettemp(void){                  
47
  uint8_t bit = 0, bitnr = 12;          
48
  uint8_t foo1 = 0;
49
  uint16_t Rohdata = 0;
50
51
  
52
  MAX_PORT &= ~(1 << CS);  
53
54
  for(foo1 = 0 ; foo1 < 16 ; foo1++){
55
56
    bit = 15 - foo1;
57
  
58
59
    MAX_PORT |= (1 << SCK);  
60
  
61
62
    if((bit <= 14) && (bit >= 3)){
63
64
      if((MAX_PIN & (1 << SO))){
65
        bitnr--;
66
        Rohdata |= (1 << bitnr);
67
      }else{
68
        bitnr--;
69
        Rohdata &= ~(1 << bitnr);
70
      } 
71
72
    }else{
73
      bitnr = 12;
74
    }
75
76
    MAX_PORT &= ~(1 << SCK);
77
  
78
  }
79
80
81
  MAX_PORT |= (1 << CS);
82
    
83
84
  return Rohdata;  //gibt die 12 relevanten Bits zurück
85
  }
86
87
// ----------- Long Delay -------------------
88
void long_delay(uint16_t ms) {        
89
    for(; ms>0; ms--) _delay_ms(1);      
90
  //while(ms--) _delay_ms(1);
91
}
92
// ------------------------------------------
93
94
//------------ Taster entprellen ------------
95
96
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
97
{
98
    if ( ! (*port & (1 << pin)) )
99
    {
100
        /* Pin wurde auf Masse gezogen, 100ms warten   */
101
        long_delay(110);  // max. 262.1 ms / F_CPU in MHz
102
        if ( *port & (1 << pin) )
103
        {
104
            /* Anwender Zeit zum Loslassen des Tasters geben */
105
            long_delay(50);
106
            return 1;
107
        }
108
    }
109
    return 0;
110
}
111
//-------------------------------------------
112
113
114
void initavr(void){              //AVR initialisieren
115
116
  MAX_DDR &= ~(1 << SO);          
117
  MAX_DDR |= ((1 << CS) | (1 << SCK));
118
  
119
  MAX_PORT |= (1 << CS);          
120
  MAX_PORT &= ~(1 << SCK);
121
122
}
123
124
125
int main(void)
126
{
127
  char MenuVal;
128
  char intMaxTemp;
129
  int intMaxTempCompare;
130
  char strMaxTemp[3];
131
132
  char intOffset;
133
  char intOffsetCompare;
134
  char strOffset[3];
135
136
  initavr();
137
  lcd_init();
138
  MENU_DDR &=~ (1<<MENU_SET) | (1<<MENU_UP) | (1<<MENU_DOWN);    
139
  MENU_PORT |= (1<<MENU_SET) | (1<<MENU_UP) | (1<<MENU_DOWN);    
140
  
141
        REL_OUT_DDR |= (1<<REL_OUT);    // Ausgang für Relais
142
  REL_OUT_PORT |= (1<<REL_OUT);
143
144
  MenuVal = 0;
145
  intMaxTemp = 187;
146
  intOffset = 0;
147
148
while(1){
149
  char temp[7]; 
150
  double temperature;
151
152
  
153
  if (debounce(&MENU_PIN, MENU_SET)==1)        
154
    {
155
      MenuVal++;
156
    }
157
158
  if (MenuVal == 3)  // beim letzten Menü auf Temp.Anzeige wechseln
159
    {
160
      MenuVal=0;
161
    }
162
163
164
switch (MenuVal){
165
  case 0:
166
    temperature = gettemp();  
167
  
168
    intMaxTempCompare = intMaxTemp * 4;
169
    intOffsetCompare = intOffset * 4;  
170
    temperature = temperature + intOffsetCompare;
171
172
    if (temperature < intMaxTempCompare)  
173
    {
174
      temperature = (temperature / 4);
175
      dtostrf(temperature, 2, 2, temp);
176
      long_delay(200);
177
      lcd_clear();
178
      lcd_string(temp);
179
      set_cursor(0,2);
180
      lcd_string("Heizung an!");
181
      REL_OUT_PORT &=~ (1<<REL_OUT);        
182
    }
183
184
    if (temperature >= intMaxTempCompare)
185
    {
186
      temperature = (temperature / 4);
187
      dtostrf(temperature, 2, 2, temp);
188
      long_delay(200);
189
      lcd_clear();
190
      lcd_string(temp);
191
      set_cursor(0,2);
192
      lcd_string("Heizung aus!");
193
      REL_OUT_PORT |= (1<<REL_OUT);        
194
    }break;
195
  
196
  case 1:
197
    lcd_clear();
198
    set_cursor(0,1);
199
    lcd_string("Set max. Temp.");
200
    set_cursor(0,2);
201
    if (debounce (&MENU_PIN, MENU_UP)==1)
202
      {
203
        intMaxTemp++;
204
      }
205
    
206
    if (debounce(&MENU_PIN, MENU_DOWN)==1)
207
      {
208
        intMaxTemp--;
209
      }
210
    itoa(intMaxTemp, strMaxTemp, 10);  
211
212
    lcd_string(strMaxTemp);
213
    long_delay(23);
214
    break;
215
  
216
  case 2:
217
    lcd_clear();
218
    set_cursor(0,1);
219
    lcd_string("Set Offset Temp.");
220
    set_cursor(0,2);
221
    if (debounce(&MENU_PIN, MENU_UP)==1)
222
      {
223
        intOffset++;
224
      }
225
    
226
    if (debounce(&MENU_PIN, MENU_DOWN)==1)
227
      {
228
        intOffset--;
229
      }
230
    itoa(intOffset, strOffset, 10);
231
    lcd_string(strOffset);
232
    long_delay(23);
233
    break;}
234
235
236
  }
237
}


Nochmal was im Nachhinein. Ich habe am Schaltausgang parallel zum Relais 
noch eine LED mit drangehängt. Das würde doch bedeuten, auch wenn die 
Initialisierung des Displays nicht korrekt ist, meine LED trotzdem an 
oder aus gehen müsste wenn ich den Fühler mit einem Feuerzeug anheitze.

von Rush (Gast)


Lesenswert?

Also einen Fehler habe ich schonmal entdeckt. Undzwar hatte ich den 
RW-Pin des Displays nicht an GND gelegt. Kurz gelötet und es scheint als 
klappt die Initialisierung. Aber Test bekomme ich trotzdem nicht 
angezeigt. Auch nicht wenn ich einfach nur paar Zeilen schreibe die das 
Display initialisieren und einfach nun einen String ausgeben.

von Udo S. (udo)


Lesenswert?

Hallo Rush,

also den Teil kannst du dir sparen:
1
// ----------- Long Delay -------------------
2
void long_delay(uint16_t ms) {        
3
    for(; ms>0; ms--) _delay_ms(1);      
4
  //while(ms--) _delay_ms(1);
5
}

und überall wo du " long_delay " aufrufst schreibst du einfach 
"_delay_ms(n)"
wobei n=Anzahl der Millisekunden.
Außerdem ist die delay.h dahingehend geändert worden, das ohne weiteres 
auch über 262.1 ms eingegeben werden können. Also z.B. auch 
_delay_ms(1000)

Gruß
Udo

von ---=DIAN=--- (Gast)


Lesenswert?

Vielleicht könntest Du die lcd-routines.h und die dazugehörige 
lcd-routines.c auch nochmal posten?

ansonsten um alles andere auszuschliessen schonmal sowas wie:

int main(void)
{
  char MenuVal;
  char intMaxTemp;
  int intMaxTempCompare;
  char strMaxTemp[3];

  char intOffset;
  char intOffsetCompare;
  char strOffset[3];

  initavr();
  lcd_init();

  lcd_clear();
  set_cursor(0,2);
  lcd_string("Test");
}

ausprobiert? also nur das notwendigste?
Da der Mega8 kein JTAG usw. besitzt, scheiden die Fuses als Fehlerquelle 
nahezu aus. Prüfe doch nochmal die Verdrahtung, messen oder im Main Pin 
an- und abschalten und das messen (DB0-DB7[8bit] DB4-DB7/DB0-DB3[4bit] 
(weiß nicht mehr so genau was man bei 4bit braucht),EN,RS. RW liegt ja 
eh schon auf masse)

von Rush (Gast)


Lesenswert?

Also vorerst Entwarnung an alle ;-)
Das Ding läuft endlich.

Fehler die ich gefunden hatte:

- RW Pin des Displays lag nicht auf Masse.
- ein Pin (DB0-DB3), weiss nicht mehr genau welcher lag auf Masse.
  Evtl. hat das Display dann in 8-Bit Modus gewechselt oder zumindest 
8-Bit
  Daten erwartet. Verwende aber den 4-Bit Modus.

Nach diesen Änderungen bliebt das Display diesmal komplett leer.

Zum Schluss hatte ich einfach nochmal ein komplett neues Projekt 
angelegt wo von Anfang die Einstellunge für den mega8 vorgenommen 
wurden.

Desweiteren habe ich die abgeänderte (waren auch nur die Timings 
gewesen) durch die originale lcd-routines.c ersetzt.

Und siehe da es lief auf Anhieb.

lcd-routines.h und lcd-routines.c habe ich auch aus den Netz. Bei 
Interesse kann ich sie auch mal posten.

Danke für die Mühe die Ihr euch gemacht habt.

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.