请保留-> 【原文: https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
(代码仓库地址:https://gitee.com/luobing4365/yie002-explorer
具体参考博客:YIE002开发探索-Gitee代码仓库说明)
串口是相当的古老的接口,大概率比看这篇博客的读者早出生。常用的串口标准RS-232标准是EIA(美国电子工业联合会)和贝尔公司,于1969年公布的。它比较适合数据传输率在20000bit/s内的通讯,标准对信号线功能、电气特性都有明确规定。
常用的串口,包括RS232、TTL232、RS485和RS422标准。不过从软件协议上来看,RS232和TTL232是一样的 ,其区别主要在于硬件。
从硬件的电平上来看,TTL232使用+5V/+3.3V电平表示逻辑“1”,0V电平表示逻辑“0”;RS232则用-3V至-15V表示逻辑“1”,+3V至+15V表示逻辑“0”,也即采用负逻辑来表示。
如表1所示,给出了RS232、RS485和RS422的区别。
表1 串口标准
通信标准 | 电平标准 | 通信距离 | 通信方式 | 信号 |
---|---|---|---|---|
RS232 | 逻辑1: -15V至-3V 逻辑0: 3V至15V | 15米 | 全双工 | 单端信号 |
RS485 | 逻辑1: 2V至6V 逻辑0: -6V至-2V | 1200米 | 2线半双工 | 差分信号 |
RS422 | 逻辑1: 2V至6V 逻辑0: -6V至-2V | 1200米 | 4线全双工 | 差分信号 |
在YIE002上,准备了TTL232、RS232和RS485三个串口。考虑到TTL232和RS232软件编写没有区别,准备用几篇的时间,实现TTL232的轮询、中断和DMA编程,以及RS485的编程。
1 STM32的串口
STM32提供的串口资源很丰富,在YIE002-STM32上使用的F103C8T6,提供了3路串口。它们支持全双工异步通信、支持单线半双工通信、智能卡模拟功能、具有DMA等。
STM32的通用同步异步接收器(USART)在进行双向通信时,至少需要两个引脚:接收数据输入(RX)和发送数据输出(TX)。由于可能存在引脚复用,需要注意配置不同模式时的状态。
从软件角度看,串口的设置一般包括以下步骤:
- 串口时钟使能, GPIO 时钟使能;
- 串口复位;
- GPIO 端口模式设置;
- 串口参数初始化,包括波特率、数据位、停止位等;
- 开启中断并且初始化 NVIC(开启中断方式才需要这个步骤);
- 使能串口;
- 编写中断处理函数(中断方式下才需要此步骤)。
可以看出,以之前的GPIO及外部中断编写过程类似。不过串口的使用相对复杂些,编程过程中,最好对USART相关的寄存器有一定的了解,具体可以参考《STM32参考手册》。
Cube Library中,对串口的操作提供较多的API函数,简单罗列如下:
串口的发送接收函数:
HAL_UART_Transmit(); 串口轮询模式发送,使用超时管理机制。
HAL_UART_Receive(); 串口轮询模式接收,使用超时管理机制。
HAL_UART_Transmit_IT();串口中断模式发送,
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Receive_DMA();串口DMA模式接收
串口相关的中断函数:
HAL_UART_TxCpltCallback():发送完成后,通过中断处理函数调用。
HAL_UART_RxCpltCallback():接收完成后,通过中断处理函数调用。
HAL_UART_ErrorCallback():传输过程中出现错误时,通过中断处理函数调用
从我个人的观点来看,这些函数封装得让人比较迷惑,许多的细节不如Legacy Library容易看清。实际的用法,还得在实践中去体会。
2 YIE002-STM32的串口编程(轮询)
拟构建一个比较简单的示例,把从PC机收到的串口数据,再通过串口发送回去。本篇的示例,采用的是主程序中轮询的方式。
2.1 串口的Cube MX图形配置
YIE002-STM32中,串口1被用来实现TTL串口,在板子上提供了插针方便连接。本篇的例子是在上一篇定时器的示例上修改的,只针对串口1进行配置,其余没有改动。
在Pinout&Configuration配置界面上,选择Connectivity下的USART1,对串口1进行配置,如图1所示。
将串口1的模式配置为异步通信,其他保持缺省状态即可。在配置串口1时,在Pinout view(引脚视图)可以看出,PA9被配置为USART1_TX,PA10被配置为USART1_RX了。
选择“GENERATE CODE”按钮,生成代码。
2.2 添加应用代码
在生成的代码中可以发现,主程序main中增加了初始化串口的函数MX_USART1_UART_Init()。也就是说,此时已经可以直接访问串口1了。
主程序的while循环中,添加如下代码,对串口1进行轮询:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//robin 20210801
if(HAL_UART_Receive(&huart1,rUsartData,200,2000) !=HAL_OK)
{
Error_Handler();
}
if(rUsartData[0]!=0)
{
if(HAL_UART_Transmit(&huart1,rUsartData,200,2000) !=HAL_OK) //收到的数据发送出去
{
Error_Handler();
}
}
for(i=0; i<200; i++)
rUsartData[i]=0;
}
/* USER CODE END 3 */
代码逻辑很简单,将收到的数据存储到指定数组中,然后通过串口1返回给PC上位机。所用到的接收函数HAL_UART_Receive()和发送函数HAL_UART_Transmit(),都使用了超时机制,当超过指定时间没有发送完成,则不会再发送,函数返回超时标志。
2.3 测试
将程序编译下载,就可以进行下一步的测试了。
我使用的是FT232的USB转串进行测试的,和开发板的连接如图2所示。
开发板上的GND和USB转串设备的GND连接;两者间的Rx和Tx需要交叉连接。
把USB转串的工具接在PC机上,在PC上打开串口调试助手。设置串口参数为“115200,None,8,1”,指定USB转串设备对应的串口号,打开串口。向YIE002发送任意字符串,字符串将原样返回。
至此,轮询方式的串口通信就完成了。下一篇将尝试使用中断的方式进行串口通信。
906 total views, 1 views today