uint16_t 2 byte in LCD anzeigen

Gast #2644355
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
}
Gast #2644397
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
Gast #2648777
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?
#2648852
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.
Gast #2649099
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.
#2649801
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.
Gast #2650464
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
}
Gast #2650884
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.

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