• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
eectree
博客园    首页    新随笔    联系   管理    订阅  订阅

STM32F103 SPI连续接收数据

1、概述
使用STM32F103 SPI中断连续接收较多数据,出现数据丢失的问题,把问题与解决措施做下记录。
2、问题描述
使用单片机测试板STM32F103 SPI作为从机接收较多数据(16bit),主机设置如下:

从机STM32F103 SPI RXNE中断接收如下:

点击查看代码
uint16_t spi_recv_data[100];
__IO    uint16_t UART1_SendBuf_WriteIndex = 0; //写指针 
__IO    uint16_t UART1_SendBuf_ReadIndex = 0; //读指针 

void SPI1_IRQHandler(void)
{
	if (SPI_I2S_GetITStatus(SPI_1,SPI_I2S_IT_RXNE) == SET)//中断标志确认
	{  
		SPI_I2S_ClearITPendingBit(SPI_1,SPI_I2S_IT_RXNE);//清中断标志

		SPI_I2S_ITConfig(SPI_1, SPI_I2S_IT_RXNE, DISABLE);//关闭中断
		
		spi_recv_data[UART1_SendBuf_WriteIndex++] = SPI_I2S_ReceiveData(SPI_1);//读取数据并放入缓存
		
		if ( UART1_SendBuf_WriteIndex >= 100)
		{
			UART1_SendBuf_WriteIndex = 0;
		}

		SPI_I2S_ITConfig(SPI_1, SPI_I2S_IT_RXNE, ENABLE );//开启中断

	}
}
通过查看spi_recv_data[]的值或者串口打印,发现收到的数据为1122 5566,而3344 7788丢失。 3、解决措施 优化代码如下,问题解决。
点击查看代码
uint16_t spi_recv_data[100];
__IO    uint16_t UART1_SendBuf_WriteIndex = 0; //写指针 
__IO    uint16_t UART1_SendBuf_ReadIndex = 0; //读指针 

void SPI1_IRQHandler(void)
{
	//if (SPI_I2S_GetITStatus(SPI_1,SPI_I2S_IT_RXNE) == SET)//中断标志确认
	{  
		//SPI_I2S_ClearITPendingBit(SPI_1,SPI_I2S_IT_RXNE);//清中断标志

		//SPI_I2S_ITConfig(SPI_1, SPI_I2S_IT_RXNE, DISABLE);//关闭中断
		
		spi_recv_data[UART1_SendBuf_WriteIndex++] = SPI_I2S_ReceiveData(SPI_1);//读取数据并放入缓存
		
		if ( UART1_SendBuf_WriteIndex >= 100)
		{
			UART1_SendBuf_WriteIndex = 0;
		}

		//SPI_I2S_ITConfig(SPI_1, SPI_I2S_IT_RXNE, ENABLE );//开启中断

	}
}
4、分析 造成数据丢失的原因为:对中断接收理解不到位,多余的繁琐的代码块占用了CPU时间,没有及时读取接收缓存区的数据,导致新数据溢出。

中断标志确认函数SPI_I2S_GetITStatus(SPI_1,SPI_I2S_IT_RXNE) == SET内容较多、CPU时间较长,可用寄存器操作替换SPI1->SR & 0x01) == (uint16_t)SET.
清中断标志函数SPI_I2S_ClearITPendingBit(SPI_1,SPI_I2S_IT_RXNE)用在此处不当,该函数作用为Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
RXNE标志清除的方法见参考手册说明,读取接收缓冲区的数据也就清除了RXNE标志位。

关闭、开启中断函数用在此处,也是错误的。

posted @ 2024-08-14 15:00  第三家园  阅读(348)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3