STM32串口通信
一、串口通信的基本原理
1.串口协议和RS-232标准
(1)串口协议
串口是显控设备与信号处理板之间通信的主要接口,也是显控设备与其他设备、设备与设备之间的协议数据帧通信传输的重要接口。串口通信指串口按位(bit)发送和接收字节。尽管比特字节(byte)的串行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。
串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。串口通信协议是基于串口使得通信双方能够相互沟通信息的一种约定,其定义了双方遵循的协议数据帧格式和其传输方式。
在串口通信中,常用的协议包括RS-232、RS-422和RS-485。
(2)RS-232标准
RS-232标准接口(又称EIA RS-232)是常用的串行通信接口标准之一,它是由美国电子工业协会(Electronic Industry Association,EIA)联合贝尔系统公司、调制解调器厂家及计算机终端生产厂家于1970年共同制定,其全名是“数据终端设备( DTE)和数据通信设备(DCE)之间串行二进制数据交换接口技术标准”。RS-232为异步串行通信接口, 其电气标准采用负逻辑,不 能与TTL电平设备直接相连, 而微控制器中的UART采用的 是TTL电平标准,因此,RS- 232与微控制器相连时必须进行电平转换。
2.RS232电平与TTL电平
(1)RS232电平
RS-232电平是串行通信接口中的一种电气标准,它定义了数据通信设备之间的电气特性、连接器类型、数据格式等规范。
a.逻辑1(MARK):电压范围在-3V至-15V之间。
b.逻辑0(SPACE):电压范围在+3V至+15V之间。
逻辑电平与TTL电平的转换:RS-232与TTL(晶体管-晶体管逻辑)电平标准不同。TTL电平通常使用0V至5V的电压表示逻辑状态,其中高电平通常为2.4V至5V,低电平为0V至0.8V。因此,在将RS-232信号与TTL设备连接时,需要进行电平转换。
应用:RS-232广泛应用于计算机与外部设备之间的通信,如打印机、鼠标、键盘等。
(2)TTL电平
a.TTL:输出高电平>2.4V,低电平<0.4V;输入高电平>=2.0V,输入低电平<=0.8V,噪声容限是0.4V;全双工 (5V系统,逻辑1: 2.4V–5V 逻辑0: 0V–0.5V)。
b.TTL指双极型三极管逻辑电路,市面上很多“USB转TTL”模块,实际上是“USB转TTL电平的串口”模块。这种信号0对应0V,1对应3.3V或者5V,与单片机、SOC的IO电平兼容。我们进行串口通信的时候从单片机直接出来的基本上都是TTL电平。
3."USB/TTL转232"模块的工作原理
(1)CH340的工作原理
CH340是一款常见的USB转串口转换芯片,用于实现USB与串口(如RS-232、RS-485等)之间的通信转换。CH340可以将USB信号转换为TTL电平的串口信号,反之亦然,支持USB 2.0标准,提供高速(12Mbps)、全速(1.5Mbps)和低速(1.2Mbps)三种传输速率;可以驱动一个标准的RS-232电平串口,并且具有自动波特率检测功能。在嵌入式系统中,CH340常用于将USB接口转换为串口,以便与计算机或其他串口设备通信,在串口方式下,CH340 提供常用的MODEM联络信号,用于为计算机扩展异步串口,或者将普通的串口设备直接升级到USB 总线。在红外方式下,CH340 外加红外收发器即可构成USB 红外线适配器,实现SIR 红外线通讯。
(2)USB转RS-232
USB转RS-232是指将USB(通用串行总线)接口转换为RS-232接口的转换过程。这种转换允许原本通过USB接口连接的设备(如计算机、平板电脑、智能手机等)与使用RS-232协议的设备(如串口打印机、工业设备、老式电脑等)进行通信,USB转串口模块可以使用5V、3V3电压供电,需要将跳线帽进行安装,对USB转串口模块进行测试,将USB的电压引脚用跳帽接上,然后将RXD和TXD两个引脚用跳帽或者杜邦线接上。
二.串口通信实验1——文件互传
1.实验要求
将两台笔记本电脑,借助 USB/TTL转RS232 模块和杜邦线,建立起串口连接。然后用串口助手等工具软件(如sscom,带文件传输功能)将一台笔记本上的一个大文件(图片、视频和压缩包软件)传输到另外一台电脑。
(1)预估文件大小、波特率和传输时间三者之间的关系,并对比实际传输时间。
(2)如果只接TX–RX, RX–TX 这样两根线,不接电源线或者不接GND地线,文件传输是否还能正常工作?请解释原因。
2.实验过程
(1)首先需要两台电脑,并且两台电脑上都下载好串口调试助手(我们选用的是XCOM V2.6),方便二者发送和接收文件,使用两个USB转TTL模块连接这两台电脑,模块之间需要将TXD连接RXD,RXD连接TXD,3.3V连接3.3V,GND连接GND,具体接线图如下所示:
然后打开串口调试助手(SSCOM–V5.13.1版本)
发送机选择要发送的文件,发送机发送的图片如下所示:
设置波特率为115200,点击发送文件,传输完成后的界面如下:传输界面如下:
如图看到预计的传输时间大约是9.4多秒。
(2)接收机界面如下:
文件接收正确!
3.实验分析
(1)理论可知:传输时间=(文件大小*8)/波特率,选择接收机接收到的图片属性:
由于:182KB=182×1024×8=1490944位,波特率=115200位/s。带入公式可得:
理论时间= 1490944位/115200位/秒,约等于:12.942秒!
(2)对比实际传输时间“ 16.728s”,可知理论传输时间要小于实际传输时间。分析原因是在传输过程其中插入了一些延时,或者是传输过程中出错导致。
(3)如果只接 TX - RX 和 RX - TX 两根线,不接电源线,文件传输不能正常工作。因为 USB/TTL 转 RS232 模块需要电源来驱动内部电路工作,没有电源供应,模块无法正常将 TTL 电平转换为 RS232 电平,也无法处理和传输数据。
如果不接 GND 地线,文件传输也不能正常工作。因为串口通信是基于差分信号的,GND(地)是参考电位。没有接地,信号就没有了参考电平,接收端无法正确判断信号的高低电平,导致数据传输错误。例如,在 RS232 通信标准中,信号电平范围是相对于 GND 来定义的,正确的接地才能保证发送端发送的信号被接收端正确接收和解析。
三.串口通信实验2——STM32系统给上位机发送“hello windows!”
1.连续发送
(1)实验任务
STM32系统给上位机(win10)连续发送“hello windows!”,win10采用“串口助手”工具接收。如果STM32的连续发送之间不加延时语句,观察win10端是否出现接收数据丢失的现象。
(2)STM32CubeMx创建项目
.通过STM32CubeMx创建新工程,点击左上角的File文件选择“New Project”,在弹出的界面中,下拉列表输入芯片名称“STM32F103C8T6”,右下角选中后,点击“Start Project”,界面如下:
配置“RCC”,RCC中, HSE选中"Crystal/Ceramic Resonator"项,LSE选择Disable,界面如下:
配置“SYS”,下拉Debug模式 ,选中"Serial Wire"Timebase Source选择“SysTick”,界面如下:
这里我添加了一个LED指示灯,在进行串口通信时,可以通过这个指示灯判断是否在进行通信传输,引脚选择A1,GPIO配置如下:
接着配置USART1,选择USART1进行传输,将串口设置为异步工作模式,
点击Clock Configuration 选择HSE和PLLCLK,
设置Project Manager,这里特别注意,代码的生成路径不要有中文,点击“Code Generator”,勾选图示内容,再点击右上角"GENERATE CODE",生成文件。
(3)实验过程
a.先用keil打开工程后,找到main.c文件,在while(1)中添加如下代码内容
有延时语句:
while (1)
{
/* USER CODE END WHILE */
char data[]="hello windows!\n";
HAL_UART_Transmit(&huart1, (uint8_t *)data, 15, 0xffff);
//高电平点亮A1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
HAL_Delay(1000);
//低电平熄灭A1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
无延时
while (1)
{
/* USER CODE END WHILE */
char data[]="hello windows!\n";
HAL_UART_Transmit(&huart1, (uint8_t *)data, 15, 0xffff);
//高电平点亮A1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
//低电平熄灭A1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
/* USER CODE BEGIN 3 */
}
b.然后进行编译,生成.hex文件
实物连接图
c.串口烧录:双击点开“FlyMcu”,然后把MCU的boot0置1,boot1置0,接线时注意TXD->A10;
RXD->A9;3V3->3V3;GND->G开始烧录代码。
串口显示结果下:
a:有延时语句时:
有延时
串口显示1(无中断)
b:无延时语句时:
无延时
串口显示(无延时)
可以看到,如果STM32的连续发送之间不加延时语句,上位机出现接收数据丢失的现象。
传输时,A1会亮,如视频所示
灯
(5)使用软件仿真逻辑分析仪功能观察串口输出波形
首先设置Debug,具体配置如图所示:
使用keil逻辑分析仪,配置要观察的引脚:
USB1输出设置,然后观察输出波形:
2.查询中断
(1)实验任务
在连续发送的基础,继续扩展功能:当上位机给stm32发送一个字符“#”后,stm32暂停发送“hello windows!”;发送一个字符“*”后,stm32继续发送。
(2)STM32CubeMx创建项目
通过STM32CubeMx创建新工程,点击左上角的File文件选择“New Project”,在弹出的界面中,下拉列表输入芯片名称“STM32F103C8T6”,右下角选中后,点击“Start Project”,
配置“RCC”,RCC中, HSE选中"Crystal/Ceramic Resonator"项,LSE选择Disable
配置“SYS”,下拉Debug模式 ,选中"Serial Wire"Timebase Source选择“SysTick”
接着配置USART1,选择USART1进行传输,将串口设置为异步工作模式,
点击Clock Configuration 选择HSE和PLLCLK,
设置Project Manager,这里特别注意,代码的生成路径不要有中文,点击“Code Generator”,勾选图示内容,再点击右上角"GENERATE CODE",生成文件
最后用Keil打开新建的HAL库工程:
(3)实验过程
先用keil打开工程后,找到main.c文件在主函数中添加如下代码内容:
uint8_t receivedChar;
if (HAL_UART_Receive(&huart1, &receivedChar, 1, 0xffff) == HAL_OK)
{
switch (receivedChar)
{
case '#': // Pause sending message
HAL_UART_Transmit(&huart1, (uint8_t *)"stop", 16 , 0xffff);
break;
case '*': // Resume sending message
HAL_UART_Transmit(&huart1, (uint8_t *)"hello windows!\r\n", 16 , 0xffff);
HAL_Delay(1000);
break;
default: // Continue sending message
HAL_UART_Transmit(&huart1, (uint8_t *)"hello windows!\r\n", 16 , 0xffff);
HAL_Delay(1000);
break;
}
}
然后在while(1)添加如下代码:
HAL_UART_Transmit(&huart1, (uint8_t *)"hello windows!\r\n", 16 , 0xffff);
HAL_Delay(1000);
然后进行编译,生成.hex文件,串口烧录:双击点开“FlyMcu”,然后把MCU的boot0置1,boot1置0,接线时注意TXD->A10;RXD->A9;3V3->3V3;GND->G开始烧录代码;
(4)输出效果展示
我这里用的是XCOM V2.6
中断1
四.串口通信实验三——串口中断
通过STM32CubeMx创建新工程,点击左上角的File文件选择“New Project”,在弹出的界面中,下拉列表输入芯片名称“STM32F103C8T6”,右下角选中后,点击“Start Project”,
配置“RCC”,RCC中, HSE选中"Crystal/Ceramic Resonator"项,LSE选择Disable,
配置“SYS”,下拉Debug模式 ,选中"Serial Wire"Timebase Source选择“SysTick”,
配置USART1,选择USART1进行传输,将串口设置为异步工作模式,然后设置NVIC;
设置Project Manager,这里特别注意,代码的生成路径不要有中文,点击“Code Generator”,勾选图示内容,再点击右上角"GENERATE CODE",生成文件,
2.用keil编写相关代码
用Keil打开新建的HAL库工程:首先在main函数前定义全局变量,具体代码如下:
char c;//指令 0:停止 1:开始
char message[]="hello Windows\n";//输出信息
char tips[]="CommandError\n";//提示1
char tips1[]="Start.....\n";//提示2
char tips2[]="Stop......\n";//提示3
int flag=0;//标志 0:停止发送 1.开始发送
然后在while循环里面添加传输代码:
if(flag==1)
{
//发送信息
HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF);
//延时
HAL_Delay(1000);
}
最后重写中断处理函数HAL_UART_RxCpltCallback():
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//当输入的指令为0时,发送提示并改变flag
if(c=='0'){
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF);
}
//当输入的指令为1时,发送提示并改变flag
else if(c=='1'){
flag=1;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF);
}
//当输入不存在指令时,发送提示并改变flag
else {
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF);
}
//重新设置中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
}
3.代码的编译和烧录
然后开始编译,生成.hex文件,串口烧录:双击点开“FlyMcu”,然后把MCU的boot0置1,boot1置0,接线时注意TXD->A10;RXD->A9;3V3->3V3;GND->G开始烧录代码;
4.串口中断效果展示
当发送1后可以看到不断输出“hello Windows",.当输入0后端口停止输出
中断2
五.串口通信实验四——DMA
1.DMA基本原理
DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作,DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。DMA所需要的核心参数:
a.数据的源地址 。
b.数据传输位置的目标地址。
c.传递数据多少的数据传输量。
d.进行多少次传输的传输模式 。
2.1STM32CubeMX配置项目
使用CubeMX创建项目File-New Project,选择芯片STM32F103C8T6,
RCC配置时钟和SYS配置,点击Clock Configuration 选择HSE和PLLCLK,
选择USRAT1为异步通信模式,配置串口和NVIV以及DMA,
设置Project Manager,这里特别注意,代码的生成路径不要有中文,点击“Code Generator”,勾选图示内容,再点击右上角"GENERATE CODE",生成文件,
3.用keil编写相关代码并编译
用keil打开工程,然后找到main.c函数
在while(1)循环完整函数如下:
uint8_t data[] = "Congratulation birdy,DMA test successful\r\n";
HAL_UART_Transmit_DMA(&huart1,(uint8_t *)data,30);
HAL_Delay(1000); //
然后开始编译,生成.hex文件,串口烧录:双击点开“FlyMcu”,然后把MCU的boot0置1,boot1置0,接线时注意TXD->A10;RXD->A9;3V3->3V3;GND->G开始烧录代码;
4.DMA效果展示
DMA
六.总结
(一)理论知识层面
串口协议与标准
详细了解了串口协议的基本架构和数据传输规则,RS - 232 标准作为经典的串口通信标准,其电平范围、电气特性以及连接规范等知识为实际操作提供了重要依据。明确了 RS232 电平与 TTL 电平在电压范围上的差异,RS232 采用负逻辑,其电平范围较宽,适用于长距离传输但需要专门的转换芯片与设备连接;而 TTL 电平则是正逻辑,常用于芯片间短距离通信,这使得在构建串口连接时能根据需求合理选择合适的电平转换模块。
以 CH340 芯片为例的 “USB/TTL 转 232” 模块工作原理的学习,让我明白了它在实现不同接口类型转换过程中的关键作用,包括对数据格式的转换、电平的适配以及与计算机操作系统的通信协调等方面,这是实现串口通信的重要硬件基础。
STM32 串口相关知识
对于 STM32 的串口通信,掌握了 USART1 的参数设置,如波特率、停止位、校验位等概念及其对数据传输的影响。波特率决定了数据传输的速度,不同的应用场景需要根据设备性能和通信要求合理选择波特率;停止位用于标识数据字节的结束,校验位则可用于检测数据传输过程中的错误,这些参数的正确设置是确保串口通信稳定可靠的关键因素。
深入学习了 STM32 中断和 DMA 通信原理。中断机制允许 STM32 在串口数据传输过程中及时响应特定事件,如接收数据就绪或发送完成等,从而提高系统的实时性和响应能力;DMA 通信则通过直接内存访问方式,减少了 CPU 在数据传输过程中的干预,提高了数据传输效率,尤其适用于大数据量的快速传输场景,如高速串口数据采集或连续数据发送等应用。
(二)实践操作层面
串口传输文件实验
成功完成了两台笔记本电脑间借助 USB/TTL 转 RS232 模块和杜邦线的串口连接,并使用串口助手软件进行大文件传输。在这个过程中,不仅熟悉了硬件连接的步骤和要点,确保各线路连接正确且稳固,还学会了使用串口助手软件进行参数设置和文件传输操作。通过预估文件大小、波特率与传输时间的关系,并与实际传输时间对比,深入理解了串口通信在实际应用中的传输效率受多种因素影响,如起始位、停止位、校验位以及线路干扰等,这为今后优化串口传输性能提供了实践经验。
针对不完整线路连接(仅接 TX - RX、RX - TX 两根线,不接电源线或 GND 地线)的测试,明确了电源线和 GND 地线在串口通信中的不可或缺性。电源线为模块提供工作电源,GND 地线作为信号参考电平,缺少任何一个都会导致通信失败,进一步加深了对串口通信电气连接完整性的认识。
STM32 串口通信编程实践
安装并熟练使用 stm32CubeMX 和 Keil 软件,运用 HAL 库(或标准库)完成了一系列串口通信编程任务。在设置 USART1 参数后,实现了 STM32 向 win10 上位机的连续数据发送,并通过实验观察到发送速率与上位机接收处理能力不匹配时会出现数据丢失现象,从而学会了在编程中合理控制数据发送节奏,如添加适当的延时语句来平衡数据传输速率。
在功能扩展方面,成功实现了根据上位机发送的特定字符 “#” 和 “*” 来控制 STM32 的发送状态,这涉及到串口接收中断的处理和程序逻辑的设计,提高了对 STM32 串口通信交互性编程的能力,能够根据实际需求灵活设计串口通信的功能逻辑。
STM32 中断与 DMA 通信编程实践
采用串口中断方式完成了串口通信实验,深入理解了中断服务程序的编写规范和在串口通信中的应用流程。通过中断方式,能够及时响应上位机的指令并对 STM32 的发送行为进行精确控制,提高了系统的灵活性和实时性。
运用串口 DMA 方式实现了高速数据发送,掌握了 DMA 通道的配置、数据缓冲区的设置以及启动和停止 DMA 传输的编程方法。通过实际测试不同波特率下的 DMA 传输效果,进一步了解了 DMA 在提高数据传输效率方面的优势,能够在需要高速数据传输的项目中合理运用 DMA 技术。
软件仿真逻辑分析仪功能应用
在没有示波器的情况下,学会了使用 Keil 的软件仿真逻辑分析仪功能对串口输出波形进行观察和分析。通过设置相关参数,能够准确捕获串口数据的时序状态,计算实际波特率,并与预设波特率进行对比,从而判断串口通信的准确性和稳定性。这一功能为在硬件资源有限的环境下进行串口通信调试提供了一种有效的手段,拓宽了串口通信调试的方法和途径。
心得体会
(一)知识融合与拓展
串口通信的学习涉及到多方面知识的融合,从电子电路的电平转换、接口标准,到微控制器的编程设置以及软件工具的使用等。这种综合性的学习让我深刻体会到电子信息技术领域各个知识点之间的紧密联系,只有全面掌握相关知识,才能更好地理解和应用串口通信技术。同时,在学习过程中通过参考大量的博客、文章和文档,不仅加深了对串口通信本身的理解,还拓展了对 STM32 微控制器其他功能模块以及相关软件开发工具的认识,为今后进一步深入学习和研究嵌入式系统开发奠定了更广泛的知识基础。
(二)实践出真知
理论知识固然重要,但实践操作才是真正将知识转化为技能的关键。在串口传输文件实验、STM32 串口通信编程以及相关功能扩展和调试过程中,遇到了各种各样的问题,如硬件连接不稳定导致通信故障、软件参数设置错误导致数据传输异常、编程逻辑错误导致功能无法实现等。通过不断地排查问题、查阅资料、尝试不同的解决方案,最终成功解决问题,使我在实践中积累了宝贵的经验,提高了自己的动手能力和问题解决能力。每一次成功的实践操作都让我对串口通信的理解更加深刻,也让我更加坚信只有通过实践才能真正掌握一门技术。
(三)耐心与细心的重要性
串口通信涉及到众多的参数设置、线路连接和编程细节,任何一个小的疏忽都可能导致整个通信系统无法正常工作。在学习过程中,我深刻体会到耐心和细心的重要性。无论是在硬件连接时仔细检查每一根杜邦线的连接是否正确,还是在软件编程时认真核对每一个参数的设置和代码的逻辑,都需要保持高度的专注和耐心。只有这样,才能避免因粗心大意而产生的错误,提高工作效率,确保串口通信系统的稳定可靠运行。
总之,本次串口通信的学习是一次充实而富有挑战的经历,通过理论与实践的紧密结合,我不仅掌握了串口通信的核心技术,还在知识融合、实践能力、耐心细心以及学习方法等方面得到了全面的锻炼和提升。这些收获将对我今后在电子信息技术领域的学习和工作产生积极而深远的影响,也激励我在未来继续努力学习,不断探索和掌握更多的前沿技术。