STM32 HAL USART recevoir par interruption
J'ai du mal à recevoir des données sur l'USART. Ce que je veux réellement à atteindre les ist, que je peux recevoir une commande de plus de USART avec de la longueur (seulement une longueur maximale possible). J'ai donc utiliser la routine d'interruption pour vérifier chaque caractère reçu, mais j'ai en quelque sorte toujours pas possible d'obtenir ce que je veux. La routine est appelée à chaque fois que je reçois un nouveau personnage, mais de toute façon HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx) n'est pas mise à jour en temps réel, alors je ne vois pas reçu de caractère lorsque je vérifie rx_data[pointeur], mais quelques temps plus tard, il est dans le rx_data tampon.
Ce que j'ai à ce jour:
int pointer =0;
...
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if ( USART1->ISR & UART_IT_TXE) {
}
if ( USART1->ISR & UART_IT_RXNE) {
HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx);
if(rx_data[pointer]=='int pointer =0;
...
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if ( USART1->ISR & UART_IT_TXE) {
}
if ( USART1->ISR & UART_IT_RXNE) {
HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx);
if(rx_data[pointer]=='\0') {
pointer=0;
readCommand(rx_data);
clearBuffer(rx_data,buff_size_rx);
} else {
pointer++;
if(pointer>=buff_size_rx) {
pointer=0;
}
}
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
') {
pointer=0;
readCommand(rx_data);
clearBuffer(rx_data,buff_size_rx);
} else {
pointer++;
if(pointer>=buff_size_rx) {
pointer=0;
}
}
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
- quel est le point de dupliquer le tampon de la mise en œuvre? BTW, vous ne pouvez pas appeler HAL_UART_Receive_IT de là, et ensuite appeler HAL gestionnaire d'irq qui l'appelle à nouveau. Faire nu registres ou HAL, pas les deux. De toute façon HAL pour la simple périphérique comme uart?
- Qu'entendez-vous par dublicating le tampon de la mise en œuvre? J'aimerais réaliser cela dans HAL, mais j'ai vraiment pas trouvé de solution pour le moment. DMA serait bien, mais là, j'ai besoin d'une longueur fixe pour chaque commande ou l'utilisation d'un délai d'attente, ce qui n'est pas pris en charge par HAL pour une STM32F303K8T6.
- Hal t-il. Vous ne devriez pas faire quoi que ce soit avec le buffet si vous utilisez hal. Je voudrais mettre en œuvre nus resister moi-même, mais il est de votre code, sans cette stupide de la bibliothèque. Combien de temps vos messages? Si bref il n'y a pas de point de DMA.
- Bien que les messages ne sont que d'environ 16 caractères. Si j'utilise juste HAL_UART_Receive_IT, il va écrire les caractères de la rx_data tampon, mais je ne jamais voir si j'ai reçu un caractère nul et il agit comme un tampon en anneau, qui ne fonctionne que pour une longueur fixe.
- Regarde le code que j'utilise pour recevoir arbitraire des données GPS here. Il utilise HAL, mais les raccourcis de l'interruption. Si je devais le refaire je vidage de HAL et d'aller à la plaine CMSIS.
- OMI DMA pour les 16 octets n'est pas la peine
- Soares nue registre, CMSIS n'est que le tas de définitions & certaines fonctions inline.
- Yep, pas de bibliothèques.
Vous devez vous connecter pour publier un commentaire.
HAL_UART_Receive_IT()
n'est pas destiné à être appelée à partir d'un gestionnaire d'interruption de cette façon, mais pour initier la réception d'un fixe nombre d'octets via l'interrompre.Une solution possible est de vérifier votre tampon d'entrée après
HAL_UART_IRQHandler()
complète, c'est à dire dans le/* USER CODE BEGIN USART1_IRQn 1 */
section. Lorsqu'une commande est traitée, vous pouvez réinitialiserpRxBuffPtr
etRxXferCount
dans la poignée de la structure de leurs valeurs d'origine pour démarrer à partir du début de la mémoire tampon de nouveau.Un autre
horriblesolution possible serait d'appelerHAL_UART_Receive_IT()
avec une taille de mémoire tampon de 1, et mis en place unHAL_UART_RxCpltCallback()
gestionnaire qui vérifie la réception de l'octet à chaque fois, et les appelsHAL_UART_Receive_IT()
à nouveau si nécessaire.Bien sûr, vous pourriez le faire sans HAL, comme PeterJ et d'autres (toujours) suggèrent.
UART->BRR
valeur selon le manuel de référence, ou de copier le code de hal.UART->CR1=USART_CR1_RE|USART_CR1_TE|USART_CR1_UE|USART_CR1_RXNEIE;
Maintenant, vous obtenez des interruptions.UART->SR
dans une variable temporaire, et de l'examiner.UART->DR
lorsqu'il y a réception d'un octet d'attente, faire de la gestion d'erreur dans le cas contraire (plus tard).Interruption de réponse et le temps de traitement est souvent critique dans les applications embarquées, et HAL déchets juste le beaucoup de.
HAL_UART_Receive_IT()
n'est jamais appelé dans leHAL_UART_IRQHandler()
, ou n'importe où ailleurs dans le HAL bibliothèques. La réelle lecture de laUSART->DR
registre se produit dansUART_Receive_IT()
(sans leHAL_
préfixe), qui est déclarée statique, n'est pas accessible à partir du programme utilisateur.La normale HAL bibliothèque n'est pas utile pour la réception continue ou de commandes avec des longueurs différentes.
Si vous avez la complète HAL paquet installé, vous pouvez regarder les exemples de la LuxLevel interface.
La chose principale est de vous usart à la réception continue:
L'USART C'Gestionnaire devrait ressembler à
La dernière chose à configurer est le Rappel
Où vous pourriez mettre les octets dans un tampon et de les traiter dans la boucle principale, ou où vous voulez.
Depuis que je suis tombé sur le problème aujourd'hui et ne pouvait pas trouver une bonne solution, je tiens à vous présenter un très simple, à l'aide de la plupart de la couche d'abstraction matérielle, mais en évitant les problèmes décrits...
Court verison de mon approche est la suivante:
Dans le dernier utilisateur section de code (pour le USART exemple, si vous utilisez plus d'un) de
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
, activer l'IRQ avec:Puis mettre le code souhaité dans votre fonction d'interruption:
Ne pas utiliser HAL_UART_Receive_IT n'importe où, il va désactiver l'IRQ et vous avez besoin de ré-activer, si vous voulez obtenir appelée à chaque réception.
La version longue peut être trouvé dans mon post ici...