Forum: Compiler & IDEs Daten aus einem array einer Variablen zuweisen.


von Peter L. (lahabole)


Lesenswert?

Im moment habe ich ein Problem, mit dem ich nicht klar komme. Über Uart 
empfange ich 3 Byte (ohne \0), die Zahlenwerte enthalten. Diese Werte 
möchte ich Variablen zuweisen, was aber irgentwie nicht geht.

eine kleine Testschleife sieht im moment so aus:
1
while (1)
2
  {
3
    USART0_Gets(MotorData);  //Funktioniert
4
    //USART0_Puts(MotorData); //Funktioniert auch
5
    uint8_t test = MotorData[1]; // geht nicht
6
    USART0_putchar(test);        // geht auch nicht
7
  }

Wenn ich die Daten als array wieder Ausgebe, Funktionierts wunderbar. 
Also stehen ja Daten im array, nur wenn ich ein arrayelement einer 
Variablen zuweise geht nix. Was hab ich übersehen ?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was heißt "geht nicht"? Was passiert? Wie ist "MotorData" deklariert?

Wie sehen die "3 Byte (..) die Zahlenwerte enthalten" aus?

Was vermutest Du, sollte USART0_putchar() ausgeben, wenn Du einen 
beliebigen Wert zwischen 0 und 255 übergibst?

Womit überprüfst Du die von dieser Funktion ausgegebenen Werte?

von Peter L. (lahabole)


Lesenswert?

putchar schickt immer 0 auf die Leitung. MotorData ist als uint8_t 
initialisiert mit 3 Elementen.

Ich erwarte im moment das putchar mir den wert des 2 arrayelemnts als 
echo auf die leitung schickt. Mit Puts werden die korrekten 3 Bytes als 
echo ausgegeben.

Nachprüfen kann ich es nur mit meinem logicanalyzer, was bissher auch 
gut Funktionierte :)

von Marco (Gast)


Lesenswert?

Zeig uns doch bitte mal die 3 Funktionen puts, gets und putchar.

von Peter L. (lahabole)


Lesenswert?

Hier mal die Funktionen.
1
#define Tx0BufSize 16
2
#define Rx0BufSize 16
3
volatile unsigned char uart0TxBuf[Tx0BufSize], uart0RxBuf[Rx0BufSize], Tx0Empty = 1;
4
volatile unsigned int uart0TxInBufPtr = 0, uart0RxInBufPtr = 0;
5
volatile unsigned int uart0TxOutBufPtr = 0, uart0RxOutBufPtr = 0;
6
volatile unsigned char Rx0Overflow = 0;
7
8
char printBuffer[256];
9
uint8_t hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
10
11
extern volatile
12
13
//usart0 receive complete interrupt
14
ISR (USART_RX_vect)
15
{
16
  char dummy;
17
  unsigned int Ptr;
18
19
  Ptr = uart0RxInBufPtr + 1;
20
  if (Ptr >= Rx0BufSize) Ptr = 0;
21
  if (Ptr != uart0RxOutBufPtr)
22
  {
23
    uart0RxBuf[Ptr] = UDR;
24
    uart0RxInBufPtr = Ptr;
25
  }
26
  else        //no more space in ReceiveBuffer, set overflow warning!
27
  {
28
    dummy = UDR;
29
    Rx0Overflow = 1;
30
  }
31
}
32
33
34
35
signed int USART0_getchar(void)
36
{
37
  if (uart0RxInBufPtr != uart0RxOutBufPtr)
38
  {
39
    uart0RxOutBufPtr++;
40
    if (uart0RxOutBufPtr >= Rx0BufSize) uart0RxOutBufPtr = 0;
41
    return (signed int) uart0RxBuf[uart0RxOutBufPtr];
42
  }
43
  else return -1;        //sorry, there was nothing to read
44
}
45
46
signed int USART0_putchar(char ch)
47
{
48
  unsigned int Ptr;
49
50
  Ptr = uart0TxInBufPtr + 1;
51
  if (Ptr >= Tx0BufSize) Ptr = 0;
52
  if (Ptr != uart0TxOutBufPtr)
53
  {
54
    uart0TxBuf[Ptr] = ch;
55
    uart0TxInBufPtr = Ptr;
56
    if (Tx0Empty == 1)
57
    {
58
      UCSRA |= (1<<UDRE);    //clear data register empty flag - so interrupt will fire when UDRIE0 is set
59
      UCSRB |= (1<<UDRIE);    //Enable data register empty interrupt - force interrupt trigger
60
    }
61
62
    Tx0Empty = 0;
63
      return 0;
64
  }
65
  else
66
  {
67
    return -1;      //no room - queue is full
68
  }
69
}
70
71
72
73
void USART0_Puts (char *s)
74
{
75
    while (*s)
76
    {   // as long as *s != '\0' which is the "end of string" indicator
77
        while(USART0_putchar(*s) == -1);
78
        s++;
79
    }
80
}
81
82
83
84
void USART0_Gets (char *s)
85
{
86
  unsigned char dataHere = 1;
87
  signed int tmp;
88
  char * ptr;
89
90
  ptr = s;
91
  while(dataHere)
92
  {
93
    tmp = USART0_getchar();
94
    if (tmp < 0)  //no data is available
95
    {
96
      dataHere = 0;
97
      *ptr = 0;    //string termination
98
    }
99
    else
100
    {
101
      *ptr = tmp;
102
      ptr++;
103
    }
104
  }
105
}

