Détection automatique de la vitesse de transmission pour le STM32L0

Je ne parviens pas à détecter automatiquement le débit en bauds sur le STM32L0 . J’utilise la couche d’abstraction matérielle (HAL).

Mon code d’initiation est:

 /* USART1 init function */ void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 300; huart1.Init.WordLength = UART_WORDLENGTH_9B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_EVEN; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT; huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE; huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT; HAL_UART_Init(&huart1); } 

Les octets que j’envoie sur l’UART1 sont les suivants:

  0 1 2 3 4 5 6 7 8 000x 68 0B 0B 68 53 FD 52 FF FF .. etc. 0x68 = 0b01101000 0x0B = 0b00001011 0xFD = 0b11111101 <-- Character starting with 1, baudrate should be detected 0xFD : start 1 1 ..... ___ bit __________ ¦______¦ ... 

Pourquoi le débit en bauds n’est-il pas détecté? J’ai essayé:

UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT et UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE

J’ai donc ajusté la chronologie du réglage du mode et l’activation dans le pilote à partir de:

  /* if required, configure auto Baud rate detection scheme */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) { assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); /* set auto Baudrate detection parameters if detection is enabled */ if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) { assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); } } 

à

  /* if required, configure auto Baud rate detection scheme */ if(HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) { assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart- /* set auto Baudrate detection parameters if detection is enabled */ if(huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) { assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); } MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); } 

Ne fait rien.

Aussi ce qui suit semble bien:

La fréquence source de l’horloge doit être compatible avec la vitesse de communication attendue (en cas de suréchantillonnage de 16, le débit en bauds est compris entre fCK / 65535 et fCK / 16. En cas de suréchantillonnage de 8, la vitesse de transmission est entre fCK / 65535 et fCK / 8).

Je suréchantillonne par 16, donc

 fCK= 16000000 fCK > 16000000 / 65535 = 244 = 244 Hz fCK < 16000000 / 16 = 1000000 = 1 MHz 

Mes débits binarys au choix sont: 19200/ 9600 /2400 /300

Si vous ne parvenez pas à spécifier le contenu précis d’un seul octet à examiner par le matériel de détection du débit en bauds automatique du STM32L0, vous pourrez toujours “lancer votre propre” schéma de détection du débit en bauds automatique, si les hypothèses suivantes peuvent être établies pour votre système:

  • Il est possible de rejeter un nombre arbitraire de caractères reçus contigus au cours du processus de détection automatique des bauds.

  • Pendant tout intervalle arbitraire où plusieurs caractères sont reçus, on peut supposer que la séquence de bits 010 ou 101 est un événement relativement commun.

  • L’appareil dispose d’un périphérique de timer à usage général disponible qui peut être mappé sur la même broche d’appareil que le signal USART Rx.

Si toutes les réponses ci-dessus sont vraies, vous pouvez créer votre propre schéma de détection automatique de la vitesse de transmission en utilisant la fonction de capture d’entrée de l’un des périphériques de timer à usage général de la puce. Ces timers peuvent être configurées pour utiliser l’horloge interne de 16 MHz comme source d’horloge. Chaque temporisateur contient un compteur de 16 bits. Avec une horloge de 16 MHz, la timer a une résolution de mesure d’impulsions (1/16 000 000 Hz) = 62,5 nS.

La durée d’un bit à votre débit préféré est la suivante:

  Baud Microseconds 62.5-nS Clocks ---- ------------ -------------- 300 3,333.3 53,333 2400 416.7 6,667 9600 104.2 1,667 19200 52.1 833 

Vous pouvez configurer le minuteur en mode Capture d’entrée et le faire compter le nombre d’horloges entre deux transitions de bord adjacentes. Effectuez cette opération pour un nombre relativement élevé d’échantillons, par exemple 100. Bon nombre de ces échantillons représenteront la largeur de deux zéros adjacents ou plus, ou de deux zéros adjacents ou plus. Mais vous recherchez l’échantillon le plus court . Si vous en trouvez un compris entre 831 et 835 comptes, vous pouvez être raisonnablement assuré que le débit en bauds est de 19 200. Après 100 échantillons, si le plus court que vous avez trouvé se situe entre 1665 et 1669 comptes, vous pouvez supposer que le débit en bauds est 9600. Et ainsi de suite.

