uint8_t pour un buffer

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je travaille actuellement avec un STM32F446RE. Pour m’entraîner avec le périphérique UART, j’esaye d’allumer et d’éteindre une led lorsque j’appuie sur une touche. J’ai réussi sans problème avec la touche 1 mais pas moyen de le faire avec la touche t (comme toggle). Je sais d’où vient le problème mais pas comment le résoudre.

La fonction du HAL pour recevoir un caractère est la suivante :

/**
  * @brief  Receives an amount of data in blocking mode.
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
  *         of u16 available through pData.
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
  *               the configuration information for the specified UART module.
  * @param  pData Pointer to data buffer (u8 or u16 data elements).
  * @param  Size  Amount of data elements (u8 or u16) to be received.
  * @param  Timeout Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

Première question : pourquoi pData est un uint8_t et non un char ? Serais-ce parce que mon microcontrôleur est 32 bits et qu’il faut s’assurer que ce soit 8 bits ? (Je pensais qu’un char était 8 bits quoiqu’il arrive).

Le livre que j’utilise (Mastering STM32) m’explique comment l’utiliser et j’arrive avec ce code :

uint8_t readUserInput()
{
    char readBuffer[1];

    HAL_UART_Receive(&huart2, (uint8_t*)readBuffer, 1, HAL_MAX_DELAY);

    return atoi(readBuffer);
}

void processUserInput(uint8_t op)
{
    if (op == 1) {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);

        if (HAL_GPIO_ReadPin(LED_GPIO_Port, LED_Pin) == 1) {
            HAL_UART_Transmit(&huart2, (uint8_t*)msg_led_on, strlen(msg_led_on), HAL_MAX_DELAY);
        } else {
            HAL_UART_Transmit(&huart2, (uint8_t*)msg_led_off, strlen(msg_led_off), HAL_MAX_DELAY);
        }
    }
}
  • Pourquoi un tableau d’un seul caractère char readBuffer[1]; ? Comme on va retourner et utiliser un pointeur vers uint8_t, ça ne serait pas plus simple de faire uint8_t *readBuffer ?
  • Si je remplace 1 par 166 (le code ASCII de t), ça ne fonctionne pas. Je pense que le problème vient de la conversion du char[] en uint8_t* ou de la fontion atoi. Qu’est-ce que je dois mettre à la place de op == 1 pour que ça fonctionne avec la touche t ? Pourquoi ?

Merci pour votre aide, en vous souhaitant une bonne fin de journée.

le défaut du char, c’est qu’on ne sait pas s’il est signé ou non, et comme HAL_UART_Receive peut recevoir des données binaires, qui peuvent être manipulées avec des opérations bit à bit, notamment des décalages, il est intéressant de s’assurer que tout est traité comme non signé.

Bon par contre ce code est faux:

uint8_t readUserInput()
{
    char readBuffer[1];

    HAL_UART_Receive(&huart2, (uint8_t*)readBuffer, 1, HAL_MAX_DELAY);

    return atoi(readBuffer);
}

atoi va lire une chaine de caractères jusqu’au caractère de fin \0, donc le code si dessus a un comportement indéterminé. Les contraintes d’alignement de ARM font que ça se passe pas trop mal, mais le code est mauvais quand même, même si readUserInput renvoie la valeur numérique du chiffre lu (la valeur numérique, pas le caractère ASCII, d’où le fait que ça ne puisse pas marcher avec 't’).

PS: en faisant comme suit, tu pourras remplacer le 1 par t:

uint8_t readUserInput()
{
    char readBuffer;

    HAL_UART_Receive(&huart2, (uint8_t*)&readBuffer, 1, HAL_MAX_DELAY);

    return readBuffer;
}

void processUserInput(uint8_t op)
{
    if (op == '1') {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);

        if (HAL_GPIO_ReadPin(LED_GPIO_Port, LED_Pin) == 1) {
            HAL_UART_Transmit(&huart2, (uint8_t*)msg_led_on, strlen(msg_led_on), HAL_MAX_DELAY);
        } else {
            HAL_UART_Transmit(&huart2, (uint8_t*)msg_led_off, strlen(msg_led_off), HAL_MAX_DELAY);
        }
    }
}
+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte