模仿标准库函数,利用UART_IT_RXNE和UART_IT_IDLE两个标志,写了一个hal库串口接收的程序,只用到在中断写

2023-05-16

突然间发现,原来的标准库的程序,改成hal库,把hal库里的一些规则、形式掌握好,只需要做一些小的改动即可。
这里是串口2的接收中断的代码,用串口1实现这个功能,修改一下。

void USART2_IRQHandler(void)                	//串口2中断服务程序
{
	u8 Clear=Clear;
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断
	{ 
			USART2_RX_BUF[USART2_RX_STA&0X3FFF]=USART_ReceiveData(USART2);
      USART2_RX_STA++;
	}	
  else if(USART_GetITStatus(USART2,USART_IT_IDLE) !=RESET )
  {
							 Clear=USART2->SR;
							 Clear=USART2->DR; 
							//串口接收,继电器控制			
							//接收以30 开头
							if(USART2_RX_BUF[0] == 0x30)
							{
									Seial_PARAM_Rev();
							}
							 MQTT_USART2_LEN = USART2_RX_STA&0X3FFF;  //0011111111111111
							 memcpy(MQTT_USART2_RX_BUF,USART2_RX_BUF,MQTT_USART2_LEN);//复制串口数据到另外一个数组里面
							 Usart1_SendBuf(MQTT_USART2_RX_BUF,MQTT_USART2_LEN);//串口1 打印串口2接收的数据,直接插板子上得USB串口,xcom查看消息
							 UART2ReceiveState=1;
							 Clear_USART2_RXBUF();
	}
} 

利用UART_IT_RXNE和UART_IT_IDLE两个标志,就不用 HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);也不用回调函数了,直接在void USART1_IRQHandler(void) 改下清除UART_IT_RXNE和UART_IT_IDLE标志以及读取数据即可。

usart.c

#include "sys.h"
#include "usart.h"	

// 	  
 

//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 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)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 


//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART1_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	  
u8 Count=0;       //接收状态标记	  

u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲
UART_HandleTypeDef UART1_Handler; //UART句柄
 u16 MQTT_USART2_LEN=0; 
//初始化IO 串口1 
//bound:波特率
void uart_init(u32 bound)
{	
	//UART 初始化设置
	UART1_Handler.Instance=USART1;					    //USART1
	UART1_Handler.Init.BaudRate=bound;				    //波特率
	UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
	UART1_Handler.Init.StopBits=UART_STOPBITS_1;	    //一个停止位
	UART1_Handler.Init.Parity=UART_PARITY_NONE;		    //无奇偶校验位
	UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
	UART1_Handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式
	HAL_UART_Init(&UART1_Handler);					    //HAL_UART_Init()会使能UART1
	
__HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_IDLE);	
//	HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
	//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
  
}

//UART底层初始化,时钟使能,引脚配置,中断配置
//此函数会被HAL_UART_Init()调用
//huart:串口句柄

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
	GPIO_InitTypeDef GPIO_Initure;
	
	if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
	{
		__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
		__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟
		__HAL_RCC_AFIO_CLK_ENABLE();
	
		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9

		GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
		GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;	//模式要设置为复用输入模式!	
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10
		
//#if EN_USART1_RX
		HAL_NVIC_EnableIRQ(USART1_IRQn);				//使能USART1中断通道
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);			//抢占优先级3,子优先级3
//#endif	
	}
}

 
//串口1中断服务程序
void USART1_IRQHandler(void)                	
{ 
//	u8 Clear=Clear;   //清除空闲中断标志时,如果不用SR、DR寄存器,也可以不用定义这个//Clear
#if SYSTEM_SUPPORT_OS	 	//使用OS
	OSIntEnter();    
#endif
	
	HAL_UART_IRQHandler(&UART1_Handler);	//调用HAL库中断处理公用函数
	
	if(RESET != __HAL_UART_GET_FLAG(&UART1_Handler, UART_FLAG_RXNE))
{
	__HAL_UART_CLEAR_FLAG(&UART1_Handler,UART_FLAG_RXNE);

	USART1_RX_BUF[USART_RX_STA&0X3FFF]=UART1_Handler.Instance->DR;
	 USART_RX_STA++;
  	
}
	else if(RESET != __HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE)) //判断空闲中断标志
{
  __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);               //清除空闲中断标志
	/*注意:这里的清除空闲中断标志这一句代码,也可以用下边两句替代,
    首先要定义一个 	u8 Clear=Clear;
    //  __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);               //清除空闲中断标志
	 Clear=UART1_Handler.Instance->SR;
	 Clear=UART1_Handler.Instance->DR;
	
*/
	    if(USART1_RX_BUF[0]==0x55)    接收以0x55开头
     {
        for(int i=0;i<USART_RX_STA;i++){
        printf("USART1_RX_BUF[%d] = 0x%x\r\n",i,USART1_RX_BUF[i]); 
				}
	      MQTT_USART2_LEN = USART_RX_STA&0X3FFF;  //0011111111111111
        printf("MQTT_USART2_LEN = %d \r\n",MQTT_USART2_LEN); 
		     HAL_UART_Transmit(&UART1_Handler, (uint8_t*)USART1_RX_BUF,8,100); //接收完了,再发送出去
			   while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);          //等待发送结束


         memset(USART1_RX_BUF,0,sizeof(USART1_RX_BUF));  //清空缓存数组
        USART_RX_STA=0;  //清空接收长度
      }
		 
}