Pendant ce processus, USART est désactivé pendant que le minuteur est affecté à la broche. Après avoir déterminé le débit en bauds à utiliser, reconfigurez la broche pour l’affecter à la fonction de périphérique USART Rx.

De la fiche technique ( Celui-ci , page 759). “Avant d’activer la détection automatique du débit en bauds, il faut choisir le mode de détection du débit en bauds automatique” . -> Essayez de changer vos lignes pour:

huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT; huart1.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT; huart1.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE; `

Je ne pense pas que cela fera une grande différence lorsque vous démarrez le processus init avec HAL_UART_Init(&huart1); de toute façon. Mais ça vaut le coup d’essayer. Vous pouvez également vérifier votre fréquence source d’horloge.

Puisque vous utilisez ABRMOD[1:0] = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT (mode de débit en bauds automatique 0), le tout premier caractère reçu après l’initialisation doit avoir un bit de poids fort élevé pour que le mécanisme de débit en bauds automatique fonctionne correctement. Mais vous dites que votre séquence d’octets de données est

 68 0B 0B 68 53 FD 52 FF FF .. etc. 

Le premier octet de cette séquence est 0x68 , qui a un MSB bas. Par conséquent, le matériel de détection automatique en bauds écrira une valeur incorrecte sur le BRR. Changez votre premier octet pour avoir un bit de poids fort, ce qui devrait résoudre votre problème.


modifier

Le STM32L0 dispose de 4 modes de détection de la vitesse de transmission automatique, ce qui vous permet de spécifier différentes caractéristiques de l’octet mesuré. Du manuel de référence RM0367 :

Ces modes sont:

  • Mode 0: Tout caractère commençant par un bit à 1. Dans ce cas, l’USART mesure la durée du bit de début (front descendant à front montant).

  • Mode 1: Tout caractère commençant par un motif de bits 10xx. Dans ce cas, l’USART mesure la durée du premier et du premier bit de données. La mesure est faite d’un bord à l’autre, ce qui garantit une meilleure précision dans le cas de pentes lentes du signal.

  • Mode 2: un cadre de caractère 0x7F (il peut s’agir d’un caractère 0x7F dans le premier mode LSB ou de 0xFE dans le premier mode MSB). Dans ce cas, le débit en bauds est mis à jour tout d’abord à la fin du bit de début (BR), puis à la fin du bit 6 (sur la base de la mesure effectuée d’un front descendant à l’autre: BR6). Les bits 0 à 6 sont échantillonnés au niveau des BR, tandis que les autres bits du caractère sont échantillonnés au niveau du BR6.

  • Mode 3: Un cadre de caractère 0x55. Dans ce cas, le débit en bauds est mis à jour tout d’abord à la fin du bit de début (BR), puis à la fin du bit 0 (sur la base de la mesure effectuée de front descendant à front descendant: BR0), et enfin à la fin du bit 6 (BR6). Le bit 0 est échantillonné au niveau des BR, le bit 1 au bit 6 est échantillonné au niveau du BR0 et des bits supplémentaires du caractère sont échantillonnés au niveau du BR6. En parallèle, une autre vérification est effectuée pour chaque transition intermédiaire de la ligne RX. Une erreur est générée si les transitions sur RX ne sont pas suffisamment synchronisées avec le récepteur (le récepteur étant basé sur le débit en baud calculé sur le bit 0).

Si vous ne pouvez pas vous assurer que le premier octet reçu après avoir activé la détection automatique des bauds convient à l’un des modes ci-dessus, alors je crains que la fonction de détection automatique des bauds intégrée ne fonctionne pour vous.

Tout ne peut pas être perdu, cependant. Voir ma deuxième réponse à votre question.