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
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.
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...
Rush wrote: > Nun habe ich es auf einen mega8 geflasht und es tut sich leider > garnichts. Natuerlich tut sich nichts, was hast Du erwartet?
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
der Aufbau der Vektortabelle ist auch inkompatibel.... Gruss Otto
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.
Makefile anpassen. Dann könnte das auch passen. Und dann natürlich neu kompilieren.
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.
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.
Man vergisst auch ganz schnell mal, das Programm auch wirklich für einen ATMega8 zu kompilieren.
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!
Hier wurde geschrieben dass die Interruptvektoren nicht zusammenpassen. Hast du die schon geprüft? Sebastian
Was meckert er denn bei deiner delay funktion? Evtl. stimmt das Timing nicht ?!
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 | }
|
>../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);
Die Timer des Mega128 und Mega8 verwenden ebenfalls andere Einstellungen.
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.
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.
> 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.
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.
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.
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
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)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.