Estoy trabajando en un proyecto simple con stm32f0. el proyecto es cuando presiono el botón en la placa, el SPI1 de la MCU debe enviar los datos. Todas las cosas funcionan bien pero hay un problema. mira la rutina de interrupción EXTI:
void EXTI0_1_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_RESET );
HAL_SPI_Transmit_IT( &hspi1 , (uint8_t*)aTxBuffer , 9 );
HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_SET );
}
dos funciones manejan la interrupción EXTI y luego las ignoran. La tercera función es este HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_RESET );
que restablece el pin GPIOA4. Después de esto, tenemos que enviar los datos. ok, entonces usamos esta función HAL_SPI_Transmit_IT( &hspi1 , (uint8_t*)aTxBuffer , 9 );
y para terminar tenemos que configurar el pin nuevamente. Entonces uso esta función HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_SET );
. Bien, ahora veamos el resultado.
oh! ¿puedes ver? ¡El pin NSS se apaga inmediatamente! ¿Por qué?
la función HAL_GPIO_WritePin
:
/**
* @brief Sets or clears the selected data port bit.
*
* @note This function uses GPIOx_BSRR register to allow atomic read/modify
* accesses. In this way, there is no risk of an IRQ occurring between
* the read and the modify access.
*
* @param GPIOx: where x can be (A..F) to select the GPIO peripheral for STM32F0 family
* @note GPIOE is available only for STM32F072.
* @note GPIOD is not available for STM32F031.
* For STM32F051 and STM32F030: (0..15) for GPIOA, GPIOB, GPIOC, (2) for GPIOD and (0..1, 4..7) for GPIOF.
* For STM32F072: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF.
* For STM32F031: (0..15) for GPIOA, GPIOB, (13..15) for GPIOC and (0..1, 6..7) for GPIOF.
* @param GPIO_Pin: specifies the port bit to be written.
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
* @param PinState: specifies the value to be written to the selected bit.
* This parameter can be one of the GPIO_PinState enum values:
* @arg GPIO_BIT_RESET: to clear the port pin
* @arg GPIO_BIT_SET: to set the port pin
* @retval None
*/
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if (PinState != GPIO_PIN_RESET)
{
GPIOx->BSRRL = GPIO_Pin;
}
else
{
GPIOx->BSRRH = GPIO_Pin ;
}
}
la función HAL_SPI_Transmit_IT
:
/**
* @brief Transmit an amount of data in no-blocking mode with Interrupt
* @param hspi: SPI handle
* @param pData: pointer to data buffer
* @param Size: amount of data to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
{
assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
if(hspi->State == HAL_SPI_STATE_READY)
{
if((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(hspi);
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = pData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
hspi->pRxBuffPtr = NULL;
hspi->RxXferSize = 0;
hspi->RxXferCount = 0;
/* Set the function for IT treatement */
if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
{
hspi->RxISR = NULL;
hspi->TxISR = SPI_TxISR_16BIT;
}
else
{
hspi->RxISR = NULL;
hspi->TxISR = SPI_TxISR_8BIT;
}
/* Configure communication direction : 1Line */
if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
{
__HAL_SPI_1LINE_TX(hspi);
}
/* Reset CRC Calculation */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)
{
__HAL_SPI_RESET_CRC(hspi);
}
/* Enable TXE and ERR interrupt */
__HAL_SPI_ENABLE_IT(hspi,(SPI_IT_TXE));
/* Process Unlocked */
__HAL_UNLOCK(hspi);
/* Note : The SPI must be enabled after unlocking current process
to avoid the risk of SPI interrupt handle execution before current
process unlock */
/* Check if the SPI is already enabled */
if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
{
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
esta es la configuración para GPIOA4:
/*Configure GPIO pin : PA4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);