STM32串口中断实例二

发布者:BlissfulMoon最新更新时间:2025-09-16 来源: cnblogs关键字:STM32  串口中断 手机看文章 扫描二维码
随时随地手机看文章

int main(void) 

{

    uint8_t a=0;//LED高低电压控制


    /* System Clocks Configuration */

    RCC_Configuration();                                              //系统时钟设置

    /*嵌套向量中断控制器

        说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */

    NVIC_Configuration();                                              //中断源配置

    /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,RX。

    在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B, 因此要对这个端口的时钟

    进行使能,同时由于用到复用IO口功能用于配置串口。因此还要使能AFIO(复用功能IO)时钟。*/

    GPIO_Configuration();                                              //端口初始化

    USART_Config(USART1);                                              //串口1初始化


    while (1)

    {

        if(rec_f == 1) 

        {    

            //判断是否收到一帧有效数据                                             

            rec_f = 0;


            for(i=0; i            {

                USART_SendChar(USART1,TxBuffer1[i]);

                Delay(0x0000ff0);

            }

            /*for(i=0;i            {

                USART_SendChar(USART1,RxBuffer1[i]);

            } */

            if(a==0) 

            {

                GPIO_SetBits(GPIOD, GPIO_Pin_2);    //LED1  明暗闪烁

                a=1;

            }

            else 

            {

                GPIO_ResetBits(GPIOD, GPIO_Pin_2);

                a=0;

            }

        }

    }

}


main函数如上。


相关变量


uint8_t TxBuffer1[] = 'USART Interrupt Example: This is USART1 DEMO';

uint8_t RxBuffer1[], rec_f, tx_flag, i;


__IO uint8_t TxCounter1 = 0x00;

__IO uint8_t RxCounter1 = 0x00;


uint32_t Rec_Len;


串口中断函数配置如下所示:


//--------------------------------------------------------------------------------------

void USART_SendChar(USART_TypeDef* USARTx,uint8_t data) 

{

    USART_SendData(USARTx,data);

    while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);

}

//--------------------------------------------------------------------------------------

void USART_Config(USART_TypeDef* USARTx) 

{

    USART_InitStructure.USART_BaudRate = 19200;                        //速率19200bps

    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;   //无硬件流控

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                    //收发模式


    /* Configure USARTx */

    USART_Init(USARTx, &USART_InitStructure);                            //配置串口参数函数



    /* Enable USARTx Receive and Transmit interrupts */

    USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);          //使能接收中断

    USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);            //使能发送缓冲空中断


    /* Enable the USARTx */

    USART_Cmd(USARTx, ENABLE);

}

//--------------------------------------------------------------------------------------

void Delay(__IO uint32_t nCount) 

{

    for(; nCount!=0; nCount--);

}

/*--------------------------------------------------------------------------------------

系统时钟配置为72MHZ+外设时钟配置*/

void RCC_Configuration(void) 

{

    SystemInit();

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOA, ENABLE);

}

//--------------------------------------------------------------------------------------

void GPIO_Configuration(void) 

{

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                     //LED1控制--PD2

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;             //推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOD, &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                      //USART1 TX

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;             //复用推挽输出

    GPIO_Init(GPIOA, &GPIO_InitStructure);                     //A端口


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                  //USART1 RX

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //复用开漏输入

    GPIO_Init(GPIOA, &GPIO_InitStructure);                      //A端口

}

//--------------------------------------------------------------------------------------

void NVIC_Configuration(void) 

{

    /*  结构声明*/

    NVIC_InitTypeDef NVIC_InitStructure;


    /* Configure the NVIC Preemption Priority Bits */

    /* Configure one bit for preemption priority */

    /* 优先级组 说明了抢占优先级所用的位数,和子优先级所用的位数   在这里是1, 7 */

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);


    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                     //设置串口1中断

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;             //抢占优先级 0

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                //子优先级为0

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能

    NVIC_Init(&NVIC_InitStructure);

}


在中断服务函数中编写usart函数。


