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? */
/* ... */
}