Partage
  • Partager sur Facebook
  • Partager sur Twitter

Liaison UART avec carte STM32

récupérer des données en RS232 avec la carte STM32F746 discovery

28 février 2018 à 16:57:38

Bonjour à tous,

Je viens vers vous pour un problème sur un projet universitaire que nous devons faire pour un master 1.

Explications du projet :

Nous devons récupérer les informations d'un équipement qui dialogue en RS232 via une carte STM32 et afficher les données sur l'écran de la carte STM.

Déroulement des tests :

Notre 1er test à été de relier directement l'équipement à un PC via le port COM. Jusqu'ici tout va bien, aucune difficulté rencontrée.

Maintenant nous devons récupérer les informations de l'équipement sur la carte, et les afficher sur un PC via un port USB à l'aide d'un adaptateur db9. C'est ici que les problèmes commencent.

Notre logique est :

- on recoit les informations sur un UART noté UART1 et on les enregistre dans un buffer à l'aide de la fonction HAL_UART_Receive(&huart1,rx_buffer_huart1,sizeof(rx_buffer_huart1),1);

ensuite on a essayé plusieurs choses :

1 : on transmets les infos du buffer rx_buffer_uart1 sur un autre UART qui lui est relié au PC. Ça n'affiche rien.

2: on copie le buffer rx vers un autre buffer noté tx, puis on transmet le buffer tx. Ça n'affiche rien.

3: on transmet le buffer rx sur un autre uart (noté UART2), on reçoit avec l'UART2 ce qui remplie un autre buffer, et on transmet au PC. Ça n'affiche rien.

PS : Nous avons initialisé les UARTs avec les commandes adéquates, nous sommes sur le même baudrate entre la carte et le PC.

  • Partager sur Facebook
  • Partager sur Twitter
1 mars 2018 à 8:19:02

L'UART du STM32 utilise des niveau logique TTL de 0 et 3.3V tandis qu'une liaison RS232 d'un PC utilise des niveaux logique -12V/+12V donc forcément, il va y avoir un problème.

Dans ton message, tu parles d'un adaptateur USB mais c'est assez vague...

Pourrais-tu nous dire exactement comment tu as relié le STM32 au PC ?

=> quelles sont les liaisons que tu as faites ?

=> quelle est la référence de ton adaptateur ?

  • Partager sur Facebook
  • Partager sur Twitter
3 mars 2018 à 11:17:07

Salut lorrio, 

Sur ma carte stm32f746N discovery je configure l'uart 6 en asynchrone, 8bit sans parité, 1 bit de stop. J'utilise les pins adéquates du rx tx et gnd. Je n'est pas exactement la référence de l'adaptateur, mais ce n'est pas très grave car maintenant nous utilisons un USB UART board. 

Par contre nous avons des choses qui fonctionnent maintenant. Comme la transmission de la carte au PC, j'envois une phrase stockée dans un tableau du stm 32 et je la reçois sur le PC. 

Maintenant il faut que j'arrive à envoyer une phrase sur le terminal, que la carte la reçois et qu'elle me la transmettre. Sauf que quand j'envois "coucou" il me renvoie "ccccccccccc".

Pour recevoir j'utilise la fonction receive. Mais je ne sais pas comment faire pour que ma carte enregistre tous les caractères.

Si vous avez des idées je suis preneur.

  • Partager sur Facebook
  • Partager sur Twitter
7 mars 2018 à 16:04:50

C'est bon tous fonctionne sur la liaison, nous récupérons bien les informations transmises par l'équipement de la voiture.

Je te remercie pour ton aide.

PS : peut-on récupérer la taille du tableau que rempli la fonction receive ? Car nous devons maintenant trier nos données. Mais je pense pas que cette question soit en adéquation avec le sujet.

  • Partager sur Facebook
  • Partager sur Twitter
7 mars 2018 à 19:15:32

Si tu appelles n fois la fonction avec une taille de 1, tu sauras que la taille fait n caractères ;)
  • Partager sur Facebook
  • Partager sur Twitter
13 mars 2018 à 16:13:51

Salut, 

Ok je vais regarder ça dans l'après-midi.

Je chercher actuellement à copier le buffer rx-buffer dans un autre tableau (appelé tab) pour pouvoir ensuite travailler sur tab.

Je n'est pas trouvé beaucoup de réponse à part utiliser le DMA, mais notre prof nous a dis qu'il existait une autre façon de faire sans le DMA.

  • Partager sur Facebook
  • Partager sur Twitter
13 mars 2018 à 22:08:45

Le DMA, c'est bien mais pas toujours très utile comparativement à la complexité qu'il peut y avoir pour le mettre et place.

Si c'est pour copier quelques octets, ça ne vaut franchement pas le coût.

Tu peux très bien utiliser une boucle for pour copier le contenu d'une zone à l'autre ;)

for ( int idx = 0 ; idx < 16 ; idx++ ) {
    buffer_dest[idx] = buffer_src[idx];
}



  • Partager sur Facebook
  • Partager sur Twitter
18 mars 2018 à 17:13:30

Bonjour 

Je viens de réussir à copier le tableau dans un autre tableau avec ta technique. 

Pour la suite j'ai utilisé un timer en interruption pour ma liaison UART. 

J'ai réussi à récupérer les informations que je souhaite récupérer dans une trame fixe. Il me reste plus qu'a créer un petit programme qui cherche mes informations sur une trame dynamique.

Je te remercie lorrio pour ton aide.

