Problemas al leer los estados GPIO establecidos entre las placas STM32F Discovery y Nucleo64

1

Actualmente tengo un problema al configurar un protocolo de comunicación entre una placa de descubrimiento STM32F (con los últimos controladores HAL) y una placa Nucleo64 (con los mismos controladores). Esencialmente, cada placa tiene una línea de saludo de salida, que la otra espera en un momento dado para proceder con su propio código.

El problema es que cualquiera de los tableros no puede leer la línea de intercambio entre manos cuando se establece en un estado alto (GPIO_PIN_SET). Aunque se pueden leer entre sí en un estado bajo (GPIO_PIN_RESET) no estoy seguro de si esto se debe a que la configuración sea correcta o no. He unido las bases de las dos placas para garantizar que se encuentren en un nivel de referencia similar, ya que un nivel de referencia es el único problema que puedo ver en uno u otro no poder leer un estado alto. Estoy muy seguro de que ambas placas tienen una salida de aproximadamente 3.0 V en este estado alto, por lo que siento que están lo suficientemente cerca como para que esto no sea un problema, pero estoy perplejo. ¿Por qué mi placa Nucleo no puede detectar el GPIO_PIN_STATE fuera de la línea de reconocimiento de Discovery cuando está claramente alto y medido como tal en mi osciloscopio ???

Si pudiera obtener ayuda con esto, sería muy apreciado, ya que he estado golpeando mi cabeza contra una pared para este proyecto, que se espera pronto. A continuación, he publicado el código para la configuración de los pines GPIO y la línea de código en la que cualquiera de los tableros se atasca. Estoy bastante seguro de que el problema está relacionado con el hardware, o gira en torno a mí y no entiendo realmente los pines GPIO (aunque he leído todo lo que puedo sobre ellos para entender este problema).

La configuración de la placa Discovery y la línea lógica correspondiente se atasca en ...

#define NUCLEO_TO_DISCOVERY_GPIO_PORT       GPIOA
#define NUCLEO_TO_DISCOVERY_PIN             GPIO_PIN_3

#define DISCOVERY_TO_NUCLEO_GPIO_PORT       GPIOA
#define DISCOVERY_TO_NUCLEO_PIN             GPIO_PIN_10 

#define DISCOVERY_DATAio_CLOCK_ENABLE()     __GPIOD_CLK_ENABLE()
#define DISCOVERY_HSI_CLOCK_ENABLE()        __GPIOA_CLK_ENABLE()

void Communication_config(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    DISCOVERY_DATAio_CLOCK_ENABLE();
    DISCOVERY_HSI_CLOCK_ENABLE();                                                 

    /* .... */

    // Discovery to Nucleo  (Output - Active Low)
    GPIO_InitStructure.Pull  = GPIO_PULLUP;
    GPIO_InitStructure.Pin   = DISCOVERY_TO_NUCLEO_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(DISCOVERY_TO_NUCLEO_GPIO_PORT, &GPIO_InitStructure);

    /* .... */

    /* Instantiate HS pin to high for active low state */
    HAL_GPIO_WritePin(DISCOVERY_TO_NUCLEO_GPIO_PORT,                DISCOVERY_TO_NUCLEO_PIN, GPIO_PIN_SET);

    /* .... */

    // Nucleo to Discovery Handshake  (Input - Active Low)
    GPIO_InitStructure.Pull  = GPIO_NOPULL;
    GPIO_InitStructure.Pin   = NUCLEO_TO_DISCOVERY_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(NUCLEO_TO_DISCOVERY_GPIO_PORT, &GPIO_InitStructure);

    /* .... */ 
}

void Slave_Write(float input){

    int i;

    // Can only write decimal values between 0.0 & 0.99
    int numIntegerDigits = 0;
    int tempDecimalValue = 0;
    int tempIntegerValue = 0;

    int integerValue[8];
    int tempArray[4];

    /* ... */


    // Write first four bits of integer value (MSB first)
    for(i=0;i<4;i++)integerValue[i]=tempArray[i];
    Set_DataLines(tempArray);

    // Signal to Nucleo that pins are ready
    HAL_GPIO_WritePin(DISCOVERY_TO_NUCLEO_GPIO_PORT,    DISCOVERY_TO_NUCLEO_PIN, GPIO_PIN_RESET);

    // Wait for Nucleo to finish reading
    while(HAL_GPIO_ReadPin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN) == GPIO_PIN_SET);

    // Write next four bits of integer value (MSB first)
    for(i=0;i<4;i++)integerValue[i+4]=tempArray[i];
    Set_DataLines(tempArray);

    // Signal to Nucleo that pins are ready
    HAL_GPIO_WritePin(DISCOVERY_TO_NUCLEO_GPIO_PORT, DISCOVERY_TO_NUCLEO_PIN, GPIO_PIN_SET);

    // Wait for Nucleo to finish reading
    while(HAL_GPIO_ReadPin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN) == GPIO_PIN_RESET);

    /* The code gets stuck here, after the discovery to nucleo 

    handshake line is written high. The while loop never evaluates to false 

    because the other piece of code never reads that the handshake line from 

    the discovery is set to high (if it did then it would set the nucleo to 

    discovery handshake line high in response) */

    /* ... */

}