#if SYSTEM_SUPPORT_OS	 	//使用OS
	OSIntExit();  											 
#endif
} 


void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)

{


if(huart->Instance==USART1)

{
//	GPIO_InitTypeDef GPIO_Initure;

//DEBUG_USART_RCC_CLK_DISABLE();
		__HAL_RCC_USART1_CLK_DISABLE();			//使不能USART1时钟

/**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

		HAL_NVIC_DisableIRQ(USART1_IRQn);

}

else if(huart->Instance==USART2)

 {

		__HAL_RCC_USART2_CLK_DISABLE();			//使不能USART1时钟

    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);

		HAL_NVIC_DisableIRQ(USART2_IRQn);

 }

}

usart.h
#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "sys.h" 
//	 

#define USART_REC_LEN  			200  		//定义最大接收字节数 200
//#define EN_USART1_RX 			1			//使能(1)/禁止(0)串口1接收
	  	
extern u8  USART1_RX_BUF[USART_REC_LEN]; 	//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         			//接收状态标记	
extern UART_HandleTypeDef UART1_Handler; 	//UART句柄
extern u16 MQTT_USART2_LEN; 
#define RXBUFFERSIZE   1 					//缓存大小
extern u8 aRxBuffer[RXBUFFERSIZE];			//HAL库USART接收Buffer

//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
#endif

例如,发送55 AA 03 04 05 FD FF CC,接收到以后,再转发出来,做了测试如下图所示。
在这里插入图片描述
下载链接如下:https://download.csdn.net/download/petertang1975/86497481

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模仿标准库函数,利用UART_IT_RXNE和UART_IT_IDLE两个标志,写了一个hal库串口接收的程序,只用到在中断写 的相关文章

  • Winform datagridview中显示下拉框示例

    方式一 xff1a 如下图所示 xff0c 该方式也是较为简单的一种 你只需要添加一列类型为DataGridViewComboBoxColumn的列 xff0c 然后添加数据源即可 但是我们看到这种方式的下拉列表看起来并不是十分的美观 xf
  • subject may not be empty[Git]

    PS D MySource sino manager gt git commit husky gt pre commit node v10 15 3 STARTED Preparing SUCCESS Preparing STARTED R
  • [转]C# HTTP 错误 403.14 - Forbidden Web

    HTTP 错误 403 14 ForbiddenWeb 服务器被配置为不列出此目录的内容 出现以上这个错误可能有如下解决方法 xff1a 1 将应用程序池设置成V4 0 2 在配置文件中加上以下几句代码 xff1a lt system we
  • c# 创建Web Api项目

    创建WebApi项目 xff1a 在VS工具中创建一个ASP NET Web应用程序 选择Webapi 一个webapi项目就创建好了 这里简单的写一个post和get两种请求的方法 xff0c 由于post请求参数需要参数体的形式 xff
  • C# 反射获取类的成员变量名称及值

    测试用的类 public class PersonData public string gender 61 string Empty public List lt int gt pifuRGB 61 new List lt int gt 0
  • cstring转换为char*

    在Visual C 43 43 NET2005中 xff0c 默认的字符集形式是Unicode xff0c 但在VC6 0等工程中 xff0c 默认的字符集形式是多字节字符集 xff08 MBCS xff1a Multi Byte Char
  • Error creating bean with name 'userController'

    Caused by org springframework beans factory UnsatisfiedDependencyException Error creating bean with name 39 userControll
  • IntelliJ IDEA Cannot find declaration to go to

    最近在用IntelliJ IDEA开发一个微服务的项目的时候 xff0c 从git clone了代码 xff0c 再用IntelliJ IDEA导入项目以后 项目里好多方法 类和属性都无法转到定义或者声明处 xff0c 无论是Ctrl 43
  • CString转char * ,string

    CString头文件 include lt afx h gt string头文件 include lt string h gt 1 CString转char CString cstr char p 61 LPSTR LPCTSTR cstr
  • GPS数据包格式+数据解析

    GPS数据包格式 43 数据解析 一 全球时区的划分 xff1a 每个时区跨15 经度 以0 经线为界向东向西各划出7 5 经度 xff0c 作为0时区 即0时区的经度范围是7 5 W 7 5 E 从7 5 E与7 5 W分别向东 向西每1
  • 在C#中使用libcurl库

    几乎在所有的linux发行版中 xff0c 默认都是包含有libcurl库的 那么 xff0c libcurl是使用C开发的 xff0c 自然 xff0c 当你用C或C 43 43 使用libcurl库的时候很方便 但是 xff0c 如果你
  • Linux下chrony授时监测脚本

    1 背景概述 Linux下基于gpsd 43 chrony授时 xff0c 在有些情况下会存在收敛慢或者参考时间选择错误问题 xff0c 因此需要授时监测脚本进行监测 xff0c 便于在异常时候发现并处理 2 gpsd 43 chrony授
  • 关于linux下shell输出^M特殊字符的处理

    shell中echo输出时 M特殊字符的处理 今天在csdn论坛看一网友发了一个帖子 xff1a https bbs csdn net topics 392668752 post 403986636 xff0c 我很好奇 xff0c 于是将
  • VS2010(VS2017)+Boost_1_68_0环境搭建

    文 Seraph 一 下载 首先从Boost下载官网下载源码 xff0c 当然你也可以下载编译好的库文件直接用 我下载的是boost 1 68 0 zip 解压到某个目录下 xff0c 我解压到了D盘根目录 xff1a E boost 1
  • 2.gstreamer USB摄像头RTSP推流

    目录 1 操作系统版本 2 使用gstreamer播放mp4文件 3 采集USB摄像头视频源 xff0c 并RTSP推流 4 使用RTSP播放器播放 5 注意事项 1 操作系统版本 使用的虚拟机加ubuntu 20 04 2 使用gstre
  • 3.gstreamer UDP推流RTP及拉流播放

    目录 1 将H264数据流打包为RTP包 xff0c 然后UDP推流 2 UDP client拉流 xff0c 然后RTSP传输 3 easyplayer rtsp exe播放器播放RTSP数据流 将H264打包为RTP包 xff0c 然后
  • 靶机渗透练习80-Momentum:1

    靶机描述 靶机地址 xff1a https www vulnhub com entry momentum 1 685 Description Info easy medium 一 搭建靶机环境 攻击机Kali xff1a IP地址 xff1
  • 靶机渗透练习81-Momentum:2

    靶机描述 靶机地址 xff1a https www vulnhub com entry momentum 2 702 Description Difficulty mediumKeywords curl bash code review T
  • STM32F407单片机上开发MODBUS RTU 多主站程序(二)

    STM32F407单片机上开发MODBUS RTU 多主站程序 xff08 一 xff09 STM32F407单片机上开发MODBUS RTU 多主站程序 xff08 二 xff09 前面一篇文章 STM32F407单片机上开发MODBUS
  • 靶机渗透练习82-The Planets:Mercury

    靶机描述 靶机地址 xff1a https www vulnhub com entry the planets mercury 544 Description Difficulty Easy Mercury is an easier box

随机推荐