STM32串口接收中断与空闲中断

STM32串口接收中断与空闲中断


在这里插入图片描述
在这里插入图片描述
根据控制寄存器1(USART1_CR1)的RXNEIE(接收中断)和IDLEIE(空闲中断)

	USART1->CR1 |=(1<<5);//打开接收中断
	USART1->CR1 |=(1<<4);//打开空闲中断
	//也可以写为标准库函数
	//每来一个字节 ,就触发一次中断去中断服务函数当中及时接收
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	//空闲中断 打开IDLE 表示数据接收完成 可以进行处理了
	USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
	//这两个中断源触发同一个 中断通道

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
串口1中断服务函数:

u8 rev_buff[1000];
u8 usart1_flag=0;
void USART1_IRQHandler(void)//中断服务函数
{
	static u8 i=0;
	if(USART1->SR &(1<<5))//判断是否读取,读取内容
	//if(USART_GetITStatus(USART1,USART_IT_RXNE)==1)
	{
		rev_buff[i]=USART1->DR;
		i++;
	}
	if(USART1->SR &(1<<4))//判断是否空闲,停止读取
	//if(USART_GetITStatus(USART1,USART_IT_IDLE)==1)
	{
		USART1->SR;//读入USART_SR寄存器,清零
		USART1->DR;//读入USART_DR寄存器,清零
		rev_buff[i]='\0';
		i=0;
		usart1_flag=1;//传输完成标志位
		printf("rev_buff=%s\r\n",rev_buff);
	}
}

串口1配置函数:

/*
Function name:Usart1_Config
Description:串口1初始化
param:brr-->波特率
retval:None
Remarks:
PA9:复用推挽输出
PA10:复用
*/
void Usart1_Config(u32 brr)
{
	RCC->AHB2ENR|=(1<<0);//PA时钟
    //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC->APB2ENR|=(1<<4);//USART1时钟
	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//IO PA9
	GPIOA->MODER &=~(3<<18);//清零
	GPIOA->MODER |=(2<<18);//复用
	GPIOA->OTYPER&=~(1<<9);//推挽
	GPIOA->AFR[1]|=(7<<4);//选择USART1复用功能
	//PA10
	GPIOA->MODER &=~(3<<20);//清零
	GPIOA->MODER|=(2<<20);//复用
	GPIOA->AFR[1]|=(7<<8);//选择USART1复用功能
	//PA9-复用推挽  
  	//PA10 -浮空输入
	//GPIO_InitTypeDef GPIO_InitStruct={0};  
	//GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//串口1 发送引脚用 复用推挽
	//GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;//选中引脚
	//GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//io口速率,一般最大就行
	//GPIO_Init(GPIOA,&GPIO_InitStruct);
	//GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//串口1 发送引脚用 复用推挽
	//GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;//选中引脚
	//GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//USART1  USARTDIV是一个无符号定点数(div),
	float div;
	u32 div_f,div_m;//div_f是USARTDIV的小数部分,div_m是USARTDIV的整数部分
	div=84000000.0/16/brr;
	div_m=(u32)div;
	div_f=(div-div_m)*16+0.5;
	USART1->BRR=div_m<<4|div_f;
	
	USART1->CR1 |=(3<<2);//发送器/接收器 使能
	USART1->CR1 &=~(1<<10);//禁止奇偶校验
	USART1->CR1 &=~(1<<12);//字长 8位数据位
	USART1->CR1 &=~(1<<15);//16倍过采样	
	USART1->CR2 &=~(3<<12);//1位停止位
	
	Usart1_Nvic();//中断使能
	
	USART1->CR1 |=(1<<13);//使能USART1

	//USART_InitTypeDef USART1_InitStruct={0};
  	//USART1_InitStruct.USART_BaudRate=115200;//波特率
	//USART1_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流控制,NONE就是不用硬件流
	//USART1_InitStruct.USART_Mode=USART_Mode_Rx |USART_Mode_Tx;//接收跟发送都打开,规定用 或
	//USART1_InitStruct.USART_Parity=USART_Parity_No;//奇偶校验,不要
	//USART1_InitStruct.USART_StopBits=USART_StopBits_1;//1个停止位
	//USART1_InitStruct.USART_WordLength=USART_WordLength_8b;//8个数据位
	//USART_Init(USART1,&USART1_InitStruct);//按照结构体,初始化串口1
	//启动
	//USART_Cmd(USART1,ENABLE);
}
/*
Function name:Usart1_Nvic
Description:串口接收与空闲中断完成任意字符串的接收
param:None
retval:
Remarks:
*/
void Usart1_Nvic(void)
{
	USART1->CR1 |=(1<<5);//打开接收中断
	USART1->CR1 |=(1<<4);//打开空闲中断
	
	//配置优先级
	NVIC_SetPriority(USART1_IRQn,5);//优先级 占先=1 次级=1
	NVIC_EnableIRQ(USART1_IRQn);//使能

	//配置 串口RXNE 接收寄存器非空  表示来了一个字节数据
	//NVIC_InitTypeDef NVIC_InitStruct={0};
	//NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;//串口1的中断通道,串口1的所有中断源 都共用这一个通道
    //NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	//NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
	//NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
	//NVIC_Init(&NVIC_InitStruct);
}
u8 rev_buff[1000];
u8 usart1_flag=0;
void USART1_IRQHandler(void)//中断服务函数
{
	static u8 i=0;
	if(USART1->SR &(1<<5))//判断是否读取,读取内容
	//if(USART_GetITStatus(USART1,USART_IT_RXNE)==1)
	{
		rev_buff[i]=USART1->DR;
		i++;
	}
	if(USART1->SR &(1<<4))//判断是否空闲,停止读取
	//if(USART_GetITStatus(USART1,USART_IT_IDLE)==1)
	{
		USART1->SR;//读入USART_SR寄存器,清零
		USART1->DR;//读入USART_DR寄存器,清零
		rev_buff[i]='\0';
		i=0;
		usart1_flag=1;//传输完成标志位
		printf("rev_buff=%s\r\n",rev_buff);
	}
}
 
//重定向,即fputc重新定义,然后在keil的魔法棒->Target->勾选Use Micro LIB 
//通过此操作可以通过串口1使用printf
int fputc(int c,FILE * stream)
{
	while(!(USART1->SR & (1<<7)));
	//如果TC标志位不成立,就卡死等待 成立
	//while(USART_GetFlagStatus(USART1,USART_FLAG_TC) !=1)
	USART1->DR=c;
	return c;
}
 

Usart1_Nvic();需要的中断时就删除屏蔽,不需要时就打开屏蔽
重定向是在Keil软件中使用printf函数

主函数:

while(1)
	{
			if(usart1_flag==1)
			{
				if(strcmp((const char *)rev_buff,(const char *)"LED1ON")==0)
				{																														
					LED1_ON;
				}
				if(strcmp((const char *)rev_buff,(const char *)"LED1OFF")==0)
				{
					LED1_OFF;
				}
				usart1_flag=0;
			}	
}

注意:

strcmp((const char *)rev_buff,(const char *)"LED1ON")
   //strcmp((const )a,(const )b);固定格式
   //表示将该指针指向的数据视为常量字符,不允许对其内容进行修改。     

自我学习总结分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值