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);
}
}
Für die strcmp
Funktion 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 message
Variable eine feste Zeichenfolge ist.
strncmp
ist 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();
uint8_t
auf Zeiger auf uint8_t
?&aRxBuffer
ist kein Zeiger, sondern ein const
Zeiger und abhängig von der Signatur von HAL_UART_Receive
dürfen Sie keinen const
Zeiger eingeben, also müssen Sie ihn wegwerfen. (Die Methode sollte const
jedoch einen Zeiger verwenden)aRxBuffer
als 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.const
Richtigkeit ...
PeterJ
aRxBuffer
ein Byte lang ist, kann es keine nullterminierte Zeichenfolge sein?Arsenal
Merelda
Arsenal
message
für uns Antworter immer noch außerhalb des Geltungsbereichs liegt, könnte das Problem auch damit zusammenhängen.Ruslan
memcmp
anstelle von verwendenstrcmp
, 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).Merelda