Stringlänge von Zeichen und Buchstaben bestimmen

Gast #3319684
Lesenswert?

Hallo,

ich stehe grade vor dem Problem, dass ich über UART eine Telefonnummer 
zum Atmega 32 geschickt bekomme. Diese Telefonnummer wird dann auf 
Plausibilität überprüft und auf einem LCD ausgegeben.

Jetzt möchte ich allerdings für die weitere Verarbeitung die genaue 
Länge des Strings erfahren, weil der String ins EEProm geschrieben und 
dann später immer wieder geladen werden soll.

Auf dem LCD lass ich mir auch die Länge des Strings ausgeben, es wird 
aber nur Müll angezeigt. Wo liegt hier mein Fehler ?

Also die über UART empfangene Telefonnumemr wird korrekt angezeigt....
1
#include <avr/io.h>
2
#define F_CPU 4000000
3
#include <util/delay.h>
4
#include "com74hc595.h"
5
#include "com74hc595_lcd.h"
6
#include <avr/interrupt.h>
7
#include <avr/eeprom.h>
8
#include <string.h>
9

10
#define BAUD 9600UL      // Baudrate
11
#define UART_MAXSTRLEN 14
12

13

14
// Konstanten fuer die Baudrate aus der Taktfrequenz berechnen
15
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
16
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
17
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
18

19
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
20
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
21
#endif
22

23
volatile uint8_t uart_str_complete = 0;     // 1 .. String komplett empfangen
24
volatile uint8_t uart_str_count = 0;
25
volatile char uart_string[UART_MAXSTRLEN + 1] = "";
26
volatile char Buffer[20];
27

28
uint8_t eeFooTelefonnummer[15] EEMEM;
29
uint8_t eeFooLaenge[4] EEMEM;
30

31
//**********************************************************//
32
//******************Funktionen UART*************************//
33
//**********************************************************//
34

35
int uart_putc( unsigned char c )
36
{
37
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
38
    ;
39

40
  UDR = c;                      /* sende Zeichen */
41
  return 0;
42
}
43

44
uint8_t uart_getc(void)
45
{
46
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
47
        ;
48
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
49
}
50

51
uint8_t uart_getc_wait()
52
{
53
  // Warten, bis etwas empfangen wird
54
  while (!(UCSRA & (1 << RXC)))
55
    ;
56

57
  // Das empfangene Zeichen zurückliefern
58
  return UDR;
59
}
60

61
/* String senden */
62
void uart_puts( const char *s )
63
{
64
//  lcd_clear();
65
//  lcd_string(s);
66
  while (*s)
67
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
68
    uart_putc(*s);
69
    s++;
70
  }
71
}
72

73
//**********************************************************//
74
//******************UART-Verbindung*************************//
75
//**********************************************************//
76

77
    void initUART()
78
    {
79
      UCSRB |= (1<<TXEN) | (1<<RXEN)|(1<<RXCIE);      // UART TX/RX einschalten
80
      UCSRC |= (1<<URSEL) | (1 << UCSZ1) | (1 << UCSZ0);//| (3<<UCSZ0);      // Asynchron 8N1
81

82
      UBRRH = UBRR_VAL >> 8;               // Baudrate setzen
83
      UBRRL = UBRR_VAL & 0xFF;
84
    }
85

86

87

