遵循此post之后,我设法为我的Nucleo板设置了两个SPI设备和工作中断,并以1ms的周期发送6字节有效负载。我的想法是将两个SPI模块一起触发,以使它们并行运行,但是有一些事情使我无法实现:
这是我的主要代码段:
volatile uint8_t t[6] = {0x50, 0x60, 0x70, 0x80, 0x90, 0x10};
volatile uint8_t r[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
volatile uint8_t transmit_count1 = 6, transmit_count2 = 6, transmit_count3 = 6;
volatile uint8_t transmit_index1 = 0, transmit_index2 = 0, transmit_index3 = 0;
void do_SPI_ISR(){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // SS1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // SS2
LL_SPI_Enable(SPI1);
LL_SPI_Enable(SPI2);
transmit_index1 = transmit_index2 = transmit_index3 = 0;
transmit_count1 = transmit_count2 = transmit_count3 = 6;
LL_SPI_EnableIT_TXE(SPI1); // enable SPI1 TX interrupt
LL_SPI_EnableIT_TXE(SPI2); // enable SPI2 TX interrupt
LL_SPI_TransmitData8(SPI1, t[transmit_index1]);
LL_SPI_TransmitData8(SPI2, t[transmit_index2]);
while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_RESET || HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET){
// SS are set HIGH by interrupts, remain here until that happens for both lines
}
}
void SPI1_ISR_callback(){
if (transmit_index1 < transmit_count1 - 1){
transmit_index1 ++;
LL_SPI_TransmitData8(SPI1, t[transmit_index1]);
} else {
LL_SPI_DisableIT_TXE(SPI1);
transmit_index1 = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
LL_SPI_Disable(SPI1);
}
}
void SPI2_ISR_callback(){
if (transmit_index2 < transmit_count2 - 1){
transmit_index2 ++;
LL_SPI_TransmitData8(SPI2, t[transmit_index2]);
} else {
LL_SPI_DisableIT_TXE(SPI2);
transmit_index2 = 0;
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
LL_SPI_Disable(SPI2);
}
}
我没有对中断优先级进行任何调整,两个SPI的优先级均为0/0。我以为两个中断都会依次触发并触发字节传输,但事实并非如此,也许某些中断事件不断在SPI1上触发,从而阻止SPI2触发他?我尝试删除所有错误并接收中断,但这并没有改变结果。
编辑,更多代码:
void SPI1_IRQHandler(void)
{
/* USER CODE BEGIN SPI1_IRQn 0 */
if (LL_SPI_IsActiveFlag_TXE(SPI1)){
SPI1_ISR_callback();
}
/* USER CODE END SPI1_IRQn 0 */
/* USER CODE BEGIN SPI1_IRQn 1 */
/* USER CODE END SPI1_IRQn 1 */
}
/**
* @brief This function handles SPI2 global interrupt.
*/
void SPI2_IRQHandler(void)
{
/* USER CODE BEGIN SPI2_IRQn 0 */
if (LL_SPI_IsActiveFlag_TXE(SPI2)){
SPI2_ISR_callback();
}
/* USER CODE END SPI2_IRQn 0 */
/* USER CODE BEGIN SPI2_IRQn 1 */
/* USER CODE END SPI2_IRQn 1 */
}
编辑2(25/05/2020),其中TXE标志由主应用程序管理,并且中断被禁用:
对应的代码:
void do_SPI_ISR(){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // SS1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // SS2
LL_SPI_Enable(SPI1);
LL_SPI_Enable(SPI2);
transmit_index1 = transmit_index2 = transmit_index3 = 0;
transmit_count1 = transmit_count2 = transmit_count3 = 6;
//LL_SPI_EnableIT_TXE(SPI1); // enable SPI1 TX interrupt
//LL_SPI_EnableIT_TXE(SPI2); // enable SPI2 TX interrupt
LL_SPI_TransmitData8(SPI1, t[transmit_index1]);
LL_SPI_TransmitData8(SPI2, t[transmit_index2]);
while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_RESET || HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET){
if (LL_SPI_IsActiveFlag_TXE(SPI1)){
SPI1_ISR_callback();
}
if (LL_SPI_IsActiveFlag_TXE(SPI2)){
SPI2_ISR_callback();
}
}
}
非常感谢任何帮助