//串口1 中断服务程序

void USART1_IRQHandler(void)      

{

    unsigned int i;

    

    //判断读寄存器是否非空

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)       

    {

        //将读寄存器的数据缓存到接收缓冲区里

        RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);   


        //判断结束标志是否是0x0d 0x0a

        if(RxBuffer1[RxCounter1-2] == 0x0d && RxBuffer1[RxCounter1-1] == 0x0a)     

        {

            for(i=0; i< RxCounter1; i++) 

                TxBuffer1[i] = RxBuffer1[i];          //将接收缓冲器的数据转到发送缓冲区,准备转发

            

            //接收成功标志

            rec_f = 1;            

            

            //发送缓冲区结束符

            TxBuffer1[RxCounter1] = 0;                                             

            TxCounter1 = RxCounter1;

            RxCounter1 = 0;

        }

    }


    //这段是为了避免STM32 USART 第一个字节发不出去的BUG

    if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                   

    {

        //禁止发缓冲器空中断,

        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);                         

    }


}


运行结果如下,在发送去不填写任何字符,直接发送,显示RT Interrupt Example: This is USART1 DEMO,说明前三个字符已经被占用替换了。

试验平台alienteck mini stm32V1.9 stm32f103rbt6


关键字:STM32  串口中断 引用地址:STM32串口中断实例二

上一篇:stm32基本定时器timer6的原理与使用
下一篇:stm32串口——标志位学习

推荐阅读最新更新时间:2026-03-21 23:04

