stm32轮询接收字符串控制开关灯

即将放年假了,公司目前也没有什么事情是我可做的,便买了一块便宜的stm32板子重新系统学下单片机。目前学到了串口轮询接收字符串,例程是stm32板子自带的看门狗例程,可以把看门狗的实现函数和头文件注释掉,以免影响编译。

板子主控:stm32rct6,他们的库函数其实都差不多,适当修改下即可。主要实现代码如下:

while(1)
	{
		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1)			//USART_FLAG_RXNE判断数据,== 1则有数据
		{ for(i=0;i<5;i++){
			while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
			USART1_ReceiveData[i] = USART_ReceiveData(USART1);				//通过USART1串口接收字符
		  USART_ClearFlag(USART1,USART_FLAG_RXNE);					//接收后先清空标志位
		}
		}
		if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n')									//如果数据为1,LED1灯电平翻转
		{  
		
			printf("\r\n open light \r\n");
			LED0 =0;	
		}
		
  else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s'  && USART1_ReceiveData[4]=='e')									//如果数据为2,LED2灯电平翻转
		{ 
			printf("\r\n close light \r\n");
			LED0=1;
		}
		/*else{
		    
			printf("\r\n input error \r\n");		
		}
		*/
		//USART1_ReceiveData = 0;											//数据清零
	}

usart,h

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

//1,增加了对UCOSII的支持
#define USART_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收
	  	
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         		//接收状态标记	
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
void USART1_Init();
#endif


usart.c

#include "sys.h"
#include "usart.h"	  
// 	 
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h"					//ucos 使用	  
#endif
 

//加入以下代码,支持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;
}
#endif 

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

void USART1_Init()
{
	GPIO_InitTypeDef 	GPIOInit_Struct;
	USART_InitTypeDef 	USARTInit_Struct;
	
	//1、使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	//2、初始化对应的IO引脚复用为USART1功能
	//RCC_AHB1PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIOInit_Struct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIOInit_Struct.GPIO_Pin=GPIO_Pin_9;
	GPIOInit_Struct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIOInit_Struct);
	/* 将USART RX(A10)的GPIO设置为浮空输入模式 */
	GPIOInit_Struct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIOInit_Struct.GPIO_Pin=GPIO_Pin_10;
	GPIO_Init(GPIOA,&GPIOInit_Struct);
	
	
	//将PA9  PA10复用为USART1功能
	 //GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	//GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
	//3、USART1初始化
	USARTInit_Struct.USART_BaudRate 	= 115200; 								//波特率
	USARTInit_Struct.USART_Parity		= USART_Parity_No;						//无校验位
	USARTInit_Struct.USART_StopBits		= USART_StopBits_1;						//1位停止位
	USARTInit_Struct.USART_WordLength	= USART_WordLength_8b;					//8位数据位
	USARTInit_Struct.USART_Mode			= USART_Mode_Rx | USART_Mode_Tx;		//收发模式
	USARTInit_Struct.USART_HardwareFlowControl	= USART_HardwareFlowControl_None;//无硬件控制流
	USART_Init(USART1,&USARTInit_Struct);
	
	//4、开启串口
	USART_Cmd(USART1,ENABLE);
}
void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif	

void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
	int i = 0;
	USART_ClearFlag(USARTx,USART_FLAG_TC);										//发送字符前清空标志位(否则缺失字符串的第一个字符)
	while(DataString[i] != '\0')												//字符串结束符
	{
		USART_SendData(USARTx,DataString[i]);									//每次发送字符串的一个字符
		while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);					//等待数据发送成功
		USART_ClearFlag(USARTx,USART_FLAG_TC);									//发送字符后清空标志位
		i++;
	}
}

