当前位置: 首页 > news >正文

32f4,串口1,usart.c.h2025

usart.c

#include "sys.h"
#include "usart.h"	
#include "led.h"	
//
#include "stdlib.h"
#include "stdarg.h"
#include "stdio.h"
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
			#pragma import(__use_no_semihosting)             
			//标准库需要的支持函数                 
			struct __FILE 
			{ 
				int handle; 
			}; 

			FILE __stdout;       
			//定义_sys_exit()以避免使用半主机模式    
			_sys_exit(int x) 
			{ 
				x = x; 
			} 
			//重定义fputc函数 
			int fputc(int ch, FILE *f)
			{ 	
				while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
				USART1->DR = (u8) ch;      
				return ch;
			}
			

		//	printf("HEllo")  printf("i=%d\r\n",i) ;
#endif

 			
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
char USART1_RX_BUF[USART1_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	
u16 USART1_Rec_Byte_Length=0;//接收长度,最大是200,在接收数组空间范围内?
u8  USART1_Rec_Frame_Flag=0;//接收完整一帧标记
			
//初始化IO 串口1 
//bound:波特率
void uart1_init(u32 baudRate)
{
   //GPIO端口设置
  GPIO_InitTypeDef    GPIO_InitStructure;
	USART_InitTypeDef   USART_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟DISABLE
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
 
	//串口1对应引脚复用映射
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
	
	//USART1端口配置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10

   //USART1 初始化设置
	USART_InitStructure.USART_BaudRate = baudRate;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  USART_Init(USART1, &USART_InitStructure); //初始化串口1
	
  USART_Cmd(USART1, ENABLE);  //使能串口1 
	
	USART_ClearFlag(USART1, USART_FLAG_TC);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断,接收一个字节,就发生中断
}

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
	
	//接收中断(接收到的数据必须是0x0a结尾)
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
		
		USART1_RX_BUF[USART1_Rec_Byte_Length]=Res;//将数据放到缓冲区中
		if(USART1_RX_BUF[USART1_Rec_Byte_Length]==DIY_END_CODE) //如果接收到的最后的数据是约定好的帧尾
		{
			if(USART1_RX_BUF[USART1_Rec_Byte_Length-1]==DIY_END_CODE_Before)
			{
			  USART1_Rec_Frame_Flag=1;//接收标记等于1,在哪里清0?在判断里面清0
			}
			//USART1_Rec_Byte_Length=0;//长度清零,给下次使用
		}
		else
		{
			USART1_Rec_Byte_Length++;//递增座位号,不断放到数组中
			if(USART1_Rec_Byte_Length>USART1_REC_LEN-1) USART1_Rec_Byte_Length=0;
			
		}
			
  } 

} 
void Clear_Uart1_RecBuf(void)//清空接收缓冲区
{
  char *p;
	u8 i;
	p=USART1_RX_BUF;
	for(i=0;i<USART1_REC_LEN;i++)
	{
		*p++=0;
	}
	USART1_Rec_Byte_Length=0;
	USART1_Rec_Frame_Flag=0;
}

//#include "stdlib.h"
//#include "stdarg.h"
//#include "stdio.h"  
//#include "string.h"  //str函数
//带不定长度参数的函数
u8 Judge_Usart1_Response(char* fmt,...)
{
	char p[30];
	va_list ap;
	//如果串口1没接收到一帧数据,那么返回0,结束本函数
	if(!USART1_Rec_Frame_Flag) return 0;
  //如果接收到一帧数据,到下面将需要判断的数据数据复制到p数组中
	va_start(ap,fmt);
	vsprintf((char*)p,fmt,ap);
	va_end(ap); //结束ap指针,必须结束
	//用strstr函数,将接收到的字符串和我们的数据进行对比,如果没有相等的那么返回0并结束函数,否则返回1说明判断有效
	if(strstr((char*)USART1_RX_BUF,p)==NULL) return 0;
	else return 1;
}


//获取指定格式字符串的部分数据
//x=12,y=12.5  \r\n
u8 Get_Usart1_Data(int *x,float *y)
{
	int xtemp;
	float ytemp;
	
	if(!USART1_Rec_Frame_Flag) return 0;
	//第一个字符,第二个字符。
	else if(USART1_RX_BUF[0]=='x' && USART1_RX_BUF[1]=='=')
	{
		sscanf((const char *)USART1_RX_BUF,"x=%d,y=%f",&xtemp,&ytemp);
		*x=(int)xtemp;
		*y=(float)ytemp;
		return 1;
	}
	else return 0;	
}
//https://www.cnblogs.com/zhanxiaohong0303/p/zz_2020_10_1.html


















