Hallo Ich habe ein ATmega32 Prototype Board mit einem Siemens ME45 Handy verbunden. Mit dem Board frage ich das Handy mit dem Befehl AT+CCLK? um die Uhrzeit und den Datum, um es dann später in einen DS1307 RTC-Baustein schreiben zu können. Der string der da zum Board zurück gesendet wird der lautet: +CCLK: "11/05/28,19:09:29" OK Und hier meine Frage. Wie kann ich diese Daten einlesen, aufsplitten und in Variable reinschrieben so das ich es in denn RTC schreiben kann? Und gibt es da einen Befehl wo man z.B. den Teil innerhalb der Klammer nehmen kann? Danke im Voraus mfg Matthias Drexler
>Wie kann ich diese Daten einlesen, Datenblatt: UART > aufsplitten und in Variable reinschrieben so das ich es in denn RTC > schreiben kann? In C? Frag mal Google nach C-Standard-Library, alles was mit str(n) anfängt ist potentiell hilfreich. Header ist string(s?).h
ich habe in meiner string.h datei keinen strtok befehl. nur einen strtok_r befehl. wie bekomme ich denn strtok da rein das es auch funktioniert, denn einfach reinschreiben klappt nicht.
Matthias Drexler schrieb: > ich habe in meiner string.h datei keinen strtok befehl. > nur einen strtok_r befehl. > wie bekomme ich denn strtok da rein das es auch funktioniert, denn > einfach reinschreiben klappt nicht. Dann nimm eben strtok_r. Die Funktion ist sowieso besser als strtok.
was ist denn da der unterschied? hier sind nämlich 3 char typen in der klammer. der erste ist der string der zweite die trennzeichen und was ist der dritte char?
1. RTFM: PARAMETERS s1 Points to the string from which to extract tokens. s2 Points to a null-terminated set of delimiter characters. s3 Is a value-return parameter used by strtok_r() to record its progress through s1. 2. Da eine C-function nur einen return-wert hat (in diesem fall ein zeiger auf den extrahierten token oder einen NULL-pointer) behilft man sich, indem weitere return-values per Referenz (adresse) mit übergeben werden. Das genau wird mit dem s3 Parameter gemacht. Du solltest da also auf jeden Fall gültigen Speicherplatz (Variable, Zeiger - welcher Typ auch immer gefordert ist) übergeben, egal ob Du den Wert benutzen möchtest - sonst "übergibt" sich wahrscheinlich strtok_r(). gruss, Tom.
Einen solchen String: Matthias Drexler schrieb: > "11/05/28,19:09:29" von Hand zu zerlegen ist eigentlich etwas, das ganz dicht hinter den Grundlagen in C kommt. Die Funktionen in string.h sind eigentlich nur dazu da damit man das Rad nicht immer neu erfinden muss. Was würdest du denn machen, wenn du nur den Tag haben wolltest? ;)
Hallo Mathias, also für diesen String brauchst Du ein Array von 30 Zeichen. Nimm 40 Zeichen. Dann hast Du Reserve. Ich gehe davon aus, dass Du weißt, wie Du eine ISR benutzen mußt, um die empfangenen Daten aus der UART in ein charakter-Array zu kopieren. (Ich verstehe sonst das "einlesen" nicht...) Vorschlag: char string[40] = +CCLK: "11/05/28,19:09:29" char help[5]; int_16 jahr,monat,tag,stunde,minute,sekunde; Du kannst jetzt die strncmp-Funktion nehmen, um den Teilstring "+CCLK: " zu identifizieren. z.B. so: if(!strncmp(string,"+CCLK: ",7)) { uint_8 i=9; // Zeitstring gelesen. help[0] = string[i++]; help[1] = string[i++]; help[2] = 0; // jetzt ist das Jahr im help zu fuss kopiert. jahr = atoi(help); i++; // Komma überspringen help[0] = string[i++]; help[1] = string[i++]; help[2] = 0; // jetzt ist der Monat im help zu fuss kopiert. monat = atoi(help); und so weiter... } Ich habe die Erfahrung gemacht, dass die Standard-Stringfunktionen doppelten RAM verbrauchen. Der Vergleichsstring wird irgendwie 2 mal im RAM abgelegt. Jedenfalls ist bei mir der RAM weggeschmolzen. Ich bin dazu übergegeben, die Vergleichsstrings in der Flash abzulegen und mit den Funktion strcpy_P(...). Dann hatte ich wieder etwas mehr RAM zum Ahsen. Außerdem habe ich die Erfahrung gemacht, dass diese Antwortstrings von den GSM-Geräten immer irgendwie gemischt sind. Deshalb würde diese strtok-Funktion ebenfalls mehrmals eingesetzt werden müssen. Übersichtlicher wird das Programm dadurch nicht. Das zu Fuß kopieren ist primitiv aber effektiv und verständlich. Nur wenn Dir irgendwann SMS senden und im Empfangen mit PDU-Format vorschwebt, wirst Du damit nicht mehr allzu weit kommen. Ich hoffe, das hier was für Dich dabei ist. Viel Erfolg
cskulkw schrieb: > Der Vergleichsstring wird irgendwie 2 mal im > RAM abgelegt Wenn sich der Vergleichsstring während der Laufzeit nicht ändert kann man ihn auch direkt aus dem Flash lesen und muss ihn nicht erst ins RAM umkopieren:
1 | #include <avr/pgmspace.h> |
2 | .
|
3 | .
|
4 | .
|
5 | char[] string_im_RAM = "Ich werde zur Laufzeit im RAM zu finden sein!"; |
6 | char[] string_im_Flash PROGMEM= "Ich werde den Flashspeicher nicht verlassen!"; |
7 | .
|
8 | .
|
9 | .
|
Sowas spart RAM ;) Siehe hierzu auch: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38003
danke für die vielen und schnellen Antworten. ich werde mir die vorschläge anschauen und sie ausprobieren. mfg Matthias Drexler
Ich hätte da mochmal ne frage: Wie heist denn der Name der ISR der auslöst wenn über die com schnittstelle daten rein kommen? mfg Matthias
Bei diesem Befehl sagt er auch das dieser Befehl wahrscheinlich falsch geschrieben ist...... was könnte das sein?
Matthias Drexler schrieb: > Bei diesem Befehl sagt er auch das dieser Befehl wahrscheinlich falsch > geschrieben ist...... > was könnte das sein? Liegt wohl daran, dass ich ins falsche Datenblatt schaute. Hab aus irgend einem Grund ins Datenblatt zum Atmega88 geschaut statt ins Datenblatt vom Atmega32. Beim 32er heißt der Vector:
1 | ISR(USART_RXC_vect){} |
ich habe diesen befehl jetzt eingefügt aber dann sagt er mir folgendes: gcc plug-in: Error: Object file not found on expected location K:\AVR\AVR-Programme\Wechselrichter Störmeldeprogramm\default\WvS-Sample.elf und wenn ich eine WvS-Sample.elf datei einfüge löscht er sie mir wieder. was kann das jetzt sein?
Schau mal in den anderen Output-Tab im AVRStudio, dann siehst Du auch die richtige Fehlermeldung.
Öhm, also ich vermeide "Sonderzeichen" auch in Order- und Dateinamen. Also keine Leerzeichen, keine ä,ö,ü oder ß. Hat mir alles schon Probleme gemacht beim Programmieren. Der Dateipfad mit dem ö drin könnte hier auch eine Fehlerquelle sein.
Im anderen Tab steht folgendes: uart.o: In function `__vector_13': K:\AVR\AVR-Programme\WechselrichterStoermeldeprogramm\default/../uart.c: 260: multiple definition of `__vector_13' WvS-Sample.o:K:\AVR\AVR-Programme\WechselrichterStoermeldeprogramm\defau lt/../WvS-Sample.c:673: first defined here make: *** [WvS-Sample.elf] Error 1 und den dateipfad habe ich auch geändert und ist immer noch der gleich fehler
Wie schaut denn dein gesamter Code aus? Mich dünkt, da klemmts irgendwo bei dir. Und welchen Atmega verwendest du genau (und was soll dieser tun)? Sonst reden wir hier wohl nur um den heißen Brei.
tja herausfinden warum in uart.c zeile 260 "__vector_13" mehrfach definiert ist bzw. warum woanders nochmal definiert bzw. was überhaupt __vector_13 ist. Ich tippe auf den RXC interupt. du hast warscheinlich irgendeine definition ausversehen nocheinmal benutzt die schon in den standard includes vorkommt. Und ich würde mal an Zeile 673 in Date WvS-Sample.c reingucken ob das nur ein Fehler ist der durch den vorhergehende Fehler entstand.
Das vermute ich auch, Uwe. Genauer: In uart.c, Zeile 260 wird eine Funktion definiert, die schon in WsV-Sample.c, Zeile 673 definiert worden ist. Der eigentliche Fehler kann jetzt alles Mögliche sein, z.B. eine Klammer zuviel geschlossen in uart.c vor Zeile 260.
ich verwende einen ATMega32. Hier code ab zeile 672: ISR (USART_RXC_vect)//ISR (USART_RX_vect)//ISR (SIG_UART0_RECV) //RS232(UART)Interrupt { if (schutz == 1) //Schutz vor nicht benötigter Interruptauslösung { buffer = UDR; //Daten aus dem buffer lesen ..... while (!(UCSRA & (1<<UDRE))) //.... warten bis der Sende´buffer leer ist .... UDR = buffer; //.....und gleich wieder zurück schicken if (buffer != 26) //bei einem Return beginnnt die Auswertung, solange kein Return kommt, werden die Zeichen einfach nur gesammelt { string[f] = buffer; buffer = 0; f++; rprintf("buffer"); } else { schutz = 1; rs232_recieve(); schutz = 0; } } } Und im uart.h ab zeile 258: // UART Receive Complete Interrupt Handler UART_INTERRUPT_HANDLER(SIG_UART_RECV) { u08 c; // get received char c = inb(UDR); // if there's a user function to handle this receive event if(UartRxFunc) { // call it and pass the received data UartRxFunc(c); } else { // otherwise do default processing // put received char in buffer // check if there's space if( !bufferAddToEnd(&uartRxBuffer, c) ) { // no space in buffer // count overflow uartRxOverflow++; } } }
1 | #include <avr/io.h> |
2 | #include "global.h" // include our global settings |
3 | #include "i2cmaster.h" // Auskommentieren, falls nicht benötigt... |
4 | #include "lcd.h" |
5 | #include "adc.h" // include printf function library |
6 | #include <avr/interrupt.h> |
7 | #include <avr/wdt.h> |
8 | #include "string.h" |
9 | #include "timer.h" |
10 | #include <stdlib.h> |
11 | //#include <avr/signal.h>
|
12 | #include <stdio.h> |
13 | //#include "usart.h"
|
14 | //#include "uart.h"
|
15 | |
16 | |
17 | #define DS1307 0xd0 /* I2C Adresse unseres DS1307 Uhrenbausteins, write-Zugriff */ |
18 | #define USE_LCD 1 // 1 Falls LCD verwendet wird
|
19 | |
20 | // type declarations - Hier werden neue Typen für Variablen definiert
|
21 | typedef unsigned char uint8; /*!< vorzeichenlose 8-Bit-Zahl 0..255 */ |
22 | |
23 | // Hier die Variablen definieren, die im Programm verwendet werden sollen
|
24 | |
25 | uint8 i; // Eine Variable: Zahlenbereich 0..255 |
26 | |
27 | uint8 sec,minute,hour,wd,day,month,year; // Variablen für Zeit, Wochentag, Datum |
28 | |
29 | const char zeichen[] = ",:/"; |
30 | |
31 | char string[30]; |
32 | char *wert, empfang[20]; |
33 | |
34 | |
35 | int schutz = 0, buffer = 0, (f), (t) = 0; |
36 | |
37 | /*unsigned*/ char tempstr[20]; // temporärer String (Variable für eine Folge von Zeichen) |
38 | |
39 | // Definitionen für Unterprogramme
|
40 | void init(void); |
41 | void i2cGetdatetime(void); |
42 | void i2cSettime(void); |
43 | void i2cSetdate(void); |
44 | void rs232_recieve (void); //Fernsteuerung über RS-232 |
45 | |
46 | /*
|
47 | UART-Init:
|
48 | Berechnung des Wertes für das Baudratenregister
|
49 | aus Taktrate und gewünschter Baudrate
|
50 | */
|
51 | |
52 | #ifndef F_CPU
|
53 | /* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
|
54 | F_CPU im Makefile definiert werden, eine nochmalige Definition
|
55 | hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
|
56 | #ifndef/#endif
|
57 |
|
58 | Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio
|
59 | verwendet wird und dort eine andere, nicht zur Hardware passende
|
60 | Taktrate eingestellt ist: Dann wird die folgende Definition
|
61 | nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?)
|
62 | von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
|
63 | noch nicht definiert: */
|
64 | #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 14756000"
|
65 | #define F_CPU 14756000UL // Systemtakt in Hz - Definition als unsigned long beachten
|
66 | // Ohne ergeben sich unten Fehler in der Berechnung
|
67 | #endif
|
68 | |
69 | #define BAUD 9600UL // Baudrate
|
70 | |
71 | // Berechnungen
|
72 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
73 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
74 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
|
75 | |
76 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
77 | #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
|
78 | #endif
|
79 | |
80 | // Unterprogramm init: Hier werden die Initialisierungen vorgenommen
|
81 | void init(void) |
82 | {
|
83 | |
84 | wdt_disable(); // Watchdog ausschalten |
85 | |
86 | |
87 | // Port B initialisieren
|
88 | DDRB= 0xFF; // alle 8 pins sind als Ausgang geschaltet |
89 | |
90 | // Port A initialisieren
|
91 | DDRA= 0x00; // alle 8 pins sind als Eingänge geschaltet |
92 | |
93 | |
94 | PORTB= 0x00; // Alle unteren Pins sind low (Ruhestellung) |
95 | |
96 | timer0Init(); /* Mit diesem Befehl wird die include-Datei timer initialisiert, |
97 | die uns u.a. den Befehl timerPause() zur Verfügung stellt.
|
98 | */
|
99 | i2c_init(); // Initialisierung des I2C-Busses |
100 | |
101 | sei(); // Interrupts zulassen (für timer.c wichtig) |
102 | |
103 | |
104 | |
105 | #if USE_LCD
|
106 | lcd_init(LCD_DISP_ON); |
107 | #endif
|
108 | |
109 | lcd_clrscr(); // LCD löschen |
110 | |
111 | |
112 | |
113 | UCSRB |= (1<<TXEN); // UART TX einschalten |
114 | UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0); // Asynchron 8N1 |
115 | |
116 | UBRRH = UBRR_VAL >> 8; |
117 | UBRRL = UBRR_VAL & 0xFF; |
118 | |
119 | |
120 | |
121 | uartInit(); // initialize the UART (serial port) |
122 | uartSetBaudRate(9600); // serielle Schnittstelle auf 19200 Baud setzen |
123 | rprintfInit(uartSendByte); |
124 | |
125 | |
126 | |
127 | } // Ende init |
128 | |
129 | |
130 | uint8 bcd2hex(uint8 hexb) // Umwandlung von BCD nach Hex |
131 | // der DS1307 tickt in BCD
|
132 | {
|
133 | |
134 | u08 tempb1, tempb2; //lokale Variablen |
135 | |
136 | tempb1 = hexb >> 4; |
137 | tempb1 = tempb1 * 10; |
138 | tempb2 = hexb & 0x0F; |
139 | return (tempb1 + tempb2); |
140 | |
141 | }
|
142 | |
143 | uint8 hex2bcd(uint8 hexb) // Umwandlung von Hex nach BCD |
144 | {
|
145 | uint8 tempb1, tempb2; //lokale Variablen |
146 | |
147 | tempb1 = hexb / 10; |
148 | tempb2 = hexb % 10; |
149 | tempb1 = tempb1 << 4; |
150 | return (tempb1 | tempb2); |
151 | |
152 | }
|
153 | |
154 | |
155 | void i2cGetdatetime(void) // Holt Zeit,Datum von DS1307 |
156 | {
|
157 | unsigned char ret,isec,imin,ihour,iwd,iday,imonth,iyear; // Lokale Variablen |
158 | |
159 | |
160 | /* write 0x75 to eeprom address 0x05 (Byte Write) */
|
161 | ret = i2c_start(DS1307+I2C_WRITE); // set device address and write mode |
162 | if ( ret ) { |
163 | rprintf("I2cnotready",ret,"<<>>"); |
164 | /* failed to issue start condition, possibly no device found */
|
165 | i2c_stop(); |
166 | }else { |
167 | /* issuing start condition ok, device accessible */
|
168 | i2c_start_wait(DS1307+I2C_WRITE); // set device address and write mode |
169 | i2c_write(0x00); // write address = 0 |
170 | i2c_rep_start(DS1307+I2C_READ); // set device address and read mode |
171 | isec = i2c_readAck(); // read one byte and go on |
172 | imin = i2c_readAck(); // read one byte and go on |
173 | ihour = i2c_readAck(); // read one byte and go on |
174 | iwd = i2c_readAck(); // read one byte and go on |
175 | iday = i2c_readAck(); // read one byte and go on |
176 | imonth = i2c_readAck(); // read one byte and go on |
177 | iyear = i2c_readNak(); // read one byte and finish |
178 | i2c_stop(); // Stop i2c |
179 | sec = bcd2hex(isec); |
180 | minute = bcd2hex(imin); |
181 | hour = bcd2hex(ihour); |
182 | wd = iwd; |
183 | day = bcd2hex(iday); |
184 | month = bcd2hex(imonth); |
185 | year = bcd2hex(iyear); |
186 | |
187 | }
|
188 | }
|
189 | |
190 | |
191 | void i2cSettime(void) // setzt die Zeit im DS1307 |
192 | {
|
193 | unsigned char ret; |
194 | |
195 | |
196 | /* write 0x75 to eeprom address 0x05 (Byte Write) */
|
197 | ret = i2c_start(DS1307+I2C_WRITE); // set device address and write mode |
198 | if ( ret ) { |
199 | /* failed to issue start condition, possibly no device found */
|
200 | rprintf("\r\nKeine I2C-Uhr gefunden in SetTime!\r\n"); |
201 | i2c_stop(); |
202 | |
203 | }else { |
204 | /* issuing start condition ok, device accessible */
|
205 | i2c_start_wait(DS1307+I2C_WRITE); // set device address and write mode |
206 | i2c_write(0x00); // write address 0 |
207 | i2c_write(hex2bcd(sec)); // Sekunden |
208 | i2c_write(hex2bcd(minute)); // Minuten |
209 | i2c_write(hex2bcd(hour)); // Stunden |
210 | i2c_stop(); |
211 | |
212 | }
|
213 | }
|
214 | |
215 | void i2cSetdate(void) // setzt die Zeit im DS1307 |
216 | {
|
217 | unsigned char ret; |
218 | |
219 | |
220 | /* write 0x75 to eeprom address 0x05 (Byte Write) */
|
221 | ret = i2c_start(DS1307+I2C_WRITE); // set device address and write mode |
222 | if ( ret ) { |
223 | /* failed to issue start condition, possibly no device found */
|
224 | rprintf("\r\nKeine I2C-Uhr gefunden in SetDate!\r\n"); |
225 | i2c_stop(); |
226 | |
227 | }else { |
228 | /* issuing start condition ok, device accessible */
|
229 | i2c_start_wait(DS1307+I2C_WRITE); // set device address and write mode |
230 | i2c_write(0x03); // write address 0 |
231 | i2c_write(wd); // Wochentag |
232 | i2c_write(hex2bcd(day)); // Tag |
233 | i2c_write(hex2bcd(month)); // Monat |
234 | i2c_write(hex2bcd(year)); // Jahr |
235 | i2c_stop(); |
236 | }
|
237 | }
|
238 | |
239 | |
240 | |
241 | |
242 | void rs232_recieve (void) //Fernsteuereung über RS-232 |
243 | {
|
244 | |
245 | |
246 | //bei prgrammstart "rprintf("AT+CCLK?\r\n");" dann kommt +CCLK: "02/08/15,00:09:29"
|
247 | |
248 | string[f] = '\0'; //erst mal einen sauberen C-String daraus machen |
249 | |
250 | |
251 | wert = strtok(string, zeichen);// initialisieren und ersten Abschnitt erstellen |
252 | |
253 | |
254 | while(wert != NULL) |
255 | |
256 | {
|
257 | |
258 | empfang[t] = atoi(wert); |
259 | |
260 | wert = strtok(NULL, zeichen); |
261 | |
262 | t++; |
263 | |
264 | }
|
265 | |
266 | |
267 | |
268 | sec = empfang[5]; |
269 | minute = empfang[4]; |
270 | hour = empfang[3]; |
271 | day = empfang[2]; |
272 | month = empfang[1]; |
273 | year = empfang[0]; |
274 | i2cSettime(); // i2c Befehl zum Setzen der Zeit |
275 | i2cSetdate(); // i2c Befehl zum Setzen des Datums |
276 | |
277 | } //ende rs232_recieve |
278 | |
279 | |
280 | |
281 | int main (void) |
282 | {
|
283 | |
284 | |
285 | init(); // Aufruf des Unterprogramms init |
286 | |
287 | |
288 | while (!(UCSRA & (1<<UDRE))) // warten bis Senden moeglich |
289 | {
|
290 | }
|
291 | |
292 | rprintf("AT+CCLK?\r\n"); |
293 | timerPause(1000); |
294 | |
295 | |
296 | |
297 | |
298 | while (1) // Endlosschleife |
299 | {
|
300 | |
301 | lcd_clrscr(); |
302 | lcd_puts("Kontrolle l\xE1uft"); |
303 | i2cGetdatetime(); // Hier werden die Variablen für Zeit und Datum aktualisiert |
304 | lcd_gotoxy(15,1); |
305 | sprintf(tempstr,"%02d",hour); |
306 | lcd_puts(tempstr); |
307 | lcd_puts(":"); // : zwischen stunde und minute |
308 | sprintf(tempstr,"%02d",minute); |
309 | lcd_puts(tempstr); |
310 | |
311 | |
312 | PORTB |= (1<<PB0); |
313 | timerPause(300); |
314 | PORTB &= ~(1<<PB0); |
315 | |
316 | PORTB |= (1<<PB1); |
317 | timerPause(300); |
318 | PORTB &= ~(1<<PB1); |
319 | |
320 | PORTB |= (1<<PB2); |
321 | timerPause(300); |
322 | PORTB &= ~(1<<PB2); |
323 | |
324 | |
325 | PORTB |= (1<<PB3); |
326 | timerPause(300); |
327 | PORTB &= ~(1<<PB3); |
328 | |
329 | } // ende Endlosschleife |
330 | |
331 | |
332 | } // Ende main (Hauptprogramm) |
333 | |
334 | |
335 | |
336 | ISR (USART_RXC_vect) //SIGNAL (SIG_UART_RECV) //ISR (SIG_USART_RECV) //ISR (USART_RX_vect) //ISR (SIG_UART0_RECV) //RS232 (UART) Interrupt |
337 | {
|
338 | if (schutz == 1) //Schutz vor nicht benötigter Interruptauslösung |
339 | {
|
340 | |
341 | buffer = UDR; //Daten aus dem buffer lesen ..... |
342 | |
343 | while (!(UCSRA & (1<<UDRE))) //.... warten bis der Sende´buffer leer ist .... |
344 | |
345 | UDR = buffer; //.....und gleich wieder zurück schicken |
346 | |
347 | if (buffer != 26) //bei einem Return beginnnt die Auswertung, solange kein Return kommt, werden die Zeichen einfach nur gesammelt |
348 | {
|
349 | string[f] = buffer; |
350 | buffer = 0; |
351 | f++; |
352 | |
353 | //rprintf("buffer");
|
354 | }
|
355 | |
356 | else
|
357 | {
|
358 | schutz = 1; |
359 | rs232_recieve(); |
360 | schutz = 0; |
361 | }
|
362 | }
|
363 | }
|
In deiner Fehlermeldung steht
1 | uart.o: In function `__vector_13': |
2 | K:\AVR\AVR-Programme\WechselrichterStoermeldeprogramm\default/../uart.c:260: |
3 | multiple definition of `__vector_13' |
4 | WvS-Sample.o:K:\AVR\AVR-Programme\WechselrichterStoermeldeprogramm\default/../WvS-Sample.c:673: |
5 | first defined here |
da ist von einer Datei "uart.o" die Rede, die aus "uart.c" compiliert wurde. WEnn man davon ausgehen kann, dass du vernünftige Dateinamen gewählt hast, dann wird es sich wohl hierbei um UART Routinen handeln, die zum Bliestift eine ISR für den RXC Interrupt mitbringen. Und genau denselben Interrupt (und einen soweit ich sehen kann vollständigen Satz UART Routinen) hast du auch in deinem Hauptfile "WvS-Sample.o" welche aus "WvS-Sample.c" compiliert wurde. Das mag jetzt nicht so gewollt sein, weil du in deinem Hauptfile alle Referenzen zu uart.h auskommentiert hast. Fakt ist aber, dass in deiner Projektbeschreibung, die du im AVR-Studio (? ansonsten eben im Makefile) in Form von dazugehörigen Source-Code Dateien hast, die uart.c noch immer mit drinnen hast und die daher compiliert und zum Projekt gelinkt wird. Und deswegen gibt es alles doppelt. Insbesondere gibt es die ISR doppelt. Steht alles da. Nur lesen und seine Schlüsse aus dem Gelesenen muss man halt ziehen.
@Karl Heinz Buchegger: Danke für die Erklärung. Das diese Definition doppelt vorhanden ist hab ich schon raus gefunden. Aber was heißt der letzte Absatz genau? Sollte ich die uart.c löschen oder kann man die umändern oder ähnliches?
Matthias Drexler schrieb: > Sollte ich die uart.c löschen oder kann man die umändern oder ähnliches? Das soll heißen, dass du nicht doppelt includieren sollst.
Matthias Drexler schrieb: > @Karl Heinz Buchegger: > Danke für die Erklärung. > Das diese Definition doppelt vorhanden ist hab ich schon raus gefunden. > Aber was heißt der letzte Absatz genau? > Sollte ich die uart.c löschen oder kann man die umändern oder ähnliches? WElcher Teil von > Fakt ist aber, dass in deiner > Projektbeschreibung, die du im AVR-Studio (? ansonsten eben > im Makefile) in Form von dazugehörigen Source-Code Dateien hast, > die uart.c noch immer mit drinnen hast und die daher compiliert > und zum Projekt gelinkt wird. ist da jetzt so, dass man mit ein bischen mitdenken nicht von selber auf die Lösung kommt, das man uart.c aus der Projektbeschreibung rausnehmen soll?
Hallo Ich habe jetzt den befehl ab der angegebenen zeile im uart.c auskommentiert und da war der fehler weg. der befehl sieht wie folgt aus: /* // UART Receive Complete Interrupt Handler UART_INTERRUPT_HANDLER(SIG_UART_RECV) { u08 c; // get received char c = inb(UDR); // if there's a user function to handle this receive event if(UartRxFunc) { // call it and pass the received data UartRxFunc(c); } else { // otherwise do default processing // put received char in buffer // check if there's space if( !bufferAddToEnd(&uartRxBuffer, c) ) { // no space in buffer // count overflow uartRxOverflow++; } } } */ Muss es aber noch in der Praxis ausprobieren ob der Interrupt noch funktioniert. Danke für eure Tipps und Ratschläge. mfg Matthias Drexler
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.