Forum: Mikrocontroller und Digitale Elektronik uint16_t 2 byte in LCD anzeigen


von Weider (Gast)


Lesenswert?

Hallo,

ich bin seit Stunden an einem Problem und ich komme einfach nicht 
weiter, vielleicht könnt ihr mir helfen.

Hier mein Problem:
Ich bestimme in einer uint16_t eine EEPROM Adresse. Sprich 2Byte mit 
folgendem Code:
1
uint8_t enter(const char *frage, unsigned int MaxLen)
2
{
3
  uint8_t temp;
4
  if(atkeyb_buffcnt != 0)
5
  {
6
    temp = atkeyb_getchar();
7
  }
8
9
  unsigned short *Buffer[MaxLen];
10
  uint8_t StringLen = 0;
11
  lcd_spalte=0;
12
  lcd_zeile=0;
13
  lcd_clear();
14
  lprint("", frage, 1);
15
  lcd_command(LCD_SET_DISPLAY|LCD_DISPLAY_ON|LCD_CURSOR_ON|LCD_BLINKING_ON);
16
17
  unsigned int exit = 0;
18
19
  lcd_spalte = 0;
20
  lcd_zeile = 2;
21
  do {
22
    if(atkeyb_buffcnt != 0)
23
    {
24
      temp = atkeyb_getchar();
25
    }
26
    switch(temp)
27
    {
28
29
      case  8:
30
        if (lcd_spalte > 0)
31
        {
32
          lcd_spalte--;
33
          StringLen--;
34
          *Buffer[StringLen] = 0;
35
          lcd_setcursor(lcd_spalte, lcd_zeile);
36
          lcd_data(0xFE);
37
          lcd_setcursor(lcd_spalte, lcd_zeile);
38
        }
39
        break;
40
41
      case 13: //ENTER
42
        //*Buffer = '\0';
43
        exit = 2;
44
        break;
45
46
      default:
47
        if ((temp != 0) && (temp >= '0') && (temp <= '9'))
48
        {
49
          if (StringLen < MaxLen)
50
          {
51
            *Buffer[StringLen] = temp;
52
            lprintbk(temp);
53
              StringLen++;
54
            temp = 0;
55
          }
56
        }
57
        break;
58
    }
59
60
  } while (exit != 2);
61
  lcd_command(LCD_SET_DISPLAY|LCD_DISPLAY_ON|LCD_CURSOR_OFF|LCD_BLINKING_OFF);
62
  return *Buffer;
63
}

Jetzt möchte ich die Adresse die zuvor mittels PC-Tastatur eingegeben 
worden ist benutzen und als Dez.-Zahl im LCD anzeigen um zu überprüfen 
ob auch die richtig Adresse ausgelesen worden ist. Das Problem ist 
dabei, dass das LCD einfach nicht die richtig Zahl bzw. wirre Zeichen 
anzeigt.
1
void menu_rw_read(void)
2
{
3
  uint16_t adbyte, rdbyte;
4
//  unsigned int zahl;
5
6
  char LCDZahl[10];  
7
8
     adbyte = enter("Adresse: ", 8);
9
//  zahl = atoi(adbyte);
10
11
  utoa( adbyte, LCDZahl, 10 );
12
13
  lprint("ADD: ","Read EEPROM", 1);
14
15
  lcd_data(LCDZahl);
16
17
  long_delay(300);
18
  //rdbyte = exEEPROMRead(adbyte);
19
  lcd_clear();
20
  lcd_string("ADD: ");
21
  lcd_string(LCDZahl);
22
  lcd_setcursor(0, 2);
23
  lcd_string("Wert: ");
24
25
  lcd_data(rdbyte);
26
  wait_ofkey();
27
}

von Weider (Gast)


Lesenswert?

Jemand eine Idee?

von Vn N. (wefwef_s)


Lesenswert?

lcd_data erwartet offensichtlich keinen String als Argument.

von Weider (Gast)


Lesenswert?

hmm..  mit lcd_string() gibt er auch nur komisches Zeugs raus.

von Hans Peter B. (Gast)


Lesenswert?

Solange dein Code nicht fehler- bzw warnungsfrei übersetzt wird, darft 
du nicht erwarten, dass er fehlerlos ausgeführt wird.

z.B. Übergabewert an lcd_data() in einem Fall:
 "uint16_t rdbyte"
und im andern Fall:
 "char LCDZahl [10]"

Hans Peter

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

utoa will wie itoa ein Zeiger aufs Stringarray und den seh ich hier 
nicht!
http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/
Dann musst du noch bedenken, dass du die Stellen auf dem LCD löschen 
musst, wenn die Adresszahl um eine Zehnerpotenz kleiner wird, das 
Display löscht ja nicht von alleine und dann irrt da ne alte Zahl rum.

von 42er (Gast)


Lesenswert?