von Marco (Gast)


Lesenswert?

Oha....

Hast du mir noch die Interruptfunktion, welche warscheinlich die Daten 
über den Uart raussendet....

Danke.

von Stefan E. (sternst)


Lesenswert?

Peter Lambertz schrieb:
> Hier mal die Funktionen.

Also auf der Basis der Funktionen würde ich das "Funktioniert" hier
1
while (1)
2
  {
3
    USART0_Gets(MotorData);  //Funktioniert
4
    //USART0_Puts(MotorData); //Funktioniert auch
5
    uint8_t test = MotorData[1]; // geht nicht
6
    USART0_putchar(test);        // geht auch nicht
7
  }
stark bezweifeln. USART0_Gets kopiert alles, was gerade im Puffer ist 
(egal wie viel), und terminiert es. Es gibt keinen Grund, warum das mit 
jedem Schleifendurchlauf immer genau 3 Zeichen sein sollten. Im 
Gegenteil, schon vom Timing her ist das extrem unwahrscheinlich. Was 
wohl tatsächlich passiert, ist, dass in der "funktionierenden" Version 
pro Schleifendurchlauf immer nur 0 bis 1 Wert gelesen und wieder 
ausgegeben wird. Du siehst zwar in der Ausgabe die erwarteten 3 Werte, 
doch entstand diese Ausgabe nicht in einem Durchlauf (und die Werte 
standen auch nicht in MotorData[0-2]), sondern in vielen Durchläufen 
(und der eine Wert stand dann immer in MotorData[0]). Und damit ist dann 
auch klar, dass das
1
    uint8_t test = MotorData[1]; // geht nicht
2
    USART0_putchar(test);
immer eine 0 liefert.

von Peter L. (lahabole)


Lesenswert?

da könntest du recht haben stefan. ich bin nur von dem logicanalyzer 
ausgegangen. wenn ich die 3 bytes sende fängt er am letzten empfangenen 
an sie zurückzusenden.

etwa so:
lesen  -> ---  ---  ---  ---
echo   ->   ---  ---  ---  ---

daher ging ich mal davon aus das die 3 bytes erst mal empfangen werden. 
nehme ich jetzt die putchar funktion und lass die senden siehts so aus:

lesen  -> ---  ---  ---  ---
echo   -> ------------------

ich probier mal die MotorData[0] aber noch aus wie du gesagt hast.

von Karl H. (kbuchegg)


Lesenswert?

Nichts gegen Logic Analyzer.
Aber am einfachsten testet man eine UART indem man sie mit einem 
Terminal verbindet und nachsieht, ob das was man am Terminal tippt auch 
wieder zurückkommt bzw. wie das Programm darauf reagiert.

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.