STM32串口接收中断与空闲中断处理
串口存在中断,不用另外写中断初始化
USART1->CR1 |=(1<<5);//打开接收中断
USART1->CR1 |=(1<<4);//打开空闲中断
u8 rev_buff[1000];
u8 usart1_flag=0;
void USART1_IRQHandler(void)//中断服务函数
{
static u8 i=0;
if(USART1->SR &(1<<5))//判断是否读取,读取内容
{
rev_buff[i]=USART1->DR;
i++;
}
if(USART1->SR &(1<<4))//判断是否空闲,停止读取
{
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);
}
}
完整代码
/*
Function name:Usart1_Config
Description:串口1初始化
param:brr-->波特率
retval:None
Remarks:
PA9:复用推挽输出
PA10:复用
*/
void Usart1_Config(u32 brr)
{
RCC->AHB1ENR|=(1<<0);//PA时钟
RCC->APB2ENR|=(1<<4);//USART1时钟
//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复用功能
//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
}
/*
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);//使能
}
u8 rev_buff[1000];
u8 usart1_flag=0;
void USART1_IRQHandler(void)//中断服务函数
{
static u8 i=0;
if(USART1->SR &(1<<5))//判断是否读取,读取内容
{
rev_buff[i]=USART1->DR;
i++;
}
if(USART1->SR &(1<<4))//判断是否空闲,停止读取
{
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);
}
}
//重定向
int fputc(int c,FILE * stream)
{
while(!(USART1->SR & (1<<7)));
USART1->DR=c;
return c;
}
Usart1_Nvic();需要的中断时就删除屏蔽,不需要时就打开屏蔽
重定向是在这个软件中使用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);固定格式
作者:aflet