2020-11-11 12:18 AM
help me please. working in stm32cubeide. I can not enable interrupt on receiving bytes via SPI via HAL
main.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
/* USER CODE BEGIN PV */
uint8_t txb[1] = {0};
uint8_t rxb[1] = {0};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_NVIC_Init(void);
/* USER CODE BEGIN PFP */
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* Infinite loop */
while (1)
{
asm("nop");
txb[0] = rxb[0] + 1;
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_NVIC_Init(void)
{
/* SPI1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
}
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, LD4_Pin|LD3_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LD4_Pin LD3_Pin */
GPIO_InitStruct.Pin = LD4_Pin|LD3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
void Error_Handler(void)
{
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */
stm32f0xx_it.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_it.h"
extern SPI_HandleTypeDef hspi1;
void SPI1_IRQHandler(void)
{
/* USER CODE BEGIN SPI1_IRQn 0 */
/* USER CODE END SPI1_IRQn 0 */
HAL_SPI_IRQHandler(&hspi1);
/* USER CODE BEGIN SPI1_IRQn 1 */
/* USER CODE END SPI1_IRQn 1 */
}
2020-11-11 06:19 AM
You'll need to start the transmission somewhere:
HAL_SPI_TransmitReceive_IT(&hspi1, txb, rxb, 1);
And then start it again after all (1) bytes are completed.
2020-11-11 05:35 PM
I think this is the wrong approach. An interrupt for this was done so that everything worked in hardware. My infinite loop should be empty. This is a slave, he expects signals from the master. If it is impossible to implement it otherwise, although I found information, but there they set up the controller directly through the registers.
I suppose normal interrupts were simply not delivered to HAL. On stm8 with the SPL library, not everything is smooth either, but I was able to cope, here I made interrupts for the UART and achieved the desired result
2020-11-11 05:45 PM
With an interrupt, it should work like this:
my program runs in an infinite loop, let it be:
while (1)
{
asm("nop");
txb = rxb;
asm("nop");
}
and when the master starts the exchange with the slave, the program should get into the interrupt code:
void SPI1_IRQHandler(void)
{
HAL_SPI_IRQHandler(&hspi1);
}
и уже зде�?ь �? должен вызывать �?ту функцию: HAL_SPI_TransmitReceive_IT(&hspi1, txb, rxb, 1);
but the program does not get into the interrupt code, no matter how hard the master tries to reach the slave. I suspect that you need to enable the receive interrupt, and most likely the environment does not support this, or it just needs to be done with cunning gestures
2020-11-11 05:51 PM
Yes, but you need to actually start reception prior to the main loop, otherwise the interrupt is not enabled and will never be called. HAL_SPI_Init doesn't start anything. There are other ways to do it, but if you want to do HAL with interrupts, that's the way.
2020-11-11 06:05 PM
Okay I will try. I will write what happens
2020-11-11 09:31 PM
I declare boldly that interrupts on HAL will not work as they should!!!
2020-11-15 03:28 AM
Yes, the HAL receive API is broken by design. It stops the reception all the time and you have to restart it... for a single byte. You cannot just enable the reception and then wait for new data of arbitrary amounts. The HAL team is just incapable of understanding and designing asynchronous software...