打印
[应用相关]

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

[复制链接]
1006|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-11-5 14:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
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=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='\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=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='\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);固定格式
   //表示将该指针指向的数据视为常量字符,不允许对其内容进行修改。     
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_50866235/article/details/143462598

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2181

主题

16470

帖子

17

粉丝