STM32串口中断

目录

一、串口中断配置

1、USART1配置

2、USART3配置

(1)串口3引脚配置

(2)串口3中断配置

二、中断程序处理

1、使用字符控制Led灯

2、使用字符串控制Led灯

3、使用字符串位控制Led灯

[(1)Arduino Mega单片机程序](#(1)Arduino Mega单片机程序)

(2)串口1中断位处理程序

(3)串口3中断位处理程序

三、测试

1、起始符和结束符说明

2、串口1中断测试

3、串口3中断测试

四、程序打包下载链接


一、串口中断配置

1、USART1配置

代码

复制代码
void USART1_Init(u32 baudrate)
{
	GPIO_InitTypeDef GPIO_InitStructure;									//定义TX、RX引脚结构体变量
	USART_InitTypeDef USART_InitStructure;								//定义串口结构体
	NVIC_InitTypeDef NVIC_InitStructure;									//设置串口中断优先级
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;  						//TX,选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;	 			//复用推挽输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  	//设置传输速率
	GPIO_Init(GPIOA,&GPIO_InitStructure); 	   					/* 初始化GPIO */
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;  							//RX,选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;	 		//输入空模式
	//GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  		//接收的不需要
	GPIO_Init(GPIOA,&GPIO_InitStructure); 	   							/* 初始化GPIO */
	
	USART_InitStructure.USART_BaudRate=baudrate;									//设置波特率
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;			//数据位长度,8Bit
	USART_InitStructure.USART_StopBits=USART_StopBits_1;					//停止位: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);			//串口使能
	
	USART_ClearFlag(USART1,USART_FLAG_TC);						//清除发送完成状态标志
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);			//设置串口中断类型为接收中断,并使能
	
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;							//USART1中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;			//
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;						//
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;							//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);															//根据指定的参数初始化VIC寄存器
	
}

2、USART3配置

(1)串口3引脚配置

复制代码
void USART3_Config(void)
{

	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;	//定义串口初始化结构体
	
	/* config USART3 clock */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE);
		/* config GPIO clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB	, ENABLE);
	/* USART3 GPIO config */
	/* Configure USART3 Tx (PB.10) as alternate function push-pull 推拉输出模式*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);    
	/* Configure USART3 Rx (PB.11) as input floating 浮点输入模式*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
  	
	
	NVIC_Configurationusart3(); 
	/* USART3 mode config */
	//USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_BaudRate = 9600;//波特率9600
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//1个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No ;//无校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//禁用RTSCTS硬件流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//使能发送接收
  

	USART_Init(USART3, &USART_InitStructure); 
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//使能接收中断
	
	USART_Cmd(USART3, ENABLE);
	
}

(2)串口3中断配置

