• STM32串口重定向/实现不定长数据接收


    STM32串口重定向/实现不定长数据接收

    这是一期STM32内容代码分享,关于STM32重定向的代码和一些出现的问题吗,以及串口接收不定长数据思路

    重定向

    在这里插入图片描述

    • 重定向的功能:能够在STM32中使用printf函数通过串口发送数据

    具体代码如下:

     #if 0      //这种方式需要勾选 Use MicroLIB选项,可以使用不同的串口重定向
     #ifdef __GNUC__
         #define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
     #else
         #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
     #endif /* __GNUC__*/
     
     /******************************************************************
         *@brief  Retargets the C library printf  function to the USART.
         *@param  None
         *@retval None
     ******************************************************************/
     PUTCHAR_PROTOTYPE
     {
         HAL_UART_Transmit(&huart1, (uint8_t *)&ch,1,0xFFFF);
         return ch;
     }
    #endif
     #if 1        //这种方式不需要勾选 Use MicroLIB选项,但是只能选择串口1重定向
     
    #pragma import(__use_no_semihosting)             
    //标准库需要的支持函数                 
    struct __FILE 
    { 
    	int handle; 
    }; 
    
    FILE __stdout;       
    //定义_sys_exit()以避免使用半主机模式    
    void _sys_exit(int x) 
    { 
    	x = x; 
    } 
    //重定义fputc函数 
    int fputc(int ch, FILE *f)
    { 	
    //    HAL_UART_Transmit_IT();
    	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    	USART1->DR = (uint8_t) ch;      
    	return ch;
    }
    
    #endif 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    这一段代码是添加在usart.c文件里面的,一共有两段,同事还需要在usart.h文件里面包含“stdio.h”文件

    • 第一段需要勾选MIcroLIB选项,可以使用不同的串口重定向
    • 第二段则不需要勾选MicroLIB选项,只能使用串口1重定向

    MicroLIB

    在这里插入图片描述
    在这里插入图片描述

    MicroLIB选项

    不定长数据接收

    • 通过判断是否接收到\r\n来判断接收是否完成,同时需要发送的数据都是以\r\n结尾。

    具体代码如下:

    usart.c

    
    uint8_t USART_RX_BUF[USART_RX_BUF_SIZE];    //串口数据缓冲区,大小可自由改变
      uint8_t aRxBuffer[1];                     //存放串口每次中断产生的数据
    uint16_t USART_RX_STA;                      //串口状态位,包含接收是否完成,累积接受数据长度等信息
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    	if(huart->Instance==USART1)//如果是串口1
    	{
    		if((USART_RX_STA&0x8000)==0)//接收未完成
    		{
    			if(USART_RX_STA&0x4000)//接收到了0x0d
    			{
    				if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    				else USART_RX_STA|=0x8000;	//接收完成了 
    			}
    			else //还没收到0X0D
    			{	
    				if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
    				else
    				{
    					USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;     //将接收的数据传入串口数据缓存区
    					USART_RX_STA++;
    					if(USART_RX_STA>(USART_RX_BUF_SIZE-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
    				}		 
    			}
    		}
    
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    这样,只需要在printf函数使用的的地方,包含usart.h文件即可

    usart.h

    #include 
    
    #define  USART_RX_BUF_SIZE 100
    extern uint8_t USART_RX_BUF[USART_RX_BUF_SIZE];
    extern uint8_t aRxBuffer[1];
    extern uint16_t USART_RX_STA;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 以上就是不定长数据接收的代码,需要注意一个点:
    • 在main函数初始化完成之后和USART1_IRQHandler函数中需要重新开启串口接收中断
    • 就像这样:
      在这里插入图片描述
      在这里插入图片描述
  • 相关阅读:
    TTS引用与选型
    矿山运营攻略:提高生产效率,这点至关重要
    企业网盘中支持在线编辑的有哪些选项?
    ideaSSM 校园兼职招聘平台bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目
    软件测试之Web项目实战解析
    Linux之虚拟主机功能
    【Codeforces Round #835 (Div. 4)】A——G题解
    tar.xz 文件的压缩和生成
    【无标题】
    【云原生 | Kubernetes 系列】--Gitops持续交付 Argo Rollouts Analysis
  • 原文地址:https://blog.csdn.net/weixin_67907028/article/details/134490794