//*******************************
//int main(void)
//{ 
// 
//	u8 t;
//	u8 len;	
//	u16 times=0;  
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
//	delay_init(168);		//延时初始化 
//	uart_init(115200);	//串口初始化波特率为115200
//	LED_Init();		  		//初始化与LED连接的硬件接口  
//	while(1)
//	{
//		if(USART_RX_STA&0x8000)
//		{					   
//			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
//			printf("\r\n您发送的消息为:\r\n");
//			for(t=0;t<len;t++)
//			{
//				USART_SendData(USART1, USART_RX_BUF[t]);         //向串口1发送数据
//				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
//			}
//			printf("\r\n\r\n");//插入换行
//			USART_RX_STA=0;
//		}else
//		{
//			times++;
//			if(times%5000==0)
//			{
//				printf("\r\nALIENTEK 探索者STM32F407开发板 串口实验\r\n");
//				printf("正点原子@ALIENTEK\r\n\r\n\r\n");
//			}
//			if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
//			if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
//			delay_ms(10);   
//		}
//	}
//}


 
//void Clear_Openmv_Rxbuff(void)
//{
//	u8 *p,i;
//	p=openmv_rx_data;
//	for(i=0;i<Rx_Length;i++)
//	{
//		*p++=0;
//	}
//	length=0;
//	rx_flag=0;
//}

//u8 Judge_Openmv_Response(char* fmt,...)
//{
//	char p[30];
//	if(!rx_flag) return 0;
//	va_list ap;
//	va_start(ap,fmt);
//	vsprintf((char*)p,fmt,ap);
//	va_end(ap); 
//	if(strstr((char*)openmv_rx_data,p)==NULL) return 0;
//	else return 1;
//}

//		if(Judge_Openmv_Response("OK"))
//		{
//			Clear_Openmv_Rxbuff();
//			LCD_ShowString(0,16,"OK");
//		}


usart.h

#ifndef __USART_H
#define __USART_H

#include "stdio.h"	
#include "stm32f4xx_conf.h"
#include "sys.h" 

//********************************************************************************
#define USART1_REC_LEN  			   256  	     //定义最大接收字节数 200
#define DIY_END_CODE_Before      0x0D  //每次发送的帧尾\n
#define DIY_END_CODE             0x0A  //每次发送的帧尾\n


extern char  USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16   USART1_RX_STA;         		//接收状态标记	

extern  u16    USART1_Rec_Byte_Length;//接收长度,最大是200,在接收数组空间范围内?
extern  u8     USART1_Rec_Frame_Flag;//接收完整一帧标记=0,没接收完,=1接收完

void uart1_init(u32 baudRate);//设置串口1的波特率,以及初始化
void Clear_Uart1_RecBuf(void);//清空接收缓冲区
u8 Judge_Usart1_Response(char* fmt,...);//判断串口1接受到的字符串,比对
//if(Judge_Usart1_Response("OK"))只要存在OK连续两个就行,分大小写
//uyyOKoo
//https://www.cnblogs.com/zhanxiaohong0303/p/zz_2020_10_1.html
//将按照指定格式接收的数据赋值
u8 Get_Usart1_Data(int *x,float *y);


u8 Get_Usart1_Data2(float *x,float *y);


#endif



http://www.dtcms.com/a/109129.html

相关文章:

  • EIP-712:类型化结构化数据的哈希与签名
  • 【行测】判断推理:图形推理
  • System.arraycopy()
  • SD 重温学习笔记
  • 深入理解 Python 中的 `server.listen(backlog)`:监听队列的奥秘
  • 《深度探秘:SQL助力经典Apriori算法实现》
  • GO语言学习(17)Gorm的数据库操作
  • 两点与圆(异或神通)
  • 快速求平方根
  • 【每日一个知识点】分布式数据湖与实时计算
  • Ubuntu上离线安装ELK(Elasticsearch、Logstash、Kibana)
  • Vulkan实例教程1 - Vulkan应用程序结构(附代码)
  • node ---- 解决错误【Error: error:0308010C:digital envelope routines::unsupported】
  • 第一部分 领域驱动设计的原则与实践
  • 10.多线程
  • 【C++】第八节—string类(上)——详解+代码示例
  • P4305 [JLOI2011] 不重复数字
  • 系统与网络安全------Windows系统安全(8)
  • 纯c++实现transformer 训练+推理
  • AI+自动化测试:如何让测试编写效率提升10倍?
  • torch 拆分子张量 分割张量
  • idea运行tomcat项目,很慢的问题
  • 我想尝试做一个钢铁侠反应堆
  • 人工智能与大模型的关系
  • Java学习总结-io流-练习案例
  • 4.3学习总结
  • umi框架开发移动端h5
  • 【MySQL】理解MySQL的双重缓冲机制:Buffer Pool与Redo Log的协同之道
  • C++数据类型(整型、浮点型、字符型、布尔型)
  • 办公设备管理系统(springboot+ssm+jsp+maven)