STM32 USART串口通信 综合练习

USART(通用同步/异步串行接收/发送器)串口通信具有以下特点:

  • 全双工操作:设备之间可以同时进行数据的发送和接收。
  • 异步通信:不需要共同的时钟信号,双方设备有各自的时钟。
  • 单端信号:使用一根线传输信号,通常需要地线作为参考。
  • 点对点通信:仅支持两个设备之间的直接通信。
  • USART串口通信的参数

  • 波特率:单位时间内传输的码元数量,决定了数据传输速率。
  • 起始位:标志数据帧的开始,通常为低电平。
  • 数据位:数据帧的有效载荷,常见为8位。
  • 校验位:用于数据验证,可以位于数据帧的最后一位。
  • 停止位:标志数据帧的结束,通常为高电平。
  • USART串口通信的优缺点

    优点

  • 简单易用:不需要统一的时钟线,接线方便。
  • 广泛的应用:由于其简单性和灵活性,被广泛应用于各种嵌入式系统和物联网设备中。
  • 缺点

  • 电气接口不统一:不同处理器使用的电平存在差异,直接相连可能会损伤器件。
  • 抗干扰能力差:TTL信号的抗干扰能力较差,数据在传输过程中容易出错。
  • 通信距离短:由于抗干扰能力差,通信距离通常限制在一个电路板上的两个芯片之间。
  • tim.c配置

    #include "stm32f10x.h"
    #include "led.h"

    void Tim_init(u16 arr,u16 psc){
        
        TIM_TimeBaseInitTypeDef Tim2;
        NVIC_InitTypeDef NVIC_Initx;
        //1、开启定时器2时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);    //开启TIM2时钟
        
        //2、定时器初始化
        Tim2.TIM_Period = arr;    //自动装载值    装载值10000-1
        Tim2.TIM_CounterMode=TIM_CounterMode_Up;    //计数模式 向上计数
        Tim2.TIM_ClockDivision=TIM_CKD_DIV1;    //时钟分割是输入捕获用的,故这里随便给
        Tim2.TIM_Prescaler=psc;    //预分频值        7200-1

        TIM_TimeBaseInit(TIM2,&Tim2);    
        //3、打开更新中断
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);    //此处有中断

        //4、优先级    有中断就有中断优先级
        NVIC_Initx.NVIC_IRQChannel = TIM2_IRQn;    //配置目标:中断线0
        NVIC_Initx.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Initx.NVIC_IRQChannelPreemptionPriority = 1;        //设置抢占优先级
        NVIC_Initx.NVIC_IRQChannelSubPriority = 2;                        //设置响应优先级
        NVIC_Init(&NVIC_Initx);
        
        
        //5、启动定时器
        TIM_Cmd(TIM2,ENABLE);
    }

    //构建中断服务函数,在.s启动文件中找
    void TIM2_IRQHandler()
    {
        //交替闪烁    
        //如果B5输出为1 则B5输出为0 E5输出1
        if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))
        {
            LED1_ON;
            LED2_OFF;
        }
        else    //如果B5输出为0 则B5输出为1 E5输出0
        {
            LED2_ON;
            LED1_OFF;
        }
        //                否则B5输出为1 E5输出为0
        
        //清除中断标记位        如何已经触发过来,再次使用不清除就一直是触发过后的高电平
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }

    tim.h配置

    #ifndef __TIM_H
    #define __TIM_H

    #include "stm32f10x.h"
    void Tim_init(u16 arr,u16 psc);

    #endif

    usart.c配置

    #include "stm32f10x.h"
    #include "usart.h"

    void Usart_Init(int bsp)
    {
        GPIO_InitTypeDef Initx;
        NVIC_InitTypeDef NVIC_Initx;
        USART_InitTypeDef USART_Initx; 
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1,ENABLE);//开io时钟
        
        //1、io设置 A9复用推挽和A10浮空 复用
        //初始化 A9复用推挽 A10浮空 复用
        Initx.GPIO_Mode = GPIO_Mode_AF_PP;
        Initx.GPIO_Pin = GPIO_Pin_9;
        Initx.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&Initx);//A9复用推挽
        
        Initx.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        Initx.GPIO_Pin = GPIO_Pin_10;
        Initx.GPIO_Speed = GPIO_Speed_50MHz;    
        GPIO_Init(GPIOA,&Initx);//A10浮空 复用
        
        //2、开串口1时钟
        //3、设置串口1的工作方式
        USART_Initx.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//输入和输出
        USART_Initx.USART_Parity = USART_Parity_No;//无奇偶校验 Even偶校验 Odd奇校验
        USART_Initx.USART_StopBits = USART_StopBits_1;//帧结尾传输一个停止位
        USART_Initx.USART_WordLength = USART_WordLength_8b;//9位数据位
        USART_Initx.USART_BaudRate = bsp;//波特率
        USART_Initx.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制
        USART_Init(USART1,&USART_Initx);
        //4、打开串口的 “接收” 数据中断
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//接收中断
        //5、设置中断优先级
        
        NVIC_Initx.NVIC_IRQChannel = USART1_IRQn;//配置目标USART1 全局中断
        NVIC_Initx.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Initx.NVIC_IRQChannelPreemptionPriority = 2;        //设置抢占优先级
        NVIC_Initx.NVIC_IRQChannelSubPriority = 2;                        //设置响应优先级
        NVIC_Init(&NVIC_Initx);
        
        //6、启动串口
        USART_Cmd(USART1,ENABLE);
        
    }
    void USART1_IRQHandler()
    {
        u16 data;
        if(USART_GetITStatus(USART1,USART_IT_RXNE))    //是接收中断就触发此条件
        {
            data = USART_ReceiveData(USART1);//读数据
            USART_SendData(USART1,data);//把data数据发出去
            USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除中断标记位        
        }//可能有多个原因引起串口中断
        //else if(xxx中断)

    }

     

    usart.h文件配置

     #ifndef __USART_H
    #define __USART_H

    #include "stm32f10x.h"
    void Usart_Init();

    #endif

    main.c配置

    #include "stm32f10x.h"
    #include "tim.h"
    #include "usart.h"

    int main()
    {
        u16 data;
        u8 num[6],i = 0;
        //中断分组
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

        Tim_init(999,8999);
        Usart_Init(115200);
        

        //delay_init();
        //编写程序功能
        //BEEP_ON;
        while(1){;
            //读取定时器的当前值
            data = TIM_GetCounter(TIM2);
            i = 0;
            //拆分当前值
            while(data)
            {
                num[++i] = data %10;//把个位放入数组中保存
                data = data / 10;//去掉当前数的个位
            }
            //发送当前值
            for(;i>=1;i–)
            {
                USART_SendData(USART1,num[i]+'0');
                while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
            }
            //发完一组数据,换行
            USART_SendData(USART1,'\r');
            while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
            USART_SendData(USART1,'\n');
            while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
        }
        return 0;
    }

    运行结果:

    总结

    USART 是一种功能强大的串行通信接口,广泛应用于各种嵌入式系统和物联网设备中。通过合理配置 USART 参数,可以实现高效、稳定的数据传输。

     

    作者:随便@_@

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 USART串口通信 综合练习

    发表回复