88
int main(void)
89
{
90

91
  char Vergleich[]="+49";
92
  int StringVergleich = 0;
93
  int TelefonnummerLaenge;
94

95
    com74hc595_init();        // Porterweiterungen initialisieren
96
    com74hc595_lcd_init();      // Lcd initialisieren
97

98
    initUART();            // UART initialisieren BAUDRATE ist 9600 !!
99

100
   sei();
101

102
    while(1)
103
    {
104

105
    if( uart_str_complete == 1 )
106
    {
107
      com74hc595_lcd_clear();
108
      com74hc595_set_cursor(0,1);
109

110
      StringVergleich = strncmp(uart_string, Vergleich, 3);
111
      if ( StringVergleich == 0)
112
      {
113
         com74hc595_lcd_string(uart_string);
114

115
         TelefonnummerLaenge = strlen(uart_string);
116
         eeprom_write_byte(&eeFooLaenge,TelefonnummerLaenge);
117
         
118
         com74hc595_set_cursor(0,2);
119
         com74hc595_lcd_string(TelefonnummerLaenge);
120
         uart_str_complete = 0;
121
      }
122
      else
123
      {
124
        com74hc595_lcd_string("Fehler");
125
        uart_str_complete = 0;
126
      }
127
    }
128

129
    }
130
}
131

132
ISR(USART_RXC_vect)
133
{
134
  unsigned char nextChar;
135

136
  // Daten aus dem Puffer lesen
137
  nextChar = UDR;
138
  if( uart_str_complete == 0 ) {  // wenn uart_string gerade in Verwendung, neues Zeichen verwerfen
139

140
    // Daten werden erst in uart_string geschrieben, wenn nicht String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird
141
    if( nextChar != '\n' &&
142
        nextChar != '\r' &&
143
        uart_str_count < UART_MAXSTRLEN ) {
144
      uart_string[uart_str_count] = nextChar;
145
      uart_str_count++;
146
    }
147
    else {
148
      uart_string[uart_str_count] = '\0';
149
      uart_str_count = 0;
150
      uart_str_complete = 1;
151
    }
152
  }
153
}
#3319724
Lesenswert?

Du schliesst doch deinen zusammengebauten String mit 0 ab. Damit hast du 
alles, wa du brauchst. Beim Auslesen musst du nur bis 0 lesen.
Wo ist das Problem?

> uint8_t eeFooLaenge[4] EEMEM;
Das brauchst du nicht. Wenn du 4 mit 0 terminierte Nummern 
hintereinander ablegst, gehst du einfach durch den Speicher durch, bis 
du die richtige gefunden hast. Die zweite Nummer beginnt hinter der 
zweiten 0, die anderen entsprechend. Das geht Ratz-Fatz da einmal 
durchzunageln. Da kannst du auch den ganzen E²PROM vollschreiben.

mfg.
#3322650
Lesenswert?

... wobei man sich am sinnvollsten gleich eine Funktion
1
void com74hc595_lcd_int( int wert )
2
{
3
  char str[7];
4
  itoa( wert, str, 10 );
5
  com74hc595_lcd_string( str );
6
}
baut, anstatt erst in main da groß rumzupfriemeln. So eine int Ausgabe 
braucht man immer wieder.

Wie hast du (Thorsten), das hier
1
  com74hc595_lcd_string(TelefonnummerLaenge);
eigentlich durch den Compiler gebracht? Da muss es doch an allen Ecken 
und Enden Alarm geklingelt haben!
#3323968
Lesenswert?

>Wie hast du (Thorsten), das hier
>>com74hc595_lcd_string(TelefonnummerLaenge);
>eigentlich durch den Compiler gebracht? Da muss es doch an allen Ecken
>und Enden Alarm geklingelt haben!

Nicht, wenn ein Integer die Größe eines Pointers hat. Wenn dann noch 
Warnungen ausgeschalten sind oder der Compiler etwas älter ist, dann 
wird trotzdem kompiliert.
Gast #3323970
Lesenswert?

Thorsten schrieb:
> uint8_t uart_getc(void)
> {
>     while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
>         ;
>     return UDR;                   // Zeichen aus UDR an Aufrufer
> zurueckgeben
> }
>
ist für mich das gleiche (außer dem Funktionsnamen) wie:

> uint8_t uart_getc_wait()
> {
>   // Warten, bis etwas empfangen wird
>   while (!(UCSRA & (1 << RXC)))
>     ;
>
>   // Das empfangene Zeichen zurückliefern
>   return UDR;
> }

Wo ist der Unterschied zwischen beiden Funktionen?

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