A continuación se muestra la configuración de la placa Nucleo y la comunicación de línea correspondiente se atasca en ...

#define NUCLEO_TO_DISCOVERY_GPIO_PORT           GPIOA
#define NUCLEO_TO_DISCOVERY_PIN                     GPIO_PIN_10  // GPIO_A10

#define DISCOVERY_TO_NUCLEO_GPIO_PORT           GPIOA
#define DISCOVERY_TO_NUCLEO_PIN                     GPIO_PIN_2  // GPIO_A2

#define NUCLEO_DATAo_CLOCK_ENABLE()     __GPIOB_CLK_ENABLE()
#define NUCLEO_DATAi_CLOCK_ENABLE()     __GPIOC_CLK_ENABLE()
#define NUCLEO_HSI_CLOCK_ENABLE()       __GPIOA_CLK_ENABLE()

void NucleoComm_Config(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    NUCLEO_DATAi_CLOCK_ENABLE();
    NUCLEO_DATAo_CLOCK_ENABLE();
    NUCLEO_HSI_CLOCK_ENABLE();                                                 

    /* ... */

    // NUCLEO to Discovery Handshake Pin  (Output - Active Low)
    GPIO_InitStructure.Pull  = GPIO_PULLUP;
    GPIO_InitStructure.Pin   = NUCLEO_TO_DISCOVERY_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(NUCLEO_TO_DISCOVERY_GPIO_PORT, &GPIO_InitStructure);

    /* ... */

    /* Instantiate HS pin to high for active low state */
    HAL_GPIO_WritePin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN, GPIO_PIN_SET);

    /* ... */

    // Discovery to Nucleo Handshake Pin  (Input - Active Low)
    GPIO_InitStructure.Pull  = GPIO_NOPULL;
    GPIO_InitStructure.Pin   = DISCOVERY_TO_NUCLEO_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(DISCOVERY_TO_NUCLEO_GPIO_PORT, &GPIO_InitStructure);

/* ... */


}

float Master_Read(){

    int i;

    // Can only read decimal values between 0.0 & 0.99
    int integerValue[8];
    int decimalValue[8];
    int tempArray[4];

    float tempDecimalValue;
    float returnValue;

    // Wait for Discovery to finish writing
    while(HAL_GPIO_ReadPin(DISCOVERY_TO_NUCLEO_GPIO_PORT, DISCOVERY_TO_NUCLEO_PIN) == GPIO_PIN_SET);

    // Read first four bits of integer value (MSB first)
    Read_DataLines(tempArray);
    for(i=0;i<4;i++)integerValue[i]=tempArray[i];

    // Signal to Discovery that pins have been read
    HAL_GPIO_WritePin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN, GPIO_PIN_RESET);

    // Wait for Discovery to finish writing
    while(HAL_GPIO_ReadPin(DISCOVERY_TO_NUCLEO_GPIO_PORT, DISCOVERY_TO_NUCLEO_PIN) == GPIO_PIN_RESET);

    /* Code gets stuck at this while loop, pin read never returns a 

    GPIO_PIN_SET and thus the while loop never evaluates to true. This is 

    regardless of the fact that the pin is definitely reading 3.0V on my 

    oscilloscope. I am more confused as to why this while loop is stuck than 

    the one in the discovery communication because I know that while loop is 

    simply waiting for the next instruction here, which would be to write 

    Nucleo to Discovery high. Why is the system not reading a high pin state 

    when it clearly is high? */

    /* ... */

}
    
pregunta Luke S

1 respuesta

1

¿Ha comprobado si la adición de una resistencia al voltaje no detectado correctamente ayuda? Algunas placas usan una alta resistencia en lugar de uno de los dos estados que parece esperar (voltajes altos y bajos) y, por lo tanto, necesitan un pullup o una resistencia desplegable para convertir la alta resistencia en un estado de voltaje definido.

    
respondido por el user6030

Lea otras preguntas en las etiquetas