main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "wwdg.h"


 int main(void)
 {
	uint16_t i;
  char USART1_ReceiveData[6] = {0};		
	delay_init();	    
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	//uart_init(9600);
 	LED_Init(); 
	//LED0=0;
	//delay_ms(300);	  
//	WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);   
 
	 
	//LED_Init();															//LED灯初始化
	USART1_Init();		//串口初始化
	//USART_SendString(USART1, "Hello world!\r\n");						//发送字符串
	
									//接收PC端发送过来的字符
	USART_ClearFlag(USART1,USART_FLAG_RXNE);							//接收前先清空标志位
	while(1)
	{
		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1)			//USART_FLAG_RXNE判断数据,== 1则有数据
		{ for(i=0;i<5;i++){
			while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
			USART1_ReceiveData[i] = USART_ReceiveData(USART1);				//通过USART1串口接收字符
		  USART_ClearFlag(USART1,USART_FLAG_RXNE);					//接收后先清空标志位
		}
		}
		
		if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n')									//如果数据为1,LED1灯电平翻转
		{  
		
			printf("\r\n open light \r\n");
			LED0 =0;	
		}
		
  else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s'  && USART1_ReceiveData[4]=='e')									//如果数据为2,LED2灯电平翻转
		{ 
			printf("\r\n close light \r\n");
			LED0=1;
			
		}
		
		/*else{
		    
			printf("\r\n input error \r\n");		
		}
		*/
		//USART1_ReceiveData = 0;											//数据清零
	}
 }



版权声明:本文为CSDN博主「朝朝暮暮柳十岁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42952472/article/details/122697617

即将放年假了,公司目前也没有什么事情是我可做的,便买了一块便宜的stm32板子重新系统学下单片机。目前学到了串口轮询接收字符串,例程是stm32板子自带的看门狗例程,可以把看门狗的实现函数和头文件注释掉,以免影响编译。

板子主控:stm32rct6,他们的库函数其实都差不多,适当修改下即可。主要实现代码如下:

while(1)
	{
		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1)			//USART_FLAG_RXNE判断数据,== 1则有数据
		{ for(i=0;i<5;i++){
			while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
			USART1_ReceiveData[i] = USART_ReceiveData(USART1);				//通过USART1串口接收字符
		  USART_ClearFlag(USART1,USART_FLAG_RXNE);					//接收后先清空标志位
		}
		}
		if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n')									//如果数据为1,LED1灯电平翻转
		{  
		
			printf("\r\n open light \r\n");
			LED0 =0;	
		}
		
  else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s'  && USART1_ReceiveData[4]=='e')									//如果数据为2,LED2灯电平翻转
		{ 
			printf("\r\n close light \r\n");
			LED0=1;
		}
		/*else{
		    
			printf("\r\n input error \r\n");		
		}
		*/
		//USART1_ReceiveData = 0;											//数据清零
	}

usart,h

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

//1,增加了对UCOSII的支持
#define USART_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收
	  	
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         		//接收状态标记	
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
void USART1_Init();
#endif


usart.c

#include "sys.h"
#include "usart.h"	  
// 	 
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h"					//ucos 使用	  
#endif
 

//加入以下代码,支持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;
}
#endif 

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

void USART1_Init()
{
	GPIO_InitTypeDef 	GPIOInit_Struct;
	USART_InitTypeDef 	USARTInit_Struct;
	
	//1、使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	//2、初始化对应的IO引脚复用为USART1功能
	//RCC_AHB1PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIOInit_Struct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIOInit_Struct.GPIO_Pin=GPIO_Pin_9;
	GPIOInit_Struct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIOInit_Struct);
	/* 将USART RX(A10)的GPIO设置为浮空输入模式 */
	GPIOInit_Struct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIOInit_Struct.GPIO_Pin=GPIO_Pin_10;
	GPIO_Init(GPIOA,&GPIOInit_Struct);
	
	
	//将PA9  PA10复用为USART1功能
	 //GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	//GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
	//3、USART1初始化
	USARTInit_Struct.USART_BaudRate 	= 115200; 								//波特率
	USARTInit_Struct.USART_Parity		= USART_Parity_No;						//无校验位
	USARTInit_Struct.USART_StopBits		= USART_StopBits_1;						//1位停止位
	USARTInit_Struct.USART_WordLength	= USART_WordLength_8b;					//8位数据位
	USARTInit_Struct.USART_Mode			= USART_Mode_Rx | USART_Mode_Tx;		//收发模式
	USARTInit_Struct.USART_HardwareFlowControl	= USART_HardwareFlowControl_None;//无硬件控制流
	USART_Init(USART1,&USARTInit_Struct);
	
	//4、开启串口
	USART_Cmd(USART1,ENABLE);
}
void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif	