STM32串口中断实例二
int main(void) { uint8_t a=0;//LED高低电压控制 /* System Clocks Configuration */ RCC_Configuration(); //系统时钟设置 /*嵌套向量中断控制器 说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */ NVIC_Configuration(); //中断源配置 /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,
[单片机]
<font color='red'>STM32</font><font color='red'>串口</font><font color='red'>中断</font>实例二
STM32单片机串口中断+DMA使用(含CUBE配置)
最近又要重新用32做点东西,发现一两年没怎么碰的结果就是,曾经熟得不行的东西都变得极度陌生,这种重新学习记忆的过程过于痛苦,果然还是要留下一些记录给之后失忆的自己的。 1.STM32CUBE配置 1.1 pinout设置 找到想要用的串口,配置模式,正常情况是Asyn(异步)和Disable。 关于mode的几个选项: Asyn 异步 Syn同步 Single Wire单工 后面几个没有太多的了解惹 1.2 configuration设置 Parameter Settings可以设置:波特率/字长/奇偶校验/停止位/收发模式 DMA Settings中添加接收DMA的流 NVIC Setti
[单片机]
<font color='red'>STM32</font>单片机<font color='red'>串口</font><font color='red'>中断</font>+DMA使用(含CUBE配置)
STM32 串口接收流程-串口接收中断
串口接收 串口接收流程 编程USARTx_CR1的M位来定义字长。 编程USARTx_CR2的STOP位来定义停止位位数。 编程USARTx_BRR寄存器确定波特率。 使能USARTx_CR1的UE位使能USARTx。 如果进行多缓冲通信,配置USARTx_CR3的DMA使能(DMAT)。 使能USARTx_CR1的RE位为1使能接收器。 如果要使能接收中断(接收到数据后产生中断),使能USARTx_CR1的RXNEIE位为1。 当串口接收到数据时 USARTx_SR(ISR)的RXNE位置1。表明移位寄存器内容已经传输到RDR(DR)寄存器。已经接收到数据并且等待读取。 如果开启了接收数据中断(USART
[单片机]
STM32串口空闲中断及接受数据
STM32的串口空闲中断及接受数据——STM32简介 STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核 STM32的串口空闲中断及接受数据——关于什么是空闲中断: 检测到接收数据后,在数据总线上的一个字节时间内,没有接收到数据触发空闲中断。RXNE置位一次,空闲总线就检测一次。 关于STM32串口空闲中断的问题 1.空闲中断是接受数据后出现一个byte的高电平(空闲)状态,就会触发空闲中断。并不是空闲就会一直中断,准确的说应该是上升沿(停止位)后一个byte,如果一直是低电平是不会触发空闲中断的(会触发break中断)。 2.关于第二点有要铺垫的三个情况,datash
[单片机]
STM32串口中断还是用轮询
1.从轮询到中断 很多同学都不喜欢用中断,而偏爱用轮询的操作方式。 这是不是和我们的天性有关呢?每个人都喜欢一切尽在掌握中,肯定都不喜欢被打断。我们常常都有这样的经验:正在跟别人说一件事,然后突然有个电话打进来,Call打完后突然记不起来刚才讲到哪了!这种糟糕的体验对我们影响是如此深刻,以至于我们认定机器可能也是这样吧,频繁的中断会不会把事情搞乱呢?好在机器虽然大部分时间都比人笨一些,但在处理这种问题上却能做到一丝不苟。机器在中断来的时候总会老老实实地先把当前正在做的记录下来,然后转去处理中断事件,中断处理完后分毫不差地恢复原来的工作。 仔细想一想,我们是不是也可以在接电话前先用个小本儿记录一下正在讲的事情呢?我们为什么没有这么做
[单片机]
STM32 串口中断设置
我们基于之前的串口配置的那篇文章 来完成今天使用串口中断来控制led 灯的亮灭 首先我们要知道为什么要使用中断 使用中断 能高效的去执行程序,不会一直占用MCU的资源。 对于中断的介绍 可以看我之前关于中断的那篇文章 开始进入正题 我们如何配置串口中断 由于之前我们已经在user 这个文件夹下添加过这个文件了 所以我们直接在配置串口的那一个文件下 进行配置 首先 我们先配置 NVIC_InitTypeDef 这个结构体 uint8_t NVIC_IRQChannel; 中断分组 uint8_t NVIC_IRQChannelPreemptionPriority 抢占优先级 uint8_t NVIC_IRQChannel
[单片机]
STM32单片机串口空闲中断+DMA接收不定长数据
在上一篇文章STM32单片机串口空闲中断接收不定长数据中介绍了利用串口空闲中断接收不定长数据,这种方式有一个问题就是串口每接收到一个字节就会进入一次中断,如果发送的数据比较频繁,那么串口中断就会不停打断主程序运行,影响系统运行。那么能不能在串口接收数据过程中不要每接收一个数据中断一次,只有在一帧数据接收结束完成后只中断一次? 用串口的空闲中断加上DMA功能,就可以实现每帧数据接收完成后只中断一次,而在数据接收过程中,由DMA存储串口接收到的每个字节。 关于串口的空闲检测和DMA在STM32参考手册中有详细介绍。 下面看如何初始化串口空闲中断和 DMA。 void uart2_init( u16 baud )
[单片机]
<font color='red'>STM32</font>单片机<font color='red'>串口</font>空闲<font color='red'>中断</font>+DMA接收不定长数据
STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA
历程详解 详解包括: 中断原理讲解 例程流程详解 库函数分析详解 对应寄存器介绍 对应函数介绍 对应注释详解 本篇文章提供两种方法: 一种是 :IDLE 接收空闲中断+DMA 一种是: IDLE 接收空闲中断+RXNE接收数据中断 都可完成串口数据的收发 知识点介绍: STM32 IDLE 接收空闲中断 功能: 在使用串口接受字符串时,可以使用空闲中断(IDLEIE置1,即可使能空闲中断),这样在接收完一个字符串,进入空闲状态时(IDLE置1)便会激发一个空闲中断。在中断处理函数,我们可以解析这个字符串。 接受完一帧数据,触发中断 STM32的IDLE的中断产生条件: 在串口无数据接收的情况下,不会产生,
[单片机]
<font color='red'>STM32</font> HAL CubeMX <font color='red'>串口</font>IDLE接收空闲<font color='red'>中断</font>+DMA
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved