【STM32通讯系列--串口通讯】使用标准库、HAL库实现任意长度数据的收发(包含帧头、帧尾校验,配套完整开源程序)

这篇具有很好参考价值的文章主要介绍了【STM32通讯系列--串口通讯】使用标准库、HAL库实现任意长度数据的收发(包含帧头、帧尾校验,配套完整开源程序)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、串口的基本概念

  • 【数据组成】串口的通讯协议由开始位,数据位,校验位,结束位构成。
  • 【数据结构】一般以一个低电平作为一帧数据的起始,接着跟随 8 位或者 9 位数据位,之后为校验位,分为奇校验,偶校验和无校验,最后以一个先高后低的脉冲表示结束位,长度可以设置为 0.5,1,1.5 或 2 位长度。
  • 【奇偶校验原理】统计发送数据中高电平即’1’的奇偶,将结果记录在奇偶校验位中发送给接收方,接收方收到奇偶校验位后和自己收到的数据进行对比,如果奇偶性一致就接受这帧数据,否则认为这帧数据出错。

如下图所示:一个 8 位数据位,1 位奇偶校验位,1 位结束位的串口数据帧。

stm32串口标准库,STM32开发实践,stm32,单片机,arm

上图的解释如下:

stm32串口标准库,STM32开发实践,stm32,单片机,arm
注意事项:

  1. 一般进行串口通讯时,收发双方要保证遵守同样的协议才能正确的完成收发,除了协议要一致之外,还有一个非常重要的要素要保持一致,那就是通讯的速率,即波特率。
  2. 波特率是指发送数据的速率,单位为波特每秒,一般串口常用的波特率有 115200,38400,9600 等。
  3. 串口的波特率和总线时钟周期(clock)成倒数关系,即总线时钟周期越短,单位时间内发送的码元数量越多,串口波特率就越高。

二、使用 STM32 标准库 实现任意长度数据的收发

示例程序功能说明:首先,通过串口一实现对任意长度数据的接收,接收到数据之后,将其存放到一个数组当中,方便后续调用;其次将STM32接收到的数据通过串口一发送出去。核心程序如下:(完整版程序详见文末链接)

// 串口发送部分核心代码如下:
int main(void)
{	
	delay_init();	    //延时函数初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200	
	
//	USART_SendData(USART1, 0x11);  
//	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);

	while(1)
	{
		if(receive_flag == 1) //串口接收完成标志位
		{
				for(int i=0;i<8;i++)
				{
					USART_SendData(USART1, Receive_Data[i]);//向串口1发送数据
					while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束				
				}	
				receive_flag = 0;  //一帧数据发送完毕之后,标志位置0		
		}
	}		
}
// 串口接收部分核心代码如下:
void USART1_IRQHandler(void)
{	
	static u8 Count=0;  //定义计数静态变量
	u8 Usart_Receive;   //定义中间传递变量

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断是否接收到数据
	{
			Usart_Receive = USART_ReceiveData(USART1); //读取数据
		
			if(receive_flag == 0)
			{
					//串口数据填入数组
					Receive_Data[Count]=Usart_Receive;
					
					//确保数组第一个数据为FRAME_HEADER(帧头)
					if(Usart_Receive == FRAME_HEADER||Count>0) 
						Count++; 
					else 
						Count=0;
					
					if (Count == 8) //验证数据包的长度
					{   
						Count=0; //为串口数据重新填入数组做准备
						
						if(Receive_Data[7] == FRAME_TAIL) //验证数据包的帧尾
						{
							//接收到完整的一帧数据之后,在这里面进行处理
							receive_flag = 1;												
						}
					}					
			}			
	}
}

程序关键:

  1. 通过微小调整,可以实现任意长度数据的收发,方便使用;
  2. 串口接收鲁棒性高,采用校验帧头、帧尾以及数据长度的方式,确保接收数据的稳定性。

STM32 标准库 串口收发实验展示(实验中,帧头设置为0x01,帧尾设置为0x02,数据长度为8个字节)

stm32串口标准库,STM32开发实践,stm32,单片机,arm

【实验结论】如上图所示,发送端的数据,接收端会完好收到。下面进行干扰性测试:

stm32串口标准库,STM32开发实践,stm32,单片机,arm

【实验结论】如上图所示,在引入帧头、帧尾以及长度校验后,程序的抗干扰能力较强。

三、使用 STM32 HAL库 实现任意长度数据的收发

HAL库程序使用CUBE MX生成

// 串口发送部分核心代码如下:
int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  //__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
  HAL_UART_Receive_IT(&huart1,(uint8_t *)Usart_Receive,1); //这句话极为重要
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(receive_flag == 1)
		{
			HAL_UART_Transmit(&huart1,Receive_Data,8,100);			
			receive_flag = 0;			
		}				
  }
  /* USER CODE END 3 */
}
// 串口接收部分核心代码如下:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	static uint8_t Count=0;  //定义计数静态变量
	
  if(huart->Instance==USART1)
  {
      HAL_UART_Receive_IT(&huart1,(uint8_t *)Usart_Receive,1);
		
			if(receive_flag == 0)
			{
					//串口数据填入数组
					Receive_Data[Count]=Usart_Receive[0];
					
					//确保数组第一个数据为FRAME_HEADER(帧头)
					if(Usart_Receive[0] == FRAME_HEADER||Count>0) 
						Count++; 
					else 
						Count=0;
					
					if (Count == 8) //验证数据包的长度
					{   
						Count=0; //为串口数据重新填入数组做准备
						
						if(Receive_Data[7] == FRAME_TAIL) //验证数据包的帧尾
						{
							//接收到完整的一帧数据之后,在这里面进行处理
							receive_flag = 1;												
						}
					}					
			}					
  }
}

STM32 HAL库 串口收发实验展示(实验中,帧头设置为0x01,帧尾设置为0x02,数据长度为8个字节)

stm32串口标准库,STM32开发实践,stm32,单片机,arm

四、相关程序及总结

1.上述代码已开源,开源链接:

https://e.coding.net/ehangtest01/stm32_explore/STM32_Explore.git

文件夹内容如下:
stm32串口标准库,STM32开发实践,stm32,单片机,arm
2.不管是使用标准库还是HAL库,都需要对数据进行校验,这样才能保证数据传输的稳定性。文章来源地址https://www.toymoban.com/news/detail-621339.html

到了这里,关于【STM32通讯系列--串口通讯】使用标准库、HAL库实现任意长度数据的收发(包含帧头、帧尾校验,配套完整开源程序)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包