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<sizeof(TxBuffer1); i++) //发送字符串
            {
                USART_SendChar(USART1,TxBuffer1[i]);
                Delay(0x0000ff0);
            }
            /*for(i=0;i<TxCounter1;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

原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/9739765.html

时间: 2024-10-28 06:59:10

STM32串口中断实例二的相关文章

STM32串口中断的一些资料

在研究STM32串口接收发送中断的时候找到不少不错的资料,现在备份在这里.以供自己查阅,以及方便其他人. TC ====TXE 顺便预告下最近会写个有关串口处理数据的帖子,从查询和中断方面以及数据处理的方式,从队列以及FIFO方面写起. SECTION 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 /* 调试STM32串口过程中发现一个奇怪的问题,

STM32串口中断卡死主循环问题分析

在一项目中,使用STM32作为主控,程序运行一段时间后概率出现主循环卡死现象. 问题分析如下: 1.程序USART2不停接收并处理串口数据,波特率115200: 2.主循环卡死: 3.USART1中断及TIM2中断响应函数运行正常:(USART1及TIM2中断优先级均比USART2高) 4.出现现象后,拔掉USART2的接收数据线,现象不能回复正常: 5.出现现象后,拔掉后再插入USART2的接收数据线,现象不能回复正常: 6.并未出现HardFault现象: 基于以上4点,可能原因如下: 1.

stm32串口接收完整的数据包

借鉴了文章:<stm32串口中断接收方式详细比较> 文章地址:http://blog.csdn.net/kevinhg/article/details/40186169 串口的配置这里不做说明,仅对中断中的协议解析进行描述 数据帧协议: 帧头1 帧头2 数据长度 有效数据 crc_1 crc_2 B5 5B 03 00 57 0B 帧头1+帧头2+数据长度(包含有效数据.crc_1.crc_2)+有效数据 + crc_1 + crc_2(校验为帧头到有效数据) crc16校验未深入学习,代码也

STM32串口悬空导致CPU持续进入中断函数

STM32的串口开启中断,在串口悬空(即不接外设)的情况下,CPU会不断的进串口中断服务函数 并且接收到的数据为0,当你把外设接上,一切OK. void USART2_IRQHandler(void) { INT8U tmp; /* OK */ if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET){ USART_ClearITPendingBit(USART2, USART_IT_RXNE); tmp = USART_ReceiveData(US

STM32串口之空闲中断

NBiot模块一般都是串口接口,使用AT指令集,对接中国移动onenet平台.先用串口助手去测试,流程测试OK之后需要在MCU上重新写一遍. STM32串口 IDLE中断 IDLE其实是空闲的意思.IDLE中断叫空闲中断,不叫帧中断.那么什么叫空闲,怎么定义空闲呢?在实际发送数据的时候,比如一串字符串,我们会采用如下方式发送 void uart1_putc(char dat) { SBUF = dat; while (!TI); TI = 0; } void uart1_puts_n(char

stm32的串口中断

void USART1_IRQHandler(void)                                                              //串口中断{    if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)           //USART1接收中断,,,    {            uart1_rx_buf[uart1_rx_RecvIndex] = USART1->DR;       

STM32串口USART1的使用方法和程序

通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半双工单线通信. 1.STM32固件库使用外围设备的主要思路 在STM32中,外围设备的配置思路比较固定.首先是使能相关的时钟,一方面是设备本身的时钟,另一方面如果设备通过IO口输出还需要使能IO口的时钟:最后如果对应的IO口是复用功能的IO口,则还必须使能AFIO的时钟. 其次是配置GPIO,GPI

STM32串口USART1的使用方法

前言: 通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的   波特率选择,支持同步单向通信和半双工单线通信. 1.STM32固件库使用外围设备的主要思路 在STM32中,外围设备的配置思路比较固定.首先是使能相关的时钟,一方面是设备本身的时钟,另一方面如果设备通过IO口输出还需要使能IO口的时钟:最后如果对应的IO口是复用功能的IO口,则还必须使能AFIO的时钟. 其次是配置G

Stm32L0串口中断接收使用

最新在做LoRa的项目,使用的是STM32L072和SX1276,需要做一个串口透传模块,刚开始做demo的时候不考虑功耗,所以串口发送和接收直接使用下列函数执行: HAL_UART_Transmit(&Sensor_UartHandle,(unsigned char *)&readcommand, sizeof(vcom_read_command_t), VCOM_START_DELAY); HAL_UART_Receive(&Sensor_UartHandle,(unsigne