复制代码
void NVIC_Configurationusart3(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
	
	/* Enable the USARTy Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;	 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

二、中断程序处理

1、使用字符控制Led灯

使用串口1中断

复制代码
void USART1_IRQHandler(void)
{
	u8 r;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)				//RESET==0。产生接收中断事件
	{
		//sbuff[len++]=USART_ReceiveData(USART1);		//接收发来的字符串
		r=USART_ReceiveData(USART1);		//接收发来的字符
		
		if(r=='a')
		{
			led3=0;		//led3 点亮
		}
		else
		{
			led3=1;		//led3关闭
		}
		
		
		USART_SendData(USART1,r);				//发送字符
		while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);				//发送完成状态标志。SET==1
	}	
	USART_ClearFlag(USART1,USART_FLAG_TC);						//清除发送完成状态标志
	
	
	
	
}

2、使用字符串控制Led灯

使用串口1中断

复制代码
u16 n=0;

u8 i=0;
u8 sp=0;
u8 USART_REC_Finish_FLAG=0;
char SendData[20],Rec_Buffer[20];
char LED3ON[]="led3_on\r";			//串口调试助手发送的时候会加"\r\n",有的串口没有的,需要手动打回车符
char LED3OFF[]="led3_off\r";

void USART1_IRQHandler(void)
{
	if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET) 
    {
			if(USART_ReceiveData(USART1)=='\n')	 //串口调试助手必须加上换行符
			{ 
				sp=0;
				USART_REC_Finish_FLAG = 1;
				for(i=0;i<20;i++)           //i 字符串长度
				{
					Rec_Buffer[i]='\0';
				}					
			}
			else
			{
				if(sp==0)
				{
					for(i=0;i<20;i++)
					{
						SendData[i]='\0';
					}								
				}	
					Rec_Buffer[sp] = USART_ReceiveData(USART1);
					SendData[sp]= Rec_Buffer[sp];
					sp=sp+1;
				
					n=sp;
					
			}
		}
		
		if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
    { 
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);	//清除接收中断标志
				
    }
		
		while(USART_REC_Finish_FLAG == 1)						//等待串口接收完成标志位置1
		{	
			printf("当前发送的字符sp个数:%d\r\n",n);
			delay_us(1000);			//延时1ms
			
			USART_REC_Finish_FLAG = 0;								//使用完成后将串口标志位置0				
			
			//led3 ON
			if(strcmp(SendData, LED3ON)==0)						//比较字符串,相等则返回0
			{
				led3=0;
				printf("LED3 ON\r\n");
			}	
			//led3 OFF			
			if(strcmp(SendData, LED3OFF)==0)
			{
				led3=1;
				printf("LED3 OFF\r\n");
			}							
			printf("SendData:%s \r\n",SendData);
			
			
			
		}

}

3、使用字符串位控制Led灯

串口1中断:串口1连接串口调试助手

串口3中断:串口3和Arduino Mega单片机串口1连接,使用串口调试助手和Arduino Mega单片机连接,Arduino Mega单片机将串口调试助手发送的字符串通过串口1再转发送给STM32串口3

(1)Arduino Mega单片机程序

复制代码
String inputString = "";          //保存串口接收的字符串
bool stringComplete = false;      //串口接收完成标志位
 
void setup() 
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
  inputString.reserve(200);
}
 
void loop() 
{
  if (stringComplete) 
  {
    //Serial.print(inputString);  //串口0发送出去  
    Serial1.print(inputString);  //串口1发送出去
    Serial2.print(inputString);  //串口2发送出去
    //清空接收字符串
    inputString = "";
    stringComplete = false;
  }
}
 
//串口0中断事件
void serialEvent() 
{
  while (Serial.available()) 
  {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '#')        //结束符
    {
      stringComplete = true;
    }
    
  }  
}
 
//串口1中断事件
void serialEvent1()
{
  while (Serial1.available()) 
  {
    char inChar = (char)Serial1.read();
    inputString += inChar;
    if (inChar == '#')        //结束符
    {
      stringComplete = true;
    }
    
  }  
}

(2)串口1中断位处理程序

复制代码
void USART1_IRQHandler(void)
{  
		u8 uartvalue = 0;
		if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)						//注意!不能使用if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)来判断  
		{  
				USART_ClearFlag(USART1, USART_FLAG_ORE); 												//读SR其实就是清除标志
				USART_ReceiveData(USART1);  		
		}		
		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!=RESET)
		{
				USART_ClearITPendingBit(USART1, USART_IT_RXNE);
				uartvalue = USART1->DR;
				if(uartvalue == '$')
				{
						startBit = 1;
						num = 0;
				}
				if(startBit == 1)
				{
						inputString[num] = uartvalue;     
				}  
				if(startBit == 1 && uartvalue == '#') 
				{	    	
						newCmdReceivedFlag = 1; 
						startBit = 0;
						int9num = num;			
				}
				num++;
				if(num >= 80)
				{
						num = 0;
						startBit = 0;
						newCmdReceivedFlag	= 0;				
				}	 		
		} 
}	

(3)串口3中断位处理程序

复制代码
/***************************************************************
* 函数名		:USART3_IRQHandler
* 蓝牙-串口3,中断函数
*
* 如 前进:$1,0,0,0,0,0,0,0,0,0#
***************************************************************/
int num = 0;
u8 startBit = 0;
int int9num =0;
void USART3_IRQHandler(void)
{  
		u8 uartvalue = 0;
		if(USART_GetFlagStatus(USART3, USART_FLAG_ORE) != RESET)						//注意!不能使用if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)来判断  
		{  
				USART_ClearFlag(USART3, USART_FLAG_ORE); 												//读SR其实就是清除标志
				USART_ReceiveData(USART3);  		
		}		
		if(USART_GetFlagStatus(USART3,USART_FLAG_RXNE)!=RESET)
		{
				USART_ClearITPendingBit(USART3, USART_IT_RXNE);
				uartvalue = USART3->DR;
				if(uartvalue == '$')
				{
						startBit = 1;
						num = 0;
				}
				if(startBit == 1)
				{
						inputString[num] = uartvalue;     
				}  
				if(startBit == 1 && uartvalue == '#') 
				{	    	
						newCmdReceivedFlag = 1; 
						startBit = 0;
						int9num = num;			
				}
				num++;
				if(num >= 80)
				{
						num = 0;
						startBit = 0;
						newCmdReceivedFlag	= 0;				
				}	 		
		} 
}	

u8 newCmdReceivedFlag = 0;
u8 inputString[80] = {0};
u8 ProtocolString[80] = {0};

//测试-控制LED-$1,0,0,0,0,0,0,0,0,0#
		if(ProtocolString[1]=='1')
		{
			led13=0;			//低电平LED灯亮
		}
		if(ProtocolString[1]=='0')
		{
			led13=1;			//高电平LED灯灭
		}

三、测试

1、起始符和结束符说明

'$'的起始符,'#'是结束符。起始符和结束符对不上,则字符串发送控制指令无效。

2、串口1中断测试

LED亮:"$1,0,0,0,0,0,0,0,0,0#"

LED灭:"$0,0,0,0,0,0,0,0,0,0#"

3、串口3中断测试

串口调试助手连接Arduino Mega单片机

LED亮:"$1,0,0,0,0,0,0,0,0,0#"

LED灭:"$0,0,0,0,0,0,0,0,0,0#"

四、程序打包下载链接

https://download.csdn.net/download/panjinliang066333/92469974

相关推荐
1+2单片机电子设计6 小时前
基于 STM32 的网络授权时钟系统设计与实现
开发语言·stm32·单片机·嵌入式硬件·php·51单片机
在职工程博士7 小时前
在职博士-南京邮电大学申请考核制博士招生实施细则(信息通信、信息管理工程方向)
大数据·数据库·嵌入式硬件·物联网·硬件工程·数据库开发
TEC_INO7 小时前
STM32_3:EXTI和NVIC
stm32·单片机·嵌入式硬件
张泽腾667 小时前
Ubuntu 扩容
linux·服务器·嵌入式硬件
恒锐丰小吕7 小时前
黑锋科技(HeifengTech)过压过流保护开关芯片全系列技术解析
嵌入式硬件·硬件工程
LCG米7 小时前
基于STM32F4和LVGL的智能灯光控制系统开发实战
stm32·单片机·嵌入式硬件
歌者長門8 小时前
STM32DAC输出遇到的问题
stm32·单片机·嵌入式硬件
辰哥单片机设计8 小时前
STM32项目分享:智能头盔
stm32·单片机·嵌入式硬件
九鼎创展科技8 小时前
「有温度的陪伴」:基于全志 V821 的情感共鸣型实体机器人详解
linux·人工智能·嵌入式硬件·机器人