• 串口通信原理及应用


    1. 前言介绍

    串口通信是一种设备间非常常用的串行接口,以比特位的形式发送或接收数据,由于成本很低,容易使用,工程师经常使用这种方式来调试 MCU。

    串口通信应用广泛,可以实现两个设备之间的通信,例如STM32与wifi、蓝牙、4G、NB-IoT使用的都是串口通信协议。

    2. 连接方式

    如下图所示:
    己方的RX(接收引脚)对应对方的 TX(发送引脚),而己方的 TX 则是接收对方的 RX 引脚,这种方法可以用于双向通信。

    在这里插入图片描述

    如若只需进行单向通信,采用以下方式也是可以的,此方法通常为仅接收外部设备传来的数据:
    在这里插入图片描述

    3. 数据帧格式

    起始位(Start Bit):数据帧的起始位,用于标识数据传输的开始。通常为逻辑低电平。

    数据位(Data Bits):数据帧中实际传输的数据位数。常见的数据位数有5位、6位、7位和8位。

    校验位(Parity Bit):用于校验数据位的奇偶性,以检测和纠正传输中的错误。常见的奇偶校验方式有奇校验和偶校验,也可以选择不使用校验位。

    停止位(Stop Bit):数据帧的结束位,用于标识数据传输的结束。通常为逻辑高电平。
    在这里插入图片描述

    如图所示,可以看到串口数据是低有效位优先传输(LSB)。

    4. 代码编写

    通过STM32F407的数据手册可以查询到,PA9和PA10引脚是具有 USART1功能的,它被挂载在 APB2 总线上:
    在这里插入图片描述
    所以我们需要 开启 GPIOA端口时钟以及启用 串口1时钟:

    	//开启硬件时钟:GPIO端口硬件时钟、USART硬件时钟
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    
    • 1
    • 2
    • 3

    PA9 和 PA10 是作为复用功能使用的,所以还要开启复用功能:

    	//配置GPIO引脚为复用功能模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;	//指定9、10号引脚
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//配置为复用功能模式
    	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//速度越高,功耗就越高,但是响应速度也更快
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不需要使能内部上下拉电阻
    	GPIO_Init(GPIOA, &GPIO_InitStructure);	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    然后依次对串口参数进行配置:

    	//将对应的GPIO引脚连接到串口
    	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
    	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
    	
    	
    	//配置串口相关的参数:串口号,波特率,数据位,停止位,流控制
        //波特率
    	USART_InitStructure.USART_BaudRate = baud;
    	//接收长度
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    	//停止位
    	USART_InitStructure.USART_StopBits = USART_StopBits_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;
    	
    	USART_Init(USART1, &USART_InitStructure);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    以下是完整的配置函数:

    void usart1_init(uint32_t baud)
    {
    	
    	//开启硬件时钟:GPIO端口硬件时钟、USART硬件时钟
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    	
    	
    	//配置GPIO引脚为复用功能模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;	//指定9、10号引脚
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//配置为复用功能模式
    	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//速度越高,功耗就越高,但是响应速度也更快
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不需要使能内部上下拉电阻
    	GPIO_Init(GPIOA, &GPIO_InitStructure);	
    	
    	
    	
    	//将对应的GPIO引脚连接到串口
    	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
    	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
    	
    	
    	//配置串口相关的参数:串口号,波特率,数据位,停止位,流控制
    	USART_InitStructure.USART_BaudRate = baud;
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    	USART_InitStructure.USART_StopBits = USART_StopBits_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;
    	USART_Init(USART1, &USART_InitStructure);
    	
    	
    	
    	//配置串口相关的中断
    	
    	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    	
    	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_Init(&NVIC_InitStructure);
    	
    	
    	
    	//使能串口工作
    	USART_Cmd(USART1, ENABLE);
     
    }
    
    • 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
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    以下是其他配置文章
    STM32F103ZET6点亮板载LED灯

    STM32F103C8T6的三种延时函数

    STM32使用PWM(脉冲宽度调制)

  • 相关阅读:
    深度学习实战:用Keras搭建深度学习网络做手写数字识别
    程序员面试金典 - 面试题 17.20. 连续中值
    why redis-cluster use 16384 slots?
    Java经典面试题总结(附答案)-java经典面试题大全总结以及整理
    unigui添加ssl(https)访问的方法
    CMS系统漏洞分析溯源(第6题)
    NSSCTF做题第9页(3)
    我的Qt作品(16)基于机器视觉+运动控制的大视野激光切割机软件
    什么是关键信息基础设施及其安全保护条例
    【Spring】spring简介 + ioc理论 + helloSpring
  • 原文地址:https://blog.csdn.net/qq_53381910/article/details/134472373