一、了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解"USB/TTL转232"模块的工作原理。
1.串口通信协议
串口通信协议是一种在计算机和外设之间进行数据传输的协议,它允许数据以位的形式一位接一位地传输。以下是串口通信协议的一些关键点:
(1)通用异步收发器(UART):串口通信协议中最常用的是UART,它是一种串行、异步、全双工的通信协议。UART通信协议中信号线上的状态位高电平代表'1',低电平代表'0'。
(2)数据流和波特率:在串口通信中,数据流由10个数据位组成,包括1位起始位,7位或8位有效数据位,1位奇偶校验位,以及1位停止位。波特率表示一秒内传输的码元数量,常见的波特率有300、1200、2400、9600、19200、38400、115200等
(3)起始位、数据位、奇偶校验位和停止位:
- 起始位:通信线路上空闲时为“1”,当检测到“0”即下降沿时,认为数据传输开始。
- 有效数据位:传输开始后传递的需要接收和发送的数据值,可以表示指令或数据。
- 奇偶校验位:用于校验传输数据中“1”的个数为奇数个(奇校验)或偶数个(偶校验)来指示传输数据是否正确。
- 停止位:数据传输结束,传输线恢复常“1”状态。
(4)通信线路:串口通信通常只需要一对传输线就可以实现双向通信,这大大降低了成本,但传送速度较慢。
(5)电平标准:串口通信中常用的电平标准包括TTL电平、RS232电平和RS485电平,它们定义了数据1和数据0的电压表示方式。
(6)通讯接口:常用的串行数据接口有RS232C和RS485/422,这些标准只对接口的电气特性做出规定,而不涉及接插件、电缆或协议。
(7)通讯方式:串口通信可以是单工、半双工或全双工模式,其中全双工模式允许数据同时双向传输。
(8)自定义协议:在某些应用中,用户可以根据自己的需要定义串口通信协议,包括帧头、长度、指令、数据和校验码等。
(9)工作方式:分为轮询方式、中断方式、DMA方式;
这些是串口通信协议的基本组成部分和概念,它们构成了串口通信的基础,使得不同的设备能够通过串口进行有效的数据交换。
2.RS-232标准
- 是一种标准的串口通信协议。
- 定义了数据传输的电压范围、信号线功能、连接方式和传输速率等。
3.RS-232电平和TTL电平区别
RS-232电平和TTL电平是两种不同的电气信号电平标准,它们在电压范围、逻辑方式、传输距离和应用场景等方面有所区别:
(1)信号电压范围:
- RS-232电平:使用负逻辑,逻辑1(高电平)为-3V至-15V,逻辑0(低电平)为+3V至+15V。
- TTL电平:使用正逻辑,逻辑1(高电平)为2.0V至5.0V,逻辑0(低电平)为0V至0.8V。
(2) 信号逻辑方式:
- RS-232:负逻辑,即负电压表示逻辑高电平,正电压表示逻辑低电平。
- TTL:正逻辑,即高电压表示逻辑高电平,低电压表示逻辑低电平。
(3) 传输距离:
- RS-232:由于电压范围较宽,抗干扰能力强,传输距离可以达到15米甚至更远。
- TTL:由于电压范围窄,抗干扰能力较弱,通常适合几十厘米到几米内的短距离通信。
(4) 接口形式:
- RS-232:常见接口为DB9或DB25(9针或25针连接器)。
- TTL:没有标准化的接口形式,通常使用排针、杜邦线等简单连接方式。
(5) 应用场景:
- RS-232:常用于串口通信,如电脑与外设(打印机、调制解调器等)的通信,以及工业控制设备。
- TTL:常用于嵌入式设备的通信,如单片机与传感器、模块(GPS、Wi-Fi模块等)的通信。
(6) 转换需求:由于RS-232和TTL的电平不兼容,因此需要使用电平转换器进行信号转换,例如MAX232模块。
4.USB/TTL转232模块(以CH340芯片模块为例)的工作原理
- 功能:实现TTL或RS-232与USB之间的转换。
- 转换方式:内部电路将USB数据转换为串口数据或反之。
- 控制器:内部包含芯片控制器,负责数据转换的协调工作。
二. 串口传输文件的实验
将两台笔记本电脑,借助 USB/TTL转RS232 模块和杜邦线,建立起串口连接。然后用串口助手等工具软件(如sscom,带文件传输功能)将一台笔记本上的一个大文件(图片、视频和压缩包软件)传输到另外一台电脑。
- 预估文件大小、波特率和传输时间三者之间的关系,并对比实际传输时间。
- 如果只接TX--RX, RX--TX 这样两根线,不接电源线或者不接GND地线,文件传输是否还能正常工作?请解释原因。
1 .首先我们需要两台电脑,两台电脑都需要安装好串口助手用于发送和接收文件。
这里使用的是XCOM
2.将两个线用杜邦线正确连接,这里将TXD连接RXD,RXD连接TXD,5V连接5V,GND连接GND。
3.连接到两台计算机后,在两台电脑上都打开串口助手进行发送文件,这里选择了一张图片:
三、串口通信实验
安装 stm32CubeMX,配合Keil,使用HAL库(或标准库)方式,设置USART1 波特率为115200,1位停止位,无校验位,完成下列任务:
- STM32系统给上位机(win10)连续发送“hello windows!”,win10采用“串口助手”工具接收。如果STM32的连续发送之间不加延时语句,观察win10端是否出现接收数据丢失的现象。
- 在完成以上任务基础,继续扩展功能:当上位机给stm32发送一个字符“#”后,stm32暂停发送“hello windows!”;发送一个字符“*”后,stm32继续发送;
硬件原理图:
1.所需设备
STM32F103C8T6最小核心板;USB转TTL;CH340驱动(USB串口驱动)_XP_WIN7共用
串口调试助手XCOM V2.3
2. USB转TTL与STM32F103C8T6相连
连接方式如下:
USB转TTL <-----> STM32F103C8T6
GND <-----> G
3V3 <-----> 3V3
RXD <-----> PA9
TXD <-----> PA10
3.编写代码
(1)STM32CubeMx创建项目
通过STM32CubeMx创建新工程,点击左上角的File文件选择“New Project”,在弹出的界面中,下拉列表输入芯片名称“STM32F103C8T6”,右下角选中后,点击“Start Project”,界面如下:
配置“RCC”,RCC中, HSE选中"Crystal/Ceramic Resonator"项,LSE选择Disable。
添加了一个LED指示灯,在进行串口通信时,可以通过这个指示灯判断是否在进行通信传输,引脚选择A4,GPIO配置如下:
接着配置USART1,选择USART1进行传输,将串口设置为异步工作模式
点击Clock Configuration 选择HSE和PLLCLK
设置Project Manager,这里特别注意,代码的生成路径不要有中文,点击“Code Generator”,勾选图示内容,再点击右上角"GENERATE CODE",生成文件。
(2)keil编写程序
先用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);
//高电平点亮A4
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
HAL_Delay(1000);
//低电平熄灭A4
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,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);
//高电平点亮A4
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
//低电平熄灭A4
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
/* USER CODE BEGIN 3 */
}
然后进行编译,生成.hex文件。
(3)串口烧录
安装FlyMcu
链接:单片机在线编程网
双击点开“FlyMcu”,然后把MCU的boot0置1,boot1置0,接线时注意TXD->A10;
RXD->A9;3V3->3V3;GND->G开始烧录代码。
下载完成后,打开串口助手,此时BOOT0置0,BOOT1置1。
4.串口显示结果
有延时:
串口1
无延时:
串口2
可以看到,如果STM32的连续发送之间不加延时语句,上位机出现接收数据丢失的现象。
5.查询中断
(1)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",生成文件
(2)keil代码
先用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开始烧录代码
使用的是野火多功能调试助手进行调试,打开串口助手,此时BOOT0置0,BOOT1置1,
(3)实验效果
串口3
四、学习STM32中断、DMA通信原理和编程方法
使用stm32tubemx和HAL库分别完成以下编程练习:
- 采用串口中断方式重做上面任务三(2)的串口通信实验。
- STM32采用串口DMA方式,用115200bps或更高速率向上位机连续发送数据。
1.串口中断方式
(1)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进行传输,将串口设置为异步工作模式,然后设置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);
}
然后开始编译,生成.hex文件,串口烧录:双击点开“FlyMcu”,然后把MCU的boot0置1,boot1置0,接线时注意TXD->A10;RXD->A9;3V3->3V3;GND->G开始烧录代码
(3)效果展示
串口4
2.DMA
DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作,DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。
(1)STM32CubeMX配置项目
使用CubeMX创建项目File
-New Project,
选择芯片STM32F103C8T6
RCC配置时钟和SYS配置,点击Clock Configuration 选择HSE和PLLCLK
选择USRAT1为异步通信模式,配置串口和NVIV以及DMA
设置Project Manager,这里特别注意,代码的生成路径不要有中文,点击“Code Generator”,勾选图示内容,再点击右上角"GENERATE CODE",生成文件
(2)keil代码
在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开始烧录代码
(3)效果展示
串口5
五、在没有示波器条件下,可以使用Keil的软件仿真逻辑分析仪功能观察任务二(1)串口输出波形,并分析时序状态正确与否,计算波特率实际为多少。
1.首先设置Debug,具体配置如下。
使用keil逻辑分析仪,配置要观察的引脚。
USB1输出设置,然后观察输出波形:
六、实验心得
通过这些实验,我更加深刻地理解了串口通信的理论知识。从RS-232标准到实际的硬件连接,再到软件编程,每一个环节都是对理论知识的实际应用。这种从理论到实践的过程,不仅加深了我对串口通信原理的理解,也提高了我解决实际问题的能力。在实验中,我意识到正确的硬件连接对于串口通信的成功至关重要。特别是在连接电源线和地线时,如果不接电源线或不接GND地线,文件传输将无法正常工作,因为这样无法形成完整的电路,设备之间无法正确地传输信号。这一点在实验中得到了明确的验证。通过预估和实际测量文件传输时间,我对波特率、文件大小和传输时间三者之间的关系有了更直观的认识。实验表明,实际传输时间往往比理论计算的要长,这可能是由于传输过程中的延迟和错误校正等因素造成的。这个发现让我意识到在实际应用中,理论计算只能作为一个参考,实际测试才是最终的验证手段。在STM32的编程实践中,我遇到了一些挑战,比如如何正确设置波特率、如何通过串口助手接收数据等。通过查阅资料和不断调试,我逐渐掌握了HAL库的使用,也学会了如何通过编程来控制STM32的行为。这个过程锻炼了我的编程能力和问题解决能力。
参考博客:
一. 了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解USBTTL转232模块(以CH340芯片模块为例)的工作原理。_ttl 转232-CSDN博客
两台电脑之间实现串口通信_两台电脑通过串口进行通信-CSDN博客
【嵌入式知识08】STM32的USART串口通信,给上位机连续发送Hello Windows!_stm32串口发送数据给上位机-CSDN博客