Weider schrieb:
> Das Problem ist dabei, dass das LCD einfach nicht die richtig Zahl bzw.
> wirre Zeichen anzeigt.

Ohne konkrete Beispiele treibt die Phantasie wilde Blüten. Möchtest du 
das?

von Werner (Gast)


Lesenswert?

Was spricht dagegen, die Umwandlung der Daten und die Übergabe an das 
LCD im Simulator zu verfolgen und den Fehler einzukreisen?

von Rolf M. (rmagnus)


Lesenswert?

Weider schrieb:
> unsigned short *Buffer[MaxLen];

Bist du sicher, daß ein Array aus Zeigern hier das richtige ist?

von Weider (Gast)


Lesenswert?

Nein, bin ich mir nich, das ist ja das Problem O.o  xD

von Weider (Gast)


Lesenswert?

Jemand eine Idee / Lösung dazu?

von Weider (Gast)


Lesenswert?

Also nach lesen mehrere Forumeinträge und dem überdenken des Problems 
bin ich zu folgender Überlegung gekommen: Da also ein uint16_t 
übertragen wird muss ich evtl. den Wert in zwei uint8_t umwandeln, 
danach über utoa(); laufen lassen und danach zu einer Dez.-Zahl 
zusammenfügen!? Würde das so funktionieren?

Und hier noch eine kleine Frage neben bei: Der Wert für die Adresse im 
EEPROM ist nun mal, auch der Funktion zu folge ein int16_t Übergabewert, 
eine Dez.-Zahl. Wie mach ich das aber mit dem Byte das ich beschreiben 
will bzw. lesen möchte? Ist es Sinnvoll das Byte (uint8_t) als Bitfolge 
auszulesen (anzeigen) zu lassen oder eher als Hex? Wie ist es mit dem 
Beschreiben einer Adresse? Binär, Hex ? Wie könnte ich das eingeben per 
Keyboard, anzeigen lassen auf dem LCD und dann mit der richtigen 
Varriable an die Funktion weitergeben ohne ständige umwandlungen zu 
machen?

von Karl H. (kbuchegg)


Lesenswert?

Weider schrieb:
> Also nach lesen mehrere Forumeinträge und dem überdenken des Problems
> bin ich zu folgender Überlegung gekommen:

Ich weiß nicht was du liest, aber du solltest den Ankauf eines C-Buches 
und dessen Durcharbeitung ernsthaft in Erwägung ziehen. Wesentlich 
besser als sich anlassbezogenes 1/4 Wissen in Foren zusammenzusuchen.

> Da also ein uint16_t
> übertragen wird muss ich evtl. den Wert in zwei uint8_t umwandeln,

Nein, musst du nicht. Du musst dir nur im klaren darüber sein, was die 
Funktion enter() eigentlich zu liefern hat und das dann auch umsetzen. 
Soll enter() einen String liefern oder lieber doch gleich die fertige 
Zahl (in Form eines uint16_t), die dem entspricht was der Benutzer 
eingetippt hat.

Hinweis:
enter() eine fertige 16 Bit Zahl (als fertige Zahl) liefern zu lassen 
ist trivial. enter() einen String liefern zu lassen, ist alles andere 
als trivial. Bei letzterem muss man (mindestens) einen Tod sterben.

von Weider (Gast)


Lesenswert?

Ja, ich möchte eine 16Bit Zahl von der Funktion enter() zurück geben 
lassen. Leider bekomme ich das nicht hin. Irgendwas stimmt in der 
Funktion nich beim eingeben. Da ja eine Zahl die größer ist als 9 zwei 
stellen bzw. mehrere benötigt. Diese Zahl (z.B. 1020) muss ja als 
komplette zurückgegeben werden von der Funktion aber muss einzell im LCD 
wiedergegeben werden, um auch eine Numer löschen zu können ASCII 8 
(Backspace).

L.g.

von Weider (Gast)


Lesenswert?

