网站搭建哪家好,wordpress 修改文件名,wordpress如何写个插件,中国市政建设局网站文章目录 前言1. 接口概述1.1 USART/UART接口1.2 串口通信参数1.3 波特率计算 2. 传输函数3. 回环测试3.1 上位机环境配置3.2 阻塞模式3.3 中断模式 4. STM32CubeMX配置4.1 时钟配置4.2 调试配置4.3 串口引脚配置4.4 工程配置 5. 测试效果6. 不借助上位机回环测试总结 前言
这… 文章目录 前言1. 接口概述1.1 USART/UART接口1.2 串口通信参数1.3 波特率计算 2. 传输函数3. 回环测试3.1 上位机环境配置3.2 阻塞模式3.3 中断模式 4. STM32CubeMX配置4.1 时钟配置4.2 调试配置4.3 串口引脚配置4.4 工程配置 5. 测试效果6. 不借助上位机回环测试总结 前言
这篇博客从串口通信的接口讲起阐述原理介绍通信方式最后上机测试。 本篇博客主要以异步通信为例。 1. 接口概述
串口分为很多种我们STM32学习过程中常见的就是UART/USART前者是同步模式后者是异步模式。还有RS485,RS232这种也是串口。我们平常使用的串口模块大多都是类似于USB转TTL模块为什么叫USB转TTL而不是USB转串口因为MCU上的串口是逻辑电平TTL或者CMOS电平MCU和模块的通信通过逻辑电平的串口信号线直接连接。所以两种叫法后者包含前者。前者更为常用。
1.1 USART/UART接口
下面是USART/UART对应的一般接口图 各个引脚说明如下 请注意各个箭头方向。
引脚标识引脚含义备注TX串行输出信号MCU向对方设备发送数据RX串行输入信号MCU接收对方设备发送的数据nCTS允许发送信号低电平有效是对方设备发来的信号。如果nCTS为低电平则表示对方设备准备好了接受数据本机可以发送数据了否则不能发送数据。nRTS请求发送信号低电平有效是发送给给对方设备的一个信号。如果本机准备好了接受数据则将nRTS置为低电平通知对方设备可以发送数据了SCLK发送器输出的时钟信号时钟信号线仅用于同步模式USART没有这个引脚UART有。
上面的图和表是串口最全的情况是带有硬件流控制同时又是同步模式的情况。 其实一般我们使用异步模式并且没有硬件流控制。所以上面的5个引脚最常用的只有RX,TX。 拿USB转TTL模块来举例我们只需要接RX,TX,GND,VCC四个脚就行。这里RX和TX注意要交叉接主机的TX接从机的RX从机的TX接主机的RX。这个也很好理解就是数据发送与接收的方向。 1.2 串口通信参数
串口发送数据是以数据帧的方式发送数据下图是以传输一个8为字长的数据帧的时序图。
参数说明 数据位8位/9位一般设置为8位即8bit即1byte。这样一帧传输1字节的有效数据。 奇偶校验位可以无奇偶校验位也可以设置奇校验或者偶校验。 停止位1个或者2个停止位一般设置为1个停止位。 波特率串行数据传输的速率单位是bit/s常用的波特率有9600、19200、115200等。最高波特率的计算是根据时钟来的。一个串口单元的时钟由APB1或APB2总线提供所以挂在不同APB总线上的串口单元的最高波特率不同。
1.3 波特率计算 波特率 时钟频率 ( UART的分频因子 × 过采样次数 ) \text{波特率} \frac{\text{时钟频率}}{(\text{UART的分频因子} \times \text{过采样次数})} 波特率(UART的分频因子×过采样次数)时钟频率
分频因子我查了一下使用STM32CubeMX似乎是自动配置的我就没有管了。 不过手动配置多少的话可以算。 比如波特率115200时钟频率100MHz过采样次数16 算出来的UART的分频因子大约为54.2534四舍五入到最近的整数。即54 2. 传输函数
这一小节主要介绍一下串口传输数据的三种方式对应的函数
传输类别函数名功能说明阻塞式传输HAL_UART_Transmit()阻塞方式发送一个缓冲区的数据发送完成或超时后才返回HAL_UART_Receive()阻塞方式将数据接收到一个缓冲区接收完成或擦手后才返回中断方式传输HAL_UART_Transmit_IT()以中断方式(非阻塞式)发送一个缓冲区的数据HAL_UART_Receive_IT()以中断方式(非阻塞方式)将指定长度的数据接收到一个缓冲区DMA方式传输HAL_UART_Transmit_DMA()以DMA方式发送一个缓冲区数据HAL_UART_Receive_DMA()以DMA方式将指定长度的数据接收到缓冲区HAL_UART_DMAPause()暂停DMA传输过程HAL_UART_DMAResume()继续先前暂停的DMA传输过程HAL_UART_DMAStop停止DMA传输过程
上表中我只列举了函数名称对于其中的参数并没有详细介绍具体参数可以参考对应的驱动文件。 3. 回环测试
简单的回环测试先接收上位机PC用XCOM发来的信息再把数据发回去。
3.1 上位机环境配置
使用的是CH340安装驱动。 如果出现预安装成功但是你用USB接开发板之后没反应不妨换一根数据线我这里踩坑饿了有些垃圾数据线不支持协议。
XCOM的话点击就能用主要是上下位机的波特率要一致。 3.2 阻塞模式
使用到的函数为 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, const uint8_t *pData, uint16_t Size, uint32_t Timeout) 函数对应的参数说明如下 UART_HandleTypeDef *huart 串口响应对象 const uint8_t *pData发送/接受的数据 uint16_t Size发送/接收数据的大小 uint32_t Timeout发送或接收数据超时时间。超时后结束函数。
测试代码
uint8_t testBuf[5]hello;
uint8_t receiveBuf[20]{0};
while (1){ if(HAL_UART_Receive(huart1,receiveBuf,sizeof(testBuf),100)HAL_OK) {HAL_UART_Transmit(huart1,receiveBuf,sizeof(testBuf),100);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}3.3 中断模式
使用到的函数为 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) 函数对应的参数说明如下 UART_HandleTypeDef *huart 串口响应对象 uint8_t *pData发送/接受的数据 uint16_t Size发送/接收数据的大小
测试代码
uint8_t testBuf[5]hello;
uint8_t receiveBuf[20]{0};
while (1){ if(HAL_UART_Receive_IT(huart1,receiveBuf,sizeof(testBuf))HAL_OK) {HAL_UART_Transmit_IT(huart1,receiveBuf,sizeof(testBuf));}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}4. STM32CubeMX配置
4.1 时钟配置 4.2 调试配置 4.3 串口引脚配置 开启中断 4.4 工程配置 5. 测试效果
使用中断还是阻塞在这个回环测试都一个效果。
6. 不借助上位机回环测试
原始版本这个代码和上面的很类似不同的地方在于硬件的连接。
uint8_t testBuf[5]hello;
uint8_t receiveBuf[20]{0};
while (1){HAL_UART_Transmit(huart1,testBuf,sizeof(testBuf),100);HAL_UART_Receive(huart1,receiveBuf,sizeof(testBuf),100);
}我这里将STM32F407ZET6的TX1直接接到RX1上了按道理来说这样的效果使用debug来看的话receiveBuf接收到的值应该是hello但是实际效果却不是这样的我用debug来看得到的数据却一直是h。后面的数据根本过不来。我一开始以为是发送需要时间我没给延时后来给了延时也是一样的效果。
按照显示的现象我修改了部分代码
for(int i0;isizeof(testBuf);i)
{HAL_UART_Transmit(huart1,testBufi,sizeof(testBuf),100);HAL_UART_Receive(huart1,receiveBufi,sizeof(testBuf),100);
}改完后再用debug来看发现数据正常了。
一直不太明白为什么目前自己暂时认为GPIO脚一次只能接受1bit数据虽然每次发送了5个数据但是只能收一个数据这就导致只能收到h这个数据。 后来用了个for循环其实就是多次发送每次接受不同位置的数据达到我们最终想要的效果。 总结
这个平时用的时候没有遇到第六小节的情况因为都是借助上位机以及对应的USB转TTL做的测试。只关注了波特率校验位等配置。没有过多考虑TX直接RX这种情况。这次出现的问题还有待确切的答案暂时只能先这样认定。