PS : Pour récupérer la longueur de la trame, j'ai essayé plusieurs techniques. La seul qui a fonctionné c'est une exécution pas à pas du logiciel.

Par compte j'ai essayé la fonction strlen avec un tableau de char fixe : char tableau[]="Coucou"; Mais la fonction me renvoie 1. Or sur codeblocks ça fonctionne très bien. Une idée peut-être ? 

  • Partager sur Facebook
  • Partager sur Twitter
18 mars 2018 à 17:43:45

C'est plutôt étrange que strlen ne marche pas, peut-être un problème de lib.

Mais au pire, tu peux créer cette fonction toi même ;)

int mystrlen( const char * const str ) {
    int len = 0;
    while ( str[len] != '\0' ) {
        len++;
    }
    return len;
}



  • Partager sur Facebook
  • Partager sur Twitter
18 mars 2018 à 21:08:39

J'avais déja essayé d'en créer une manuel mais ça ne fonctionne pas. C'est pas grave en faisant l'exécution pas à pas j'ai retrouvé la trame et j'ai fais strlen de cette trame sur codeblocks et ça m'a sorti 214 donc c'est bon. 

Merci de ton aide. 

J'ai réussi a intégrer mon programme sur atollic, tous fonctionne en liaison UART manque plus qu'a reussir à l'affiché sur l'écran LCD. D'ailleurs peut être que tu sais. L'écran galère avec l'affichage de tableau, est-ce qu'il est possible de regroupés les valeurs d'un tableau en un int. Par exemple tab[0] =1, tab[1]= 0, tab[2]=0 et avoir un int = 100 ?

  • Partager sur Facebook
  • Partager sur Twitter
19 mars 2018 à 8:14:13

La encore, tu peux faire la fonction toi même ;)

int str2int( const char * const str ) {
    int idx = 0;
    int result = 0;
    while ( str[idx] != '\0' ) {
        result *= 10;
        result += ( str[idx] - '0' );
        idx++;
    }
    return result;
}



  • Partager sur Facebook
  • Partager sur Twitter
23 mars 2018 à 11:47:33

Bonjour, 

Merci une personne de mon groupe à utilisé une autre fonction pour faire sert strtod, moi j'ai utilisé la tienne sur mon mini projet et ça a fonctionné du tonnerre. Je te remercie 

Il me reste plus qu'a trouver comment faire mon compteur de vitesse.

Je veux utiliser un timer en interruption et dans cette interruption je scrute une gpio en input ou j'ai branché un GBF.

Configuration timer :

Mon timer compte sur une seconde pile (1Hz à l'oscilloscope).

Mon GBF est réglé sur 7 Hz. 

Mais je ne sais pas comment dire que je veux qu'il teste la gpio pendant toute la seconde, sachant que une boucle while ne fonctionne pas et ça non plus je ne c'est pas pourquoi.

Mon programme est 

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */
  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */
  HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_1);
  if(HAL_GPIO_ReadPin(GPIOI,GPIO_PIN_3)==1)
  	{
  		compteur=compteur+1;
  	}
}

En faisant le debug ma variable compteur ne s'incrémente pas. 

Dans ma tête elle devrais avoir la valeur 7.

Si t'a une idée tu est le bienvenue ^^

  • Partager sur Facebook
  • Partager sur Twitter
23 mars 2018 à 12:10:40

Actuellement, ton interruption s'exécute une fois par seconde.

Donc une fois par seconde, elle vérifie l'état de la pin du GBF et incrémente la variable.

Mais cette GPIO a une fréquence de 7 Hz donc elle va changer 7 fois par secondes.

Du coup, le GBF a le temps de changer 7 fois alors que l'interruption du timer n'aura fait qu'une mesure.

Si l'on fait un chronogramme, cela donne quelque chose comme ça :

GBF:
1       2       3       4       5       6       7       8       9      10
+---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+

  /\                                                      /\
  ||                                                      ||
  ||                                                      ||
  ++- TICK TIMER n°1                                      ++- TICK TIMER n°2

Bref, ton timer étant à 1 Hz alors que le GBF est à 7 Hz, il fera toujours la mesure lorsque le signal est à l'état HIGH, ou à l'état LOW suivant le déphasage qu'il y a entre les 2.

C'est donc normale que ta mesure donne n'importe quoi.

Pour faire une mesure de vitesse, il faut 2 choses :

- mettre une interruption (typiquement le périphérique External Interupt) qui incrémente la valeur à chaque front montant

- mettre une autre interruption periodique (ton timer) qui relève à interval régulier la valeur incrémentée par l'autre interruption

  • Partager sur Facebook
  • Partager sur Twitter
16 décembre 2020 à 11:42:04

Salut Pixoumax85

comment tu a fait pour recevoir toute la chaine reçu j'ai un problème, enfaite ma fonction recieve me retourne qu'un seul caractére. 

merci

  • Partager sur Facebook
  • Partager sur Twitter
2 janvier 2021 à 23:33:35

Joli déterrage d'un sujet datant de 2018...

J'en profite aussi que l'on peut lire ceci sur la page du profil de Pixoumax85 : Dernière connexion : 24 mars 2018

Du coup, je doute fort qu'il te réponde, tu ferais mieux d'ouvrir un nouveau sujet et détailler ton problème là bas.

Sur ceux, je ferme.

-
Edité par lorrio 2 janvier 2021 à 23:33:54

  • Partager sur Facebook
  • Partager sur Twitter