IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Firmware STM32F4 (UART) [STM32]


Sujet :

Embarqué

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Par défaut Firmware STM32F4 (UART)
    Bonjour a tous, je suis entrain d’étudié un programme pour effectuer une liaison UART entre 2 carte STM32F429 et je bloque sur des conditions ternaires:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
    (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 |=  ((__INTERRUPT__) & UART_IT_MASK)): \
    ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
    Dans ces lignes j'ai repéré comme opérateurs ?: (condition), |= (Affectation OU entre bits), >> (decalage a droite), & (ET entre bits) mais difficile a dechiffrer pour moi.

    SI quelqu’un peut m'aider a comprendre ces quelques lignes je l'en remercie d'avance.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 498
    Billets dans le blog
    1
    Par défaut
    Cette ligne est beaucoup trop compliquée et est un bon exemple de ce qu'il ne faut pas faire. Qui a fait ? Histoire de le fouetter

    La seule solution pour arriver à la déchiffrer est sans doute de la réindenter un peu mieux, par exemple comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ((((__INTERRUPT__) >> 28) == 1)
    		? 
    		((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK))
                    :
                    (((__INTERRUPT__) >> 28) == 2)
                                                                    ?
                                                                    ((__HANDLE__)->Instance->CR2 |=  ((__INTERRUPT__) & UART_IT_MASK))
    		                                                :
    		                                                ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)));
    Personnellement, je n'ai pas vraiment envie de te dire exactement ce que ça fait ^^ Tu peux aussi traduire ça avec des if / else. Ici, tu peux commencer par :
    - si __INTERRUPT__ décalé de 28 vers la droite vaut 1 (en gros, __INTERRUPT__ a pour partie haute 0b0001, probablement):
    * on effectue un OU logique le champ CR1 et ((__INTERRUPT__) & UART_IT_MASK), on met ça dans CR1 et on "renvoie" cette valeur
    - sinon:
    * on fait un truc dans le même genre.

    En écrivant ça, je viens de comprendre ce que fait ce code : il teste si la partie haute de __INTERRUPT__ vaut 1 (ou 2 ou autre chose, respectivement) et fait un OU logique entre le champ CR1, (ou CR2 et CR3, respectivement) et ((__INTERRUPT__) & UART_IT_MASK)) pour modifier ce champ, et "renvoie" la nouvelle valeur. Je ne vois pas d'affectation de la valeur de la structure ternaire, donc cette valeur est peut-être jetée. C'est dommage car c'est justement l'intérêt d'une structure ternaire : s'évaluer et donner une valeur.

    Un code acceptable aurait été, sauf erreur de ma part :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	if((__INTERRUPT__ >> 28) == 1)
    	{
    		__HANDLE__->Instance->CR1 |= __INTERRUPT__ & UART_IT_MASK;
    	}
    	else if((__INTERRUPT__ >> 28) == 2)
    	{
    		__HANDLE__->Instance->CR2 |= __INTERRUPT__ & UART_IT_MASK;
    	}
    	else
    	{
    		__HANDLE__->Instance->CR3 |= __INTERRUPT__ & UART_IT_MASK;			
    	}

  3. #3
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Je confirme, tu parles d'une horreur ! Pour ne plus rien y comprendre le jour où tu veux revoir le source, on ne peut pas faire mieux.

    En ayant juste regardé les spec de ton micro (et pas la datasheet), je dirai que ce bout de programme détermine le quel UART à déclenché une interruption. Ton micro en possède plusieurs sauf erreur de ma part.

    On dirait que ton micro gère 3 UART dans ton application ?

    Il faudrait regarder dans la datasheet quel bit est CR1 et qu'est ce qu'on regarde avec interrupt décalé de 28 ?
    Tu as le lien vers la datasheet pour qu'on regarde les registres qui concerne l'UART car quand je vais sur le site de ST, je tombe bien sûr la doc constructeur mais je n'ai pas d'info sur les registres !?

  4. #4
    Membre éclairé
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Par défaut
    Bonjour,

    merci pour vos réponse, il me semble nécessaire de rajouter un peu plus de code afin que vous arriviez a mieux cerner ce que fais le programme.

    Debut de la fonction!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
    {
      uint32_t tmp = 0;
      
      tmp = huart->State;
      if((tmp == HAL_UART_STATE_READY) || (tmp == HAL_UART_STATE_BUSY_RX))
    .....
    .....
    .....
     /* Enable the UART Parity Error Interrupt */
        __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
    Voir fichier uart.png pour la definition de la fonction

    __HAL_UART_ENABLE_IT renvoi a un header ou se trouve les conditions ternaires:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
                                                     
    /** @brief  Enable the specified UART interrupt.
      * @param  __HANDLE__: specifies the UART Handle.
      *         This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or 
      *         UART peripheral.
      * @param  __INTERRUPT__: specifies the UART interrupt source to enable.
      *          This parameter can be one of the following values:
      *            @arg UART_IT_CTS:  CTS change interrupt
      *            @arg UART_IT_LBD:  LIN Break detection interrupt
      *            @arg UART_IT_TXE:  Transmit Data Register empty interrupt
      *            @arg UART_IT_TC:   Transmission complete interrupt
      *            @arg UART_IT_RXNE: Receive Data register not empty interrupt
      *            @arg UART_IT_IDLE: Idle line detection interrupt
      *            @arg UART_IT_PE:   Parity Error interrupt
      *            @arg UART_IT_ERR:  Error interrupt(Frame error, noise error, overrun error)
      * @retval None
      */
    #define UART_IT_MASK  ((uint32_t)0x0000FFFF)
    #define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)   ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
                                                                                              (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 |=  ((__INTERRUPT__) & UART_IT_MASK)): \
                                                                                              ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
    Pour la definition des bits voir usart_cr1 en attaché et voir message suivant pour usart_cr2 et usart_cr3
    Images attachées Images attachées     

  5. #5
    Membre éclairé
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Par défaut
    ci-joint les registres usart_cr2 usart_cr3.

    Merci pour votre patience, j'ai essayé de mettre le plus d'info, j'espère que cela ne sera pas trop brouillon.
    Images attachées Images attachées     

  6. #6
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Il manque une info pour comprendre.
    C'est le décalage de 28 pour le quel je n'ai pas ce qu'il faut :

    ((__INTERRUPT__) >> 28) == 1) fait une chose simple, tu dois avoir un registre de 32 bits quelque part :

    xxxx 0000 0000 0000 0000 0000 0000 0000

    Cette macro de la mort fait un décalage de 28 bits, de ce registre vers la droite ce qui donne :

    0000 0000 0000 0000 0000 0000 0000 xxxx

    Le but étant de regarder la valeur des x pour faire, si par exemple la première condition est rempli : (__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK))

    Tu peux nous donner aussi la valeur de UART_IT_PE pour qu'on essaye de comprendre.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 20/07/2006, 12h30
  2. [Où poster ?] Modifier un firmware
    Par Halobox dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 4
    Dernier message: 31/03/2006, 21h56
  3. firmware pour graveur LG gma 4020b
    Par jeanpierreco dans le forum Périphériques
    Réponses: 1
    Dernier message: 23/10/2005, 20h29
  4. Edition et modification d'icones dans firmware demodulateurs
    Par cachousam dans le forum Langages de programmation
    Réponses: 1
    Dernier message: 23/04/2005, 16h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo