Probleme mit C Code und hilfe bei änderung

#5782228
Lesenswert?

Hallo,

ich bin nicht so bewandt was C angeht aber bisher hat alles geklappt. 
Nunja. ich habe nun Probleme mit Strings.

Ich habe mit folgende Funktion gebastelt:
1
#include "main.h"
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <stdint.h>
5
#include "mylcd.h"
6
#include <avr/interrupt.h>
7
#include <stdint.h>
8
#include <inttypes.h>
9
#include <avr/pgmspace.h>
10
#include <stdlib.h>
11
#include <stdio.h>
12
#include <avr/eeprom.h>
13

14
int display_run = 0;
15
extern char temp_a;
16
extern char temp_b;
17
extern char temp_c;
18
extern int stunde;
19
extern int minute;
20
char Buffer[20];
21

22
char temp_log_data_1_time[10];
23
char temp_log_data_2_time[10];
24
char temp_log_data_3_time[10];
25
char temp_log_data_4_time[10];
26
char temp_log_data_5_time[10];
27

28
char temp_log_data_1_temp1;
29
char temp_log_data_1_temp2;
30
char temp_log_data_1_temp3;
31

32
char temp_log_data_2_temp1;
33
char temp_log_data_2_temp2;
34
char temp_log_data_2_temp3;
35

36
char temp_log_data_3_temp1;
37
char temp_log_data_3_temp2;
38
char temp_log_data_3_temp3;
39

40
char temp_log_data_4_temp1;
41
char temp_log_data_4_temp2;
42
char temp_log_data_4_temp3;
43

44
char temp_log_data_5_temp1;
45
char temp_log_data_5_temp2;
46
char temp_log_data_5_temp3;
47

48
void write_temp_log(void) {
49

50
  *temp_log_data_5_time = *temp_log_data_4_time;
51
  temp_log_data_5_temp1 = temp_log_data_4_temp1;
52
  temp_log_data_5_temp2 = temp_log_data_4_temp2;
53
  temp_log_data_5_temp3 = temp_log_data_4_temp3;
54

55
  *temp_log_data_4_time = *temp_log_data_3_time;
56
  temp_log_data_4_temp1 = temp_log_data_3_temp1;
57
  temp_log_data_4_temp2 = temp_log_data_3_temp2;
58
  temp_log_data_4_temp3 = temp_log_data_3_temp3;
59

60
  *temp_log_data_3_time = *temp_log_data_2_time;
61
  temp_log_data_3_temp1 = temp_log_data_2_temp1;
62
  temp_log_data_3_temp2 = temp_log_data_2_temp2;
63
  temp_log_data_3_temp3 = temp_log_data_2_temp3;
64

65
  *temp_log_data_2_time = *temp_log_data_1_time;
66
  temp_log_data_2_temp1 = temp_log_data_1_temp1;
67
  temp_log_data_2_temp2 = temp_log_data_1_temp2;
68
  temp_log_data_2_temp3 = temp_log_data_1_temp3;
69

70
  sprintf(temp_log_data_1_time, "foo");
71
  temp_log_data_1_temp1 = temp_a;
72
  temp_log_data_1_temp2 = temp_b;
73
  temp_log_data_1_temp3 = temp_c;
74
}

In der main führe ich folgendes aus:
1
.....
2
  while(1)
