Vergleich zwischen uint8_t und String

Ich habe eine sehr grundlegende Frage zum String-Vergleich.

Ich habe ein USART-to-PC mit STM32L0 Nucleo-Board implementiert, und ich kann etwas in das Terminal eingeben und es wie folgt auf dem Mikro empfangen:

#define RXBUFFERSIZE 1
uint8_t aRxBuffer[RXBUFFERSIZE];

/** Put UART peripheral in reception process */
  if(HAL_UART_Receive(&huart2, (uint8_t *)aRxBuffer, RXBUFFERSIZE, 0xFFFF) != HAL_OK)
    Error_Handler(); 

Ich möchte die empfangenen Daten mit einem String vergleichen, aber der Vergleich funktioniert nicht.

char *is_correct= "Y";
if (strcmp((char*) aRxBuffer, is_correct) == 0)
    DoSomething();
else
    DoSomethingElse();

Was mache ich falsch? Danke

So richte ich den USART ein:

/* USART2 init function */
void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  HAL_UART_Init(&huart2);

}

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==USART2)
  {
    /* Peripheral clock enable */
    __USART2_CLK_ENABLE();

    /**USART2 GPIO Configuration    
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  }

}
Sie haben nicht den gesamten relevanten Code gezeigt, aber eine Sache ist, weil aRxBufferein Byte lang ist, kann es keine nullterminierte Zeichenfolge sein?
@PeterJ das ist wahrscheinlich das Problem, der RxBuffer befindet sich irgendwo im Speicher und abhängig von den Dingen dahinter wird es eine Zeichenfolge mit zufälliger Länge sein.
@PeterJ Danke. Wie konvertiere ich aRxBuffer in einen String?
messagefür uns Antworter immer noch außerhalb des Geltungsbereichs liegt, könnte das Problem auch damit zusammenhängen.
Wenn die empfangenen Daten nicht nullterminiert werden sollen, sollten Sie memcmpanstelle von verwenden strcmp, was nur die Größe der Speicherbereiche zum Vergleichen erfordert. Beachten Sie, dass die Größe der Größe der Daten entsprechen sollte, die Sie erhalten, und nicht des gesamten Puffers (wenn sie nicht gleich sind).
Oh, kein schrecklicher Fehler, 'Nachricht' sollte is_correct sein. Aber auf jeden Fall ist die Antwort von @PeterJ perfekt.

Antworten (3)

Für die strcmpFunktion und alle anderen String-Funktionen muss der String nullterminiert sein. Für Ihr Beispiel wäre eine Möglichkeit, dies zu tun, etwa so, um ein zusätzliches Byte im Array zuzuweisen und am Ende ein Null-Terminator einzufügen:

#define RXBUFFERSIZE 1
uint8_t aRxBuffer[RXBUFFERSIZE + 1];
if(HAL_UART_Receive(&huart2, (uint8_t *)aRxBuffer, RXBUFFERSIZE, 0xFFFF) != HAL_OK)
    ....
aRxBuffer[RXBUFFERSIZE] = 0;

Obwohl für einen einzelnen Zeichenvergleich, wie Sie ihn im Moment haben, kein Zeichenfolgenvergleich erforderlich ist, könnten Sie einen Zeichenvergleich für das erste und einzige Element des Arrays verwenden:

if (aRxBuffer[0] == 'Y')
    DoSomething();
else
    DoSomethingElse();

Der strcmp benötigt ein Null-Terminator, aber es gibt eine andere Funktion, die Sie verwenden könnten, um Zeichenfolgen zu vergleichen, nämlich strncmp , die die Anzahl der Zeichen annimmt, die Sie vergleichen möchten. So könnten Sie am Ende Folgendes tun:

char *is_correct= "Y";
if (strncmp((char*) aRxBuffer, message,strlen(message) ) == 0)
    DoSomething();
else
    DoSomethingElse();

Dies setzt auch voraus, dass die messageVariable eine feste Zeichenfolge ist.

Seien Sie jedoch vorsichtig: strncmpist kein Drop-in-Ersatz für strcmp. Zum Beispiel strncmp("YB", "YA", 1)wird sagen, dass die Zeichenfolgen übereinstimmen. Das mag in Ordnung sein, aber es könnte auch eine Falle sein.

Warum sich mit strcmp oder strncmp herumschlagen, wenn Sie dies einfach tun können:

uint8_t aRxBuffer;
#define RXBUFFERSIZE (sizeof(aRxBuffer))

if(HAL_UART_Receive(&huart2, (uint8_t *)&aRxBuffer, RXBUFFERSIZE, 0xFFFF) != HAL_OK)
    Error_Handler();

if(aRxBuffer == message)
   DoSomething();
else
   DoSomethingElse(); 
Was ist der Punkt beim Casting von Zeiger uint8_tauf Zeiger auf uint8_t?
Vielleicht, weil der andere Ansatz einfacher auf ein Passwort oder so etwas skalierbar ist?
@Ruslan &aRxBufferist kein Zeiger, sondern ein constZeiger und abhängig von der Signatur von HAL_UART_Receivedürfen Sie keinen constZeiger eingeben, also müssen Sie ihn wegwerfen. (Die Methode sollte constjedoch einen Zeiger verwenden)
@Arsenal Nun, die erste Zeile deklariert aRxBufferals uint8_t, nicht const uint8_t, also ist der Zeiger weder ein Zeiger auf const noch ein Zeiger const. Obwohl ich jetzt sehe, dass dies nur eine Kopie des OP ist, nicht Alex 'Fehler.
@Ruslan vergiss meinen Kommentar, weiß nicht, was ich mir angesehen habe, wahrscheinlich verursacht durch laufende Fusseln für die constRichtigkeit ...
Abgesehen von der seltsamen Besetzung verstehe ich nicht, warum dies so viele Stimmen bekommt. Wenn Sie nur ein einziges Zeichen erwarten, brauchen Sie Ihren Code nicht mit zahlreichen String-Handling-Funktionen aufzublähen. Gesunder Menschenverstand ist ein sehr nützliches Werkzeug beim Programmieren.
Es ist ein wirklich schlechter Programmierstil ... das habe ich verdient ...