重要的事情要说三遍,这个通信口,非常重要!非常重要!非常重要!
Uart = Universal Asynchronous Receiver/Transmitter,通用异步接收器/发送器,它的特点就在于它的名字,通用,很多地方都用到;异步,它没有同步时钟;接收器/发送器:能收能发,全能小超人。
一般用在上位机(比如PC,比如中控等)与单片机的通信,单片机与模块间的通信,单片机与单片机的通信等等,主要用于两个不同设备间的通信,总之,它很通用!
它的主要特点除了它的名字之外,还要明白几个:1.一对一;2.全双工;3.传输距离不长,15m以内,长了干扰啊,还得取决于硬件设计电路;
PC如何与单片机通信呢?
PC相关的通信接口叫COM口,它有9个pin,是RS-232的电平标准,+15/+13V表示1,-15/-13V表示0;
单片机的相关通信接口叫UART口,它有4个pin,是TTL电平标准,+5V表示1,0V表示0;
这两个接口标准不一样,引脚数目不一样的通信接口,如何连接呢?
1. 电平标准不一样,需要一个电平转换芯片,MAXxxxx,所以,大家看到的,单片机跟PC机的接口连接上,有一个电路,如下图:
![](data/attach/1904/7smnodzdc94rcfwuwl14lcsd3ban4eip.jpg)
2. 引脚数目不一样,
Uart有四个引脚,VCC(电源),RXD(接收),TXD(发送),GND(地);
COM口有9个引脚,我们只用第2个pin(RXD)和第3个pin(TXD)就行了,其它引脚暂时不管;
需要注意的是,要把PC的RXD和板子的TXD连接起来,板子发送对PC接收,把PC的TXD和板子的RXD连接起来,PC发送对板子接收,还要记得共地,也就是把串口的铁壳子和板子的地连接起来;
具体的设计原理和细节,软件工程师不需要了解太多,知道有这么一回事就行了。
同理,单片机与单片机,单片机与模块通信,也就是把不同设备的RXD和TXD交叉连接起来。
如下图:上面的是板子上的接口,下面的是PC的接口,USB转COM口;
![](data/attach/1904/ea873pdwzsyopobny0dvz2vxlsy00hug.jpg)
这两个长这样子的口,怎么连接起来呢?都是针针的,咋个连接?
这里普及一下公头和母头,
如上图,带有很多针针的,就是公头;
如下图,带有很多孔的,就是母头;
由于我用的两个都是公头,就必须要用两端都是母头的线连接起来;
![](data/attach/1904/aszper9axw4hehrhohld2ro8yvp1c36p.jpg)
如何连接?两端连接上去咯,连接后的图如下图:
![](data/attach/1904/st71290pcx8a1b82w90c90oyfzh9sm95.jpg)
好了,硬件接口讲解完毕,现在开始软件接口的配置了,
1. 找原理图,找到 RXD = PC11,TXD = PC10,这个根据原理图来,不能千篇一律;
2. 建一个STM32Cube工程,
参照STM32CubeMx 创建第一个工程;
3. 在Pinout页,看一下PC11/PC10,可以设置为UART4,那就把它设置为 UART4吧,设置标示的 1)和 2);
![](data/attach/1904/n3jj4c81ikt44qhvnqcgs7g389oe5hwl.jpg)
4. 配置完引脚,在Configuration页,点刚刚配置引脚的UART4,可以配置UART4;
![](data/attach/1904/agj8scriswsc1pglt8wmfndfruh0gphk.jpg)
讲解一个Baud Rate、Word Length、Parity、Stop Bits、Data Direction、Over Sampling的含义吧。
先来一个串口时序图,如下图:先发一个 Start bit,接下来发几位数据,再接下来发个 Stop bit,一个数据帧结束,接下来发下一帧;
![](data/attach/1904/1vql4ev0sb157zfvbwcu2mz7tdv86pp2.jpg)
Baud Rate:波特率,通信的速率,表示每秒传多少个Bits,我们设置成 115200 Bits/s,一秒钟能传115200个Bits,通信的速率越高,传输数据越快,当然,传输距离就越短,出错的可能性也越大;
Word Length:一帧数据帧的位数,一个Start Bit到一个Stop Bit,就算一帧数据,一个BYTE为8 Bit,一般设置为8;
Parity:奇偶校验位,数据位为“1”的个数,加上这个位,使得"1"的个数为偶数(偶校验)或者奇数(奇)校验,以此来校验数据的正确性,如果想用8 Bit数据和校验位,可以把上面的Word Length设置为9,奇偶校验位设置为奇或者偶;不过我们这里不使用奇偶校验位;
Stop Bits:停止位,表示数据帧结束;另外,由于是异步传输,没有专门的时钟,每个设备有不同的时钟源,可能会有一点点点小小的偏差,这个停止位还可以用来提供通信双方校正通信同步的机会;
Data Direction:这个还用说,当然选收发咯,当然,你也可以选单收或者单发,你喜欢,你愿意!
Over Sampling:对这东东,只要知道 1. 主要用来做接收采样的,8倍波特率或者16倍波特率;2. 波特率计算跟这个有关系,反正不用自个计算;3. 我们平常用的波特率都在1MBps之下,选啥没什么区别;具体就不上图了,RM0033文档满上,撸一把!
总之,通信双方,参数,一定要一致!一定要一致!!一定要一致!!!
好了,生成代码,生成的代码是这样的,有没有熟悉的感觉撒:
![](data/attach/1904/bajuljogsukp6xaf6kt5qntox5321frx.jpg)
看下MX_UART4_Init(),是不是就是刚才配置的参数?
![](data/attach/1904/4honhw9iox29tbyyy9ixssw7q9iiwnwx.jpg)
再次回到main()函数里面,看看while(1){}里面,是不是空空如也呀?有没有觉得,应该加点什么?
我们就做一个收到什么,就把收到的自加1,再发送出去的功能吧。
首先,声明个变量,用来存放收到的数据;
![](data/attach/1904/9t07lfd97pqz5gto5z3m3tcjqp4z2ttd.jpg)
接下来,将收到的数据自加1,发送出去:
![](data/attach/1904/xjach3ktzriu0wzfgh8f9yq95zfdyrj3.jpg)
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
作用是接收/发送串口数据,
*huart:句柄
*pData:数据指针,该指针的内容就是接收/发送的数据
Size:接收/发送数据的长度,因为这里只接收一个字节,就写1,如果要接收多个数据,可以填其它数,但pData可以传入一个数组;
Timeout:时间,因为直接在循环里面轮询,就直接填0;
这两个函数在HAL库里面有实现的源码,有兴趣的话可以看看,对照着RM0033阅读代码,看看它是如何实现的,会有很大收获;
编译,运行,在PC机上用串口调试助手测试下;
![](data/attach/1904/8767vati42x5nv2zy8onzp6iocgsy16c.jpg)
串口配置一定要和MCU配置一致;
请钩上HEX发送,HEX显示;
这里是直接用轮询的方式接收串口数据,后面,我们再讲解一下用中断和DMA的方式接收串口数据并处理吧。
整个工程及代码呢,请上百度 {MOD}上下载咯;
链接:https://pan.baidu.com/s/19usUcgZPX8cCRTKt_NPcfg 密码:07on
在Code/UartTest文件夹里面;
上一篇:《
STM32CubeMx 创建第一个工程》
下一篇:《
STM32 Uart中断接收》