3
  {
4
    write_temp_log();
5

6
    read_temps();
7

8
    itoa(temp_log_data_1_time,Buffer,10);
9
    lcd_set_cursor(7,LINE3);
10
          lcd_puts(small_font,Buffer);
11
.....

Auf dem Display erhalte ich in LINE3 anstatt "foo" 102 angezeigt...

ich möchte allerdings folgendes:
1
sprintf(temp_log_data_1_time, "%d:%d", stunde, minute);

wenn ich nur
1
sprintf(temp_log_data_1_time, "%d", minute);
oder
1
sprintf(temp_log_data_1_time, "%d", stunde);
mache dann bekomme ich in LINE3 auf dem Display die Stunde oder die 
Minute angezeigt.... in
1
temp_log_data_1_time
soll aber die Zeit in Format SS:MM stehen, also z.b. 17:10

wenn ich nun versuche das ganze direkt da rein zu schreiben, also
1
temp_log_data_1_time = "17:10";

bzw
1
*temp_log_data_1_time = "17:10";

dann bekomme ich als Ausgabe auf dem Display "48" angezeigt.

Was mache ich falsch?

Dann ist das ganze ja ziemlich lang.. kann an das nicht irgendwie ein 
ein Array packen?

Also das z.b.
1
LOG_DATA[0][0] = UHRZEIT
2
LOG_DATA[0][1] = TEMPERATUR1
3
LOG_DATA[0][2] = TEMPERATUR2
4
LOG_DATA[0][3] = TEMPERATUR3
5

6
LOG_DATA[1][0] = 2te UHRZEIT
7
LOG_DATA[1][1] = 2te TEMPERATUR1
8
LOG_DATA[1][2] = 2te TEMPERATUR2
9
LOG_DATA[1][3] = 2te TEMPERATUR3

usw...

Ich danke euch vielmals.

P.S.:

Falls wichtig, beim compilieren bekomme ich keine Fehler oder Warnings..
1
make all
2
avr-gcc -c -Os -std=gnu99 -mmcu=atmega128 main.c -o main.o
3
avr-gcc -c -Os -std=gnu99 -mmcu=atmega128 mylcd.c -o mylcd.o
4
avr-gcc -c -Os -std=gnu99 -mmcu=atmega128 gen.c -o gen.o
5
avr-gcc -c -Os -std=gnu99 -mmcu=atmega128 ds18S20.c -o ds18S20.o
6
avr-gcc -c -Os -std=gnu99 -mmcu=atmega128 display.c -o display.o
7
avr-gcc -c -Os -std=gnu99 -mmcu=atmega128 read_temps.c -o read_temps.o
8
avr-gcc  -mmcu=atmega128 main.o mylcd.o gen.o ds18S20.o display.o read_temps.o -o main.elf
9
avr-objcopy -O ihex -j .data -j .text main.elf main.hex
10
avr-objcopy -O ihex -j .eeprom --change-section-lma .eeprom=1 main.elf main_eeprom.hex
Persönliche Seite #5782238
Lesenswert?

Nadine W. schrieb:
> *temp_log_data_5_time = *temp_log_data_4_time;

Das macht recht sicher nicht das, was Du erzielen willst.

> Auf dem Display erhalte ich in LINE3 anstatt "foo" 102 angezeigt...

Wenn Du itoa aufrufst, und dem als Quelle einen Puffer übergibst, in dem 
"foo" steht, ...

Das ist wirr.

> Dann ist das ganze ja ziemlich lang.. kann an das nicht irgendwie ein
> ein Array packen?

Du könntest die zusammenhängenden Daten in eine Struktur packen, und 
ein Array vom Typ dieser Struktur anlegen.
Gast #5782242
Lesenswert?

Nadine W. schrieb:
> char temp_log_data_4_time[10];
> char temp_log_data_5_time[10];
> ....
> ....
> ....
>   *temp_log_data_5_time = *temp_log_data_4_time;

Was  bedeutet das?




Nadine W. schrieb:
> char temp_log_data_1_time[10];
> char temp_log_data_2_time[10];
> char temp_log_data_3_time[10];
> char temp_log_data_4_time[10];
> char temp_log_data_5_time[10];

wäre

char temp_log_data{5][10];

nicht besser?
Gast #5782252
Lesenswert?

Nadine W. schrieb:
> wenn ich nun versuche das ganze direkt da rein zu schreiben, also
> temp_log_data_1_time = "17:10";
>
> bzw
> *temp_log_data_1_time = "17:10";
>
> dann bekomme ich als Ausgabe auf dem Display "48" angezeigt.

Das soll ja ein String sein.

Nadine W. schrieb:
> char temp_log_data_1_time[10];


Also z.B. mit
1
strcpy(temp_log_blablabla, "17:10");
arbeiten
#5782276
Lesenswert?

zitter_ned_aso schrieb:
> Also z.B. mitstrcpy(temp_log_blablabla, "17:10");
> arbeiten

Alles auch schon versucht

gen.c: In function ‘write_temp_log’:
gen.c:71:3: warning: implicit declaration of function ‘strcpy’ 
[-Wimplicit-function-declaration]
   strcpy(*temp_log_data_1_time, "17:10");
   ^


oder

gen.c: In function ‘write_temp_log’:
gen.c:71:3: warning: implicit declaration of function ‘strcpy’ 
[-Wimplicit-function-declaration]
   strcpy(temp_log_data_1_time, "17:10");
   ^
Gast #5782303
Lesenswert?

Nadine W. schrieb:
> gen.c:71:3: warning: implicit declaration of function ‘strcpy’
> [-Wimplicit-function-declaration]
>    strcpy(temp_log_data_1_time, "17:10");
>    ^

Dir wurde ja schon gesagt, dass du eine Headerdatei brauchst. Lerne auf 
die Fehlermeldungen und Warnungen zu ragieren.

E.g. im Terminal:
1
$ man strcpy

Bzw. auch im Browser
https://www.google.com/search?q=man+strcpy

Dort findest du u.a. auch die Header:
1
#include <string.h>
2

3
char *strcpy(char *dest, const char *src);
4
...

HTH
leo
#5782307
Lesenswert?

ja.. habe ich gerade auch alles getestet...

ich habe jetzt alles durch.. ich bekommen es auch OHNE Warnings und 
Fehler...

aber die Ausgabe ist kein Text... sondern aus 17:10 was er anzeigen soll 
zeigt er auf einmal 12336 an...

Also ich bekomme eine ausgabe... nur anstatt "foo" eben 102... 102 wäre 
"f" aber "o" und "o" fehlt usw usw...

da ist einfach irgendwo der Wurm drinne....

Ein
1
temp_log_data_1_time = 35;

das geht auch... dann sehe ich 35 auf dem Display... oder aber

1
temp_log_data_1_time = 9999;

dann sehe ich 9999 auf dem Display....

aber

1
temp_log_data_1_time = "foo";

wird zu

102 statt foo

.......
Persönliche Seite #5782310
Lesenswert?

Nadine W. schrieb:
> Also ich bekomme eine ausgabe... nur anstatt "foo" eben 102... 102 wäre
> "f" aber "o" und "o" fehlt usw usw...

Kein Wunder, itoa wertet nur einen übergebenen Wert aus. Daß hinter dem 
Wert noch andere stehen, interessiert itoa nicht.

> da ist einfach irgendwo der Wurm drinne....

Lies. Ein. C-Buch.
#5782374
Lesenswert?

zitter_ned_aso schrieb:
> Nadine W. schrieb:
>> temp_log_data_1_time = 9999;
>>
>
>
> bei char-Datentyp?

Ja alles genau so wie der Code ist... Ich mache einfach
1
temp_log_data_1_time = 9999;

Und dann habe ich auf dem Display 9999 als Ausgabe....

Das Display ist ein ks0108 wenn das weiter hilft.

Aber wenn ich in der main.c
1
itoa(temp_log_data_1_temp1,Buffer,10);
2
lcd_set_cursor(7,LINE3);
3
lcd_puts(small_font,Buffer);

Also die Temperaturen von temp1 bis temp3 durchgehen bekomme ich die 
korrekten Werte dargestellt...
Gast #5782649
Lesenswert?

> char Buffer[20];
> char temp_log_data_1_time[10];
> char temp_log_data_1_temp1;
>
> itoa(temp_log_data_1_temp1, Buffer, 10);
> lcd_puts(small_font, Buffer);

Ich denke, du bist etwas verwirrt und deine beschissene Namensvergabe 
hilft da auch nicht gerade.

itoa wandelt eine (int-)Zahl nach Ascii, erster Parameter ist die Zahl, 
zweiter der Puffer, in den er die Ascii-Zeichen reinschreibt, dritter 
die Basis, in der die Umwandlung durchgeführt werden soll.  Also, 
temp_log_data_1_temp1 ist Input, Buffer ist Output.

lcd_puts gibt einen Text aus, erster Parameter ist die Fontgröße, 
zweiter der Puffer mit dem Text.

> sprintf(temp_log_data_1_time, "%d:%d", stunde, minute);

Dies schreibt den formatierten Text in den Puffer temp_log_data_1_time. 
Dann muß auch ein 'lcd_puts(small_font, temp_log_data_1_time);' folgen. 
Alternativ kannst du auch mit 'strcpy(Buffer, temp_log_data_1_time);' 
die Uhrzeit in den Buffer kopieren und den lcd_puts mit Buffer machen.

Tipp: Mach dir Strukturen, z.B.:
1
struct temp {
2
    uint8_t stunde, minute;
3
    int8_t temp1, temp2, temp3;
4
};
5

6
#define LOGSIZE 5
7
struct temp log[LOGSIZE];
8

9
void write_temp_log()
10
{
11
    for (uint8_t i = LOGSIZE-1; i > 0; --i)
12
        log[i] = log[i-1];
13
    //oder: memmove(log+1, log+0, (LOGSIZE-1)*sizeof(*log));
14
}
15

16
...
17
    while(1)
18
    {
19
        char buf[32];
20

21
        write_temp_log();
22
        read_temps();  // fuellt 'log[0]'
23

24
        for (uint8_t i = 0; i < LOGSIZE; ++i)
25
        {
26
            sprintf(buf, "%02u:%02u %3d %3d %3d",
27
                           log[i].stunde, log[i].minute,
28
                           log[i].temp1, log[i].temp2, log[i].temp3);
29
            lcd_set_cursor(0, LINE2 + i);
30
            lcd_puts(small_font, buf);
31
        }
32
    }
Gast #5782877
Lesenswert?

Ich nehme das mal etwas auseinander.
1
char temp_log_data_1_time[10];
2
temp_log_data_1_time = "foo";

temp_log_data_1_time ist ein Zeiger auf das erste Element eines 
Char-Arrays.
Dieser sollte auf einem AVR 16-Bit lang sein.

itoa wird Dir nur diese Zeigeradresse in einen String wandeln.

Natürlich kannst Du diesen Zeiger auch selber setzen:
1
temp_log_data_1_time = 9999;

Das ist aber kein String. "17:10" wirst Du so nicht ablegen können.
Persönliche Seite #5782991
Lesenswert?

Stefanus F. schrieb:
> Ist das nicht das Gleiche?



Nein, in diesem Fall ist es das nicht. Zwar verhält es sich wie ein 
Zeiger auf das erste Element eines Arrays, und sobald man es einer 
Funktion übergibt, ist es einer, aber so, wie Du es da hingeschrieben 
hast, ist es kein Zeiger, sondern tatsächlich ein Array.

Den Unterschied zeigt Dir der sizeof -Operator:
1
void test(char[] p)
2
{
3
  printf("sizeof = %d\n", sizeof p);
4
}
5

6
void main(void)
7
{
8
  char array[10];
9

10
  printf("sizeof = %d\n", sizeof array);
11

12
  test(array);
13
}
#5782995
Lesenswert?

Stefanus F. schrieb:
> Dirk B. schrieb:
>>> temp_log_data_1_time ist ein Zeiger auf das erste Element eines
>>> Char-Arrays.
>> Nein. Das ist die Adresse von dem ersten Element des Arrays
>
> Ist das nicht das Gleiche?

Nein.
Eine Arrayadresse kann man nicht ändern.
Einen Zeiger schon.

temp_log_data_1_time++; geht beim Array nicht.

temp_log_data_1_time = Null; geht auch nicht.

Ein Array ist kein Pointer. Ein Pointer ist kein Array.
Gast #5783160
Lesenswert?

Rufus Τ. F. schrieb:
> Den Unterschied zeigt Dir der sizeof -Operator:
>
>
1
> void test(char[] p)
2
> {
3
>   printf("sizeof = %d\n", sizeof p);
4
> }
5
> 
6
> void main(void)
7
> {
8
>   char array[10];
9
> 
10
>   printf("sizeof = %d\n", sizeof array);
11
> 
12
>   test(array);
13
> }
14
>

Ich verstehe, was du sagen möchtest. Aber ich glaube, dass deine 
Begründung falsch ist/der Vergleich hinkt:
1
char[]
 als Typ für einen Parameter ist lediglich syntaktischer Zucker und wird 
identisch zu
1
char*
 behandelt. Du kannst auch
1
char p[10]
 als Parametertyp verwenden, doch sizeof ist immer noch die Größe eines 
pointers (-Wall wirft hier sogar eine Warnung):
1
$ avr-gcc -O3 -Wall -o foo foo.c 
2
foo.c: In function ‘fun’:
3
foo.c:7:26: warning: ‘sizeof’ on array function parameter ‘p’ will return size of ‘char *’ [-Wsizeof-array-argument]
4
     printf("%d\n", sizeof(p));
5
                          ^
6
foo.c:5:10: note: declared here
7
 fun(char p[10])
8
          ^
9
$ avr-gcc -dumpversion
10
5.4.0
Persönliche Seite #5783169
Lesenswert?

stdc schrieb:
> Aber ich glaube, dass deine Begründung falsch ist/der Vergleich hinkt:

Nein, denn genau das ist der Punkt, auf den ich hinauswill.

Dirk hat aber schon das wesentliche geschrieben:

>> Ist das nicht das Gleiche?
>
> Nein.
> Eine Arrayadresse kann man nicht ändern.
> Einen Zeiger schon.
>
> temp_log_data_1_time++; geht beim Array nicht.
>
> temp_log_data_1_time = Null; geht auch nicht.
>
> Ein Array ist kein Pointer. Ein Pointer ist kein Array.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren