STM32F411 El esclavo SPI entra en el bucle infinito de depuración

0

He conectado dos NUCLEOSTM32F411RE juntos, y estoy intentando enviar una carta ASCII de una PC a otra PC en modo Simplex de maestro a esclavo.

Cuando envío un carácter, el esclavo ingresa una rutina en startup_stn32f411xe.s Donde está escrito en el comentario del código. "Este es el código al que se llama cuando el procesador recibe una interrupción inesperada. Simplemente ingresa en un bucle infinito, preservar el estado del sistema para que lo examine un depurador "

He conectado SPI2MOSI (maestro) a SPI2MOSI (esclavo) como se describe en la página 6 (PC3 a PC3)

enlace

También SPI2_SCK a SPI2_SCK (PB10), así como SPI2_NSS a SPI2_NSS (PB12)

CPOL y CPHA están configurados de la misma forma en el cubo. Solo para el esclavo tengo en el NVIC verificó la prioridad 0 de la interrupción global SPI2, también tiene la interrupción global USART2.

La configuración del esclavo SPI es así en main:

void MX_NVIC_Init(void)
{
  /* SPI2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(SPI2_IRQn);
  __HAL_SPI_ENABLE_IT(&hspi2, SPI_IT_RXNE);//My addition

 /* USART2_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(USART2_IRQn);
 __HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE); //My addition
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);//My addition

}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_SLAVE;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
 hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi2.Init.CRCPolynomial = 10;
 HAL_SPI_Init(&hspi2);
 __HAL_SPI_ENABLE(&hspi2); // My addition
 }

Mi controlador de IRQ en STM324fxx_it.c tiene este aspecto

void SPI2_IRQHandler(void)
{
 HAL_SPI_IRQHandler(&hspi2);
 uint8_t data1;
 HAL_SPI_Receive_IT(&hspi2,&data1,sizeof(data1));
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);
}

¿Por qué la interrupción es inesperada en el lado esclavo?

//Adding more info after suggestion,init USART slave main
void MX_USART2_UART_Init(void)
{

 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 HAL_UART_Init(&huart2);
__HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}
//Masterside stm324fxx_it.c
void USART2_IRQHandler(void)
{  
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin,GPIO_PIN_SET);
  HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

}

La rutina de interrupción está preparada para la comunicación bidireccional, y no se ingresa ya que la he iniciado en nvic con

__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);

y no estoy intentando enviar desde la PC conectada esclavo. La transmisión a la PC slaveside, espero lograr con

HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

en

void SPI2_IRQHandler(void)//Thank's for your interest :)
    

2 respuestas

2

Esto funciona en la parte principal de la placa maestra:

SPI2_MOSI (PC3) to SPI2_MOSI (PC3)
SPI2_NSS (PB12) to SPI2_NSS (PB12) 
SPI2_SCK (PB10) to SPI2_SCK (PB10)

Termainalprogram se ejecuta en cada PC conectada a cada placa. Baud: 115200, Sin paridad, CTS / RTS

void MX_NVIC_Init(void)
{
/* USART2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);

}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_MASTER;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
 hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
 hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi2.Init.CRCPolynomial = 10;
 HAL_SPI_Init(&hspi2);
 __HAL_SPI_ENABLE(&hspi2);
}


/* USART2 init function */
void MX_USART2_UART_Init(void)
{
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 HAL_UART_Init(&huart2);
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

En stm32f4xx_it.c para el maestro

void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  data1++; //Icrementing 'A' to 'B'
  HAL_SPI_Transmit(&hspi2,&data1,  (uint16_t)sizeof(data1),HAL_MAX_DELAY);
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);//echoing back to PC
}

En el lado esclavo en main

void MX_NVIC_Init(void)
{
 HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(SPI2_IRQn);
 __HAL_SPI_ENABLE_IT(&hspi2, SPI_IT_RXNE);
 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(USART2_IRQn);
 __HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_SLAVE;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
 hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi2.Init.CRCPolynomial = 10;
 HAL_SPI_Init(&hspi2);
 __HAL_SPI_ENABLE(&hspi2);
}


/* USART2 init function */
void MX_USART2_UART_Init(void)
{
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);
  __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

En el esclavo stm32f4xx_it.c

void SPI2_IRQHandler(void)
{
  HAL_SPI_IRQHandler(&hspi2);
 uint8_t data1;
 HAL_SPI_Receive_IT(&hspi2,&data1,sizeof(data1));
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

}

void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  data1++;
  HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);
}
    
respondido por el Lasse Karagiannis
0

No mencionó MISO cuando describió sus conexiones SPI. Para comunicaciones SPI dúplex completas, necesita las 3 conexiones (MOSI, MISO & SCK) que se encuentran en el diagrama a continuación, más una señal SS o Select cuando se direccionan a varios esclavos:

Es posible que necesite la Señal de selección incluso con solo 1 esclavo. Depende de lo que el esclavo espera ver y de cómo desea gestionar la expansión futura.

    
respondido por el st2000

Lea otras preguntas en las etiquetas