void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
	int i = 0;
	USART_ClearFlag(USARTx,USART_FLAG_TC);										//发送字符前清空标志位(否则缺失字符串的第一个字符)
	while(DataString[i] != '\0')												//字符串结束符
	{
		USART_SendData(USARTx,DataString[i]);									//每次发送字符串的一个字符
		while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);					//等待数据发送成功
		USART_ClearFlag(USARTx,USART_FLAG_TC);									//发送字符后清空标志位
		i++;
	}
}

main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "wwdg.h"


 int main(void)
 {
	uint16_t i;
  char USART1_ReceiveData[6] = {0};		
	delay_init();	    
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	//uart_init(9600);
 	LED_Init(); 
	//LED0=0;
	//delay_ms(300);	  
//	WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);   
 
	 
	//LED_Init();															//LED灯初始化
	USART1_Init();		//串口初始化
	//USART_SendString(USART1, "Hello world!\r\n");						//发送字符串
	
									//接收PC端发送过来的字符
	USART_ClearFlag(USART1,USART_FLAG_RXNE);							//接收前先清空标志位
	while(1)
	{
		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 1)			//USART_FLAG_RXNE判断数据,== 1则有数据
		{ for(i=0;i<5;i++){
			while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == 0);
			USART1_ReceiveData[i] = USART_ReceiveData(USART1);				//通过USART1串口接收字符
		  USART_ClearFlag(USART1,USART_FLAG_RXNE);					//接收后先清空标志位
		}
		}
		
		if( USART1_ReceiveData[0]=='o' && USART1_ReceiveData[1]=='p' && USART1_ReceiveData[2]=='e' && USART1_ReceiveData[3]=='n')									//如果数据为1,LED1灯电平翻转
		{  
		
			printf("\r\n open light \r\n");
			LED0 =0;	
		}
		
  else if( 'c' == USART1_ReceiveData[0] && USART1_ReceiveData[1]=='l' && USART1_ReceiveData[2]=='o' && USART1_ReceiveData[3]=='s'  && USART1_ReceiveData[4]=='e')									//如果数据为2,LED2灯电平翻转
		{ 
			printf("\r\n close light \r\n");
			LED0=1;
			
		}
		
		/*else{
		    
			printf("\r\n input error \r\n");		
		}
		*/
		//USART1_ReceiveData = 0;											//数据清零
	}
 }



版权声明:本文为CSDN博主「朝朝暮暮柳十岁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42952472/article/details/122697617

生成海报
点赞 0

朝朝暮暮柳十岁

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32F103(十八)ADC总结(贼详细)

学习板:STM32F103ZET6 往期博客: STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结 STM32F103五分钟入门系列(二)GPIO的七大寄存器+GPIOx_LCKR作用和配置 STM3

STM32的SysTick定时器记录一篇

CSDN博客主页 ID : Eterlove 一笔一画,记录我的学习生活!站在巨人的肩上Standing on Shoulders of Giants! 该文章为原创,转载请注明出处和作者&#xff01

STM32基于HAL库的DS18B20实现

开发板:野火挑战者_V2 GPIO:PE2 创建工程 使能USART1 用来通过串口打印温度值 配置GPIO 代码编写 我们先打开 DS18B20 的手册 1、DS18B20 复位与存在脉冲 复位 /*