Also wenn ich die Funktion enter() so lasse und einen String zurückgeben 
könnte ich mit dem Code 
http://home.htw-berlin.de/~junghans/cref/EXAMPLES/exponent.c#atoi den 
String in eine Zahl umwandeln. Ich verstehe nur nicht wie der Code 
funzt. Hilfe ich dreh durch! xD Ne, im Ernst. Kann mir irgendjemand bei 
dem Problem helfen??? Bitte.. ich weiß net mehr weiter! =(

von Karl H. (kbuchegg)


Lesenswert?

Weider schrieb:
> Also wenn ich die Funktion enter() so lasse und einen String zurückgeben
> könnte ich mit dem Code
> http://home.htw-berlin.de/~junghans/cref/EXAMPLES/exponent.c#atoi den
> String in eine Zahl umwandeln. Ich verstehe nur nicht wie der Code
> funzt. Hilfe ich dreh durch! xD Ne, im Ernst. Kann mir irgendjemand bei
> dem Problem helfen??? Bitte.. ich weiß net mehr weiter! =(

in enter() die Einzelzeichen, die der Benutzer eingibt, in einem String 
sammeln. Aber das muss auch wirklich ein String bzw. ein char Array 
sein, das was du da hast mit deinem Buffer Array ist Murks.
Danach den String mittels atoi oder atol oder strtol oder einer 
Eigenbauroutine in eine echte Zahl umwandeln lassen und die dann 
zurückgeben.

von Weider (Gast)


Lesenswert?

Ja, das versuche ich ja, aber wie kann ich die Eingaberoutine so 
umschreiben das das Funktioniert. Den das lesen auf dem Rom klappt, wenn 
ich die Eingaberoutine aus acht lasse.
1
void menu_rw_read(void)
2
{
3
  uint16_t adbyte = 0;
4
  uint8_t rdbyte = 0;
5
  char Buffer[17];
6
  unsigned int eezahl; //char LCDZahl[10];
7
8
     adbyte = enter("Adresse: ", 8);
9
  lprint("","ENTER:", 1);
10
11
  adbyte = "1023"; //<---  HIER Umgehe ich die Routine, es wird von adresse 1023 gelesen. Klappt auch super. Nur eben nicht mit der Eingabe.
12
    eezahl = atoi(adbyte);
13
  utoa( eezahl, Buffer, 10 ); //Kontrollumwandlung
14
  
15
  EEPWriteByte(eezahl, 0xED); //test-Eigener Rom
16
  
17
  lprint("ADD: ","Read EEPROM", 1);
18
  lcd_string(Buffer); //<-- Adresse wird klar dargestellt im LCD.
19
  rdbyte = EEPReadByte(eezahl);//exEEPROMRead(eezahl);
20
  long_delay(1000);
21
  
22
  lcd_clear();
23
  lcd_string("Adresse: ");
24
  lcd_string(Buffer);
25
  lcd_setcursor(0, 2);
26
  lcd_string("Wert: ");
27
  utoa( rdbyte, Buffer, 2);//10 );
28
  lcd_data('0');
29
  lcd_data('b');
30
  lcd_string(Buffer); //<-- Der richtige Wert des Byte's wird im LCD richtig dargestellt
31
  if (wait_ofkey() == 27)
32
  {
33
    utoa( eezahl, Buffer, 10 );
34
    lcd_clear();
35
    lcd_string("Adresse: ");
36
    lcd_string(Buffer);
37
    lcd_setcursor(0, 2);
38
    lcd_string("Wert: ");
39
    utoa( rdbyte, Buffer, 16);//10 );
40
    lcd_data('0');
41
    lcd_data('x');
42
    lcd_string(Buffer);
43
    if (wait_ofkey() == 27)
44
    {
45
      utoa( eezahl, Buffer, 10 );
46
      lcd_clear();
47
      lcd_string("Adresse: ");
48
      lcd_string(Buffer);
49
      lcd_setcursor(0, 2);
50
      lcd_string("Wert (dez.): ");
51
      utoa( rdbyte, Buffer, 10 );
52
      lcd_string(Buffer);
53
      while (wait_ofkey() != 13);
54
    }
55
  }
56
  menu_rw(2);
57
}

von W.S. (Gast)


Lesenswert?

Weider schrieb:
> Ich bestimme in einer uint16_t eine EEPROM Adresse. Sprich 2Byte mit
> folgendem Code:

Hehehehe!

Haben da nicht andere Leute im Tone tiefster innerer Überzeugung in 
einem anderen Thread davon gefaselt, daß man mit goto immer nur 
Spaghetti-Code erzeugt? Der oben gepostete Code ohne goto wirkt auf 
mich mindestens genau so spaghettihaft wie der (damals in den 80er 
Jahren übliche) BASIC-Code mit goto.

Also mein Rat an den Weider:
1. Trenne die Funktionen in sinnvolle Stücke. Also schreibe 2 
Funktionen

bool CharAvail(int Portnum); und char GetChar(int Portnum); Das ist die 
unterste Ebene.
Darauf setzt eine Kommunikations-Ebene auf, die erstmal nur eine 
Kommandozeile zusammensammelt und ggf. Backspace zum Editieren kennt.

Wenn eine Zeile zusammengekommen ist, dann werte sie aus.
Schreib dir ne Funktion, die Integers aus Ziffernfolgen macht und eine, 
die Hex als Input hat. Meist braucht man beides und es ist gut, sowas im 
Repertoire zu haben.

log GetLong(void)
{ long L;
  L = 0;
  while (Kommandozeile[ptr] in ['0'..'9'])   /* ;-)  */
  { L = L*10 + (Kommandozeile[ptr] - '0');
    inc(ptr);
  }
  return L;
}

so ähnlich, mit Bereichsprüfung von ptr und von halb-Pascal nach C 
umgemodelt...

W.S.

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.