Forum: Mikrocontroller und Digitale Elektronik String einlesen und bearbeiten


von Matthias Drexler (Gast)


Lesenswert?

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

von gagast (Gast)


Lesenswert?

>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

von Matthias Drexler (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Matthias Drexler (Gast)


Lesenswert?

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?

von tom (Gast)


Lesenswert?

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.

von tom (Gast)


Lesenswert?


von M. K. (sylaina)


Lesenswert?

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? ;)

von cskulkw (Gast)


Lesenswert?

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

von M. K. (sylaina)


Lesenswert?

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

von Matthias Drexler (Gast)


Lesenswert?

danke für die vielen und schnellen Antworten.

ich werde mir die vorschläge anschauen und sie ausprobieren.

mfg
Matthias Drexler

von Matthias Drexler (Gast)


Lesenswert?

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

von M. K. (sylaina)


Lesenswert?

der heißt
1
ISR(USART_RX_vect){}

;)

von Matthias Drexler (Gast)


Lesenswert?

Bei diesem Befehl sagt er auch das dieser Befehl wahrscheinlich falsch 
geschrieben ist......
was könnte das sein?

von M. K. (sylaina)


Lesenswert?

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){}

von Matthias Drexler (Gast)


Lesenswert?

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?

von ... (Gast)


Lesenswert?

Schau mal in den anderen Output-Tab im AVRStudio, dann siehst Du auch 
die richtige Fehlermeldung.

von M. K. (sylaina)


Lesenswert?

Ö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.

von Matthias Drexler (Gast)


Lesenswert?

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

von M. K. (sylaina)


Lesenswert?

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.

von Uwe (Gast)


Lesenswert?

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.

von M. K. (sylaina)


Lesenswert?

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.

von Matthias Drexler (Gast)


Lesenswert?

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++;
    }
  }
}

von Matthias Drexler (Gast)


Lesenswert?

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
}

von Matthias Drexler (Gast)


Lesenswert?

und das ist meine kompletter quellcode incl. Fehler.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Matthias Drexler (Gast)


Lesenswert?

@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?

von M. K. (sylaina)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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?

von Matthias Drexler (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.