Daten aus einem array einer Variablen zuweisen.

OP #2164852
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 ?
OP #2164874
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 :)
OP #2164887
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
}
#2164945
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.
OP #2164997
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.

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