STM32F1系列HAL库配置串口通信
简单来说,串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。
UART与USART简单讲解
UART: 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作 UART。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,UART 通常被集成于其他通讯接口的连结上。 USART:(Universal Synchronous/Asynchronous Receiver/Transmitter) 通用同步/异步串行接收/发送器,USART 是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。 鉴于我理论知识不够,刚开始看到这些东西时,我: 什么全双工,同步,串行…这都是什么呀,趁着这点时间恶补了一下,大致能说出来个一点, 串行与并行 如果我们发送0x55,二进制就是01010101,那么在串行通信中,就是一个位一个位依次发送,而在并行中就是八根线同时发送,很明显,串行虽然一个位一个位收发,但是只用一根线,节约成本;并行八根线,牺牲成本保证速度,但我们一般用串行,这里讲解也是以串行为例。 单工与双工 单工,我们只能一方发送的同时一方只能接收且对象固定,发送只能是发送,接受只能是接收,而双工又分为半双工与全双工,半双工对象可以变化,不过也是只能同时收发,而全双工除了上述提到的以外,还可以同时接收发,图例已经很形象了。 下面再说UART帧格式: 像这样一个流程,一个数据流就发送接收完成了,举个例子: 像我们平时说话那样,如果我们作为接收方,当我们空闲时,我们可以接收别人发来的消息,那这空闲时,我们数据线是一直拉高的(1),当有人跟你说话时,首先向你示意(0),你此时可以放下手中的事,此时数据线为低电平,他给你说0x55,也就是01010101,他说完,此时校验完后,你又去干其他事了(1)。 可是真的这样简单吗? 像我就是那种不好好说话,还是空耳晚期,那我与其他人势必就会交流不畅,如果是我说 比如:我说了123,含糊不清,听到的人听成223,我以为我说的没问题,他以为他听的没问题,可事实确实有问题,这时怎么办?还记得之前提到的校验吗,如果, 我这样说”123 1+2+3=6“, 他听成”223 2+2+3=7“,他把7和我的6对应, ”哎,小兄弟你是不是有错误阿“ 这样我们就能找出错误了,这就是校验,只不过我们这里用的是奇偶校验,就是看你01010101中1的个数,判断是否为奇数(校验位置0)还是偶数(1)。 再比如:我说"00001111",和说“000111”,或者“11111111”,你会发现,前两个对方没法判断,几乎一模一样,注意是“说”,不是一字一字写给他,我“零——,一——”,“一————”你知道我说了几个零,几个一吗? 不能! 这时就不得不提到波特率与异步了 我和对话人都有一个时钟(手表),我开始讲,每说一个位恰个时间,从起始位恰到终止位停止,接收方看到我掐时间也开始恰,看到我终止,他也终止,那么他就可以从时间上来看我说了几个0与1,波特率在这里起到时间起始终止的作用,如果波特率为1bps,那就是我说完一个位就终止,接收方听完一个位就终止,其他的就不听了。 你以为就谈话终止了吗?我的表可能慢也可能快,因为我和接收方不是一个时钟,这就是异步,即不是一个时钟线,所以,我们之间会有误差,并且,他看到我恰表的信息也需要时间,这是个小的时间差,但是积累起来足够大的话就是一个位的错误,所以,串口不能连续收发其中不间断,并且一次是8位(也有5,6位),不然会有累计误差。 只是一个例子,希望大家可以更快理解,也可以直接看B站上一个十分不错的课:【讲的太透了!】UART、RS232、RS485、IIC、SPI 5种嵌入式经典总线协议 综上,串口通信差不多简单介绍了一下,接下来是CUBEMX的一般配置。
CUBEMX配置
1.打开CUBEMX,选择你所使用的芯片,我所使用的STM32F103C8T6; 2.点开左边USART,选择异步(Asynchronous),硬件控制流我们不要碰,默认即可; 3.确认一下相关配置 Baud Rate: 波特率, 波特率表示每秒钟传送的码元符号的个数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。对于串口最重要的就是波特率, 常用的波特率为 115200 与 9600。 Wrod Length : 数据长 Parity : 奇偶校验 -> 无、奇校验、偶校验 Stop : 停止位 以上的配置与需要通信双方完全配对 之后如我之前讲的一样上一节传送门
有关函数简介
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData,
uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData,
uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *
pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData
, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *
pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *
pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
我们比较常用前两个,后面带IT是中断,还有DMA这些,之后我会简单说明这些函数如何使用。
|