
第四课时UART 基础知识本课主题UART串口的基础知识包括数据帧格式、UART 与 USART 的区别以及两个串口收发的小实验。课程视频UART 基础知识一、单片机与其他设备之间的通信连接两台设备之间通信接线必须交叉数据也有固定的格式。先看接线。Tx 是数据发送引脚负责把数据发出去Rx 是数据接收引脚负责从对面收数据。所以单片机和其他设备相连时自己的 Tx 要接对方的 Rx自己的 Rx 要接对方的 Tx也就是交叉连接。接反了就收不到数据这是接线时最容易犯的错。1.1 数据格式串口线上没有时钟线收发双方全靠事先约定好的格式来对齐这个格式叫数据帧。一帧由三部分组成起始位、数据位、停止位。串口平时空闲时线是高电平。要开始发数据先发一个起始位也就是把线拉低一个位的时间告诉对方我要开始发了。接着是数据位这里用电压来表示数据发送低电压代表 0发送高电压代表 1。数据位发完再发停止位方法就是保持一段时间的高电平。数据位的长度是可以设定的习惯上以字节也就是 8 位来传输。数据位长度不同一帧能装的信息也不同。8 位正好是一个字节如果加上校验位8 位数据加 1 位校验就变成 9 位。图里把 8 位无校验、8 位有校验、9 位无校验、9 位有校验这几种情况并排列了出来方便对照。1.2 我的疑问这些位数代表的是什么东西呢知道这些有什么用处呢1.3 疑问解答数据位长度说白了就是一帧里装数据的格子数。串口是把数据拆成一个个二进制位也就是 0 和 1一位一位地发设成 8 位就是每次连发 8 个 0 或 1正好装下一个字节。所以位数指的是这一步能承载多少信息位数越多一次能装的数据越多但传得也越慢。知道这些的用处在于收发双方必须把这些参数约定成一样包括数据位长度、校验方式、停止位、波特率否则接收方会把每一帧切错收到的就全是乱码。这也是为什么在 CubeMX 和串口调试助手里要填 Data Bits、Parity、Stop Bits、Baud Rate这几个选项正是对着这张数据格式图来的。1.4 校验位数据在传输途中可能出错校验位就是用来粗查这种错误的。它分奇校验和偶校验靠数数据位里 1 的个数来判断。以发送十进制 85 为例它的二进制是 1010101其中有四个 1是偶数个。用奇校验时校验位补一个 1让 1 的总数变成奇数用偶校验时校验位补 0保持 1 的总数是偶数。接收方收到后同样数一遍 1 的个数如果奇偶性对不上就说明传输过程中出了错。1.5 一位的时间一位代表传输一个高低电压所消耗的时间这个时间由波特率决定。波特率是每秒钟传输位的数量。9600 波特率就是每秒传 9600 个位一位等于 1/9600 秒约 0.1 毫秒115200 波特率每秒传 115200 个位一位约 8.7 微秒。收发双方的波特率必须一致否则每一位的时间对不上数据就全乱了。二、UART 与 USART 的区别UART 和 USART 名字很像工作模式却不一样。UART 的全称是 Universal Asynchronous Receiver/Transmitter也就是通用异步收发器只支持异步工作模式只有 Tx、Rx 两根线。USART 是 Universal Synchronous/Asynchronous Receiver/Transmitter也就是通用同步异步收发器同步和异步都支持除了 Tx、Rx还多出一根 CK 时钟线。也就是说USART 比 UART 多了一种带时钟的同步模式用它就能补上 UART 只支持异步的短板。三、简单数据发送实验3.1 连接单片机与电脑单片机要跟电脑通信中间需要一个 USB 转 TTL 模块把电脑的 USB 信号转成串口能识别的电平。模块的 GND、TXD、RXD 接出来和单片机相连。还是要记住发送接接收所以模块的 TXD 接单片机的 Rx模块的 RXD 接单片机的 Tx。在这块 STM32F103C8T6 上USART1 用的引脚是固定的PA10 是 USART1_RX也就是数据接收引脚PA9 是 USART1_TX也就是数据发送引脚。实际接线就是这样USB 转 TTL 模块的 GND、RXD、TXD 分别接到板子的 PA10、PA9 一带另外还有 ST-Link 负责下载和调试。接着打开 CubeMX 配置。在 Connectivity 分类里找到 USART这颗芯片一共有三个串口。USART1、USART2、USART3 分别对应串口 1、串口 2、串口 3这次用串口 1。点开之后先选模式。Mode 里有好几个选项。Asynchronous 是异步模式Synchronous 是同步模式Single Wire 是半双工后面还有多处理器通信、IrDA、LIN、智能卡等。这里选 Asynchronous也就是异步模式。选好异步模式后CubeMX 会自动把引脚配好。可以看到 PA9 被设成了 USART1_TX引脚模式自动变成复用输出推挽最大输出速度是 HighPA10 被设成 USART1_RX自动变成输入、No pull。要记住 CubeMX 会把 RX 自动配置为输入、TX 自动配置为输出接线的时候千万不能接反。3.2 串口参数与生成的代码模式选好之后往下配置串口参数这些参数和前面讲的数据帧格式一一对应。Baud Rate 是波特率这里默认 115200 Bits/sWord Length 是数据位长度默认 8 Bits也就是 8 位数据位Parity 是校验方式默认 NoneStop Bits 是停止位长度默认 1。停止位长度可以选 1 位或者 2 位这里用 1 位。校验方式有不使用校验位、偶校验、奇校验三种这里选 None也就是不使用校验位。综合下来本课的串口默认配置就是 8 位数据位、无校验、1 位停止位、波特率 115200。配置好生成工程打开 main.c 看初始化流程。MX_GPIO_Init 负责 IO 引脚的初始化MX_USART1_UART_Init 负责 USART1 串口的初始化两者分工明确。除此之外CubeMX 还自动生成了一个句柄handle写法是 UART_HandleTypeDef huart1它包含了跟串口 1 有关的所有数据后面收发数据的函数都要用到它。这里只需要记住有这么个句柄叫 huart1 就行。3.3 发送数据的接口要把数据发出去用的是 HAL_UART_Transmit。它的作用是通过串口向外发送数据参数 huart 填串口句柄的指针也就是 huart1pData 填要发送的数据的指针。写发送代码之前先认识一下单片机里常用的整数类型。带符号整数用 int无符号整数多一个 u写作 uint。int8_t 和 uint8_t 是 8 位int16_t 和 uint16_t 是 16 位32 位、64 位依次类推。8 位无符号数范围是 0 到 25516 位是 0 到 65535。后面发数据时 pData 要求是 uint8_t 指针所以这些长度要提前心里有数。完整的参数一共有四个huart 是句柄pData 是要发送的数据Size 是要发送的字节数Timeout 是超时时间单位毫秒。返回值方面HAL_OK 是成功HAL_ERROR 是发送出错HAL_BUSY 是串口忙HAL_TIMEOUT 是发送超时。最后这个 Timeout 参数这里填 HAL_MAX_DELAY表示无限期地等下去直到发送完成为止。3.4 实战发送的数据可以是字节、数组、字符也可以是字符串写法略有不同。发单个字节 0x5a指针用 byteNumber长度写 1发数组指针直接用数组名 byteArray长度写 5发单个字符因为 pData 要的是 uint8_t 指针需要把 char 强转一下写成 (uint8_t *)ch发字符串指针用 (uint8_t *)str长度用 strlen(str) 自动算。照着这个套路来就行。四、通过电脑发送数据控制开发板第二个实验反过来让电脑发数据、开发板收数据。CubeMX 里的配置和前面一模一样还是默认配置。数据帧仍然是 8 位无校验、波特率 115200。本次实验的目标是用电脑通过串口发指令控制板载 LED 的熄灭与亮起。工程里同样有串口 1 的句柄 huart1。接收数据用的函数是 HAL_UART_Receive作用和 Transmit 刚好相反参数含义一样只是把发送换成了接收pData 变成了接收缓冲区的指针。完整的参数和返回值也与发送类似这里同样用 HAL_MAX_DELAY一直等直到接收完成。把接收和判断拼起来就是完整逻辑先读一个字节到 dataRcvd再判断它是什么。这里有一个很重要的点接收到的数据要加上引号写成 ‘0’ 或 ‘1’代表的是字符如果写成不带引号的 0 或 1那是数值判断永远不成立起不到任何作用。uint8_tdataRcvd;HAL_UART_Receive(huart1,dataRcvd,1,HAL_MAX_DELAY);if(dataRcvd0)// 收到字符 0熄灭 LED{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);// 板载灯是开漏写 1 熄灭}elseif(dataRcvd1)// 收到字符 1点亮 LED{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);// 板载灯是开漏写 0 点亮}需要说明一下原视频这张图里的 else if 分支也写成了 GPIO_PIN_SET那是笔误。板载 LED 是开漏接法写 0 才点亮所以这里应该是 GPIO_PIN_RESET上面的代码已经改正。复习速记串口默认配置8 数据位、无校验、1 停止位、波特率 115200。收发双方的帧格式必须一致否则收到的全是乱码。起始位是一个下降沿停止位是保持一段高电平。接线要交叉TX 接 RX、RX 接 TX千万别接反TX 是发、RX 是收。校验位分奇校验和偶校验靠 1 的个数判断有没有传错。发送指令是 HAL_UART_Transmit(huart1, 数据指针, 数量, 超时)接收是 HAL_UART_Receive参数一样。判断收到的字符要加引号写成 ‘0’、‘1’写成 0、1 没有作用那是数值不是字符。HAL_MAX_DELAY 表示无限期等待是超时参数专用。初始化MX_GPIO_Init() 管 IOMX_USART1_UART_Init() 管串口句柄是 huart1。