基于中断/DMA方式的串口通信

了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理。 使用HAL库(或标准库)方式,设置USART1 波特率为115200,1位停止位,无校验位,分别采用中断方式、DMA方式完成下列任务:
STM32系统给上位机(win10)连续发送“hello windows!”;当上位机给stm32发送字符“stop”后,stm32暂停发送“hello windows!”;发送一个字符“start”后,stm32继续发送;
在没有示波器条件下,可以使用Keil的软件仿真逻辑分析仪功能观察串口输出波形,并分析时序状态正确与否,计算波特率实际为多少。

一、串口通信基本知识

了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理。

1.串口协议

串口通信协议就是 串口通讯时共同遵循的协议,其定义了双方遵循的协议 数据帧格式 和其 传输方式。通讯协议分为 物理层和协议层。

  • 物理层:
    规定通讯系统中具有 机械、电子功能部分的特性 ,确保原始数据在 物理媒体 的传输(通俗一点就是硬件部分)。
  • 协议层:
    主要规定 通讯逻辑,统一收发双方的数据打包、解包标准(软件)。协议的内容是 每一个bit 所代表的意义 。

串口通信协议 规定了数据包的内容,内容包含了 起始位、主体数据、校验位及停止位 ,双方需要 约定一致的数据包格式 才能正常收发数据的有关规范。

  • 在串口通信中,常用的协议包括 RS-232、RS-422和RS-485。
    1、RS-232(ANSI/EIA-232标准): 只支持点对点, 最大距离 50英尺。最大速度为128000bit/s, 距离越远,速度越慢。 支持全双工(发送同时也可接收)。
    2、RS-422(EIA RS-422-AStandard): 支持点对多一条平衡总线上连接最多10个接收器 将传输速率提高到10Mbps,传输距离延长到4000英尺(约1219米),所以在100kbps速率以内,传输距离最大。支持全双工(发送同时也可接收)。
    3、RS-485(EIA-485标准): 是RS-422的改进, 支持多对多(2线连接),从10个增加到32个,可以用超过4000英尺的线进行串行通行。速率最大10Mbps。支持全双工(发送同时也可接收)。2线连接时 是半双工状态。

2.RS-232标准

RS-232是现在主流的串行通信接口之一。通常 RS-232 接口以9个引脚 (DB-9) 或是25个引脚 (DB-25) 的型态出现,对每个引脚的信号内容加以规定,还对信号电平加以规定。但是工业控制的RS232接口一般只使用RXD、TXD、GND三条线。

  • 特点:
    (1)信号线少
    RS-232总线规定了25条线,包含了两个信号通道,即第一通道(称为主通道)和第二通道(称为副通道)。利用RS- 232总线可以实现全双工通信,通常使用的是主通道,而副通道使用较少。在一般应用中,使用3条~9条信号线就可以实现全双工通信,采用三条信号线(接收线、发送线和信号线)能实现简单的全双工通信过程。
    (2)灵活的波特率选择
    RS-232规定的标准传送速率有50b/s、75b/s、110b/s、150b/s、300b/s、600b/s、1200b/s、2400b/s、4800b/s、9600b/s、19200b/s,可以灵活地适应不同速率的设备。对于慢速外设,可以选择较低的传送速率:反之,可以选择较高的传送速率。
    (3)采用负逻辑传送
    规定 逻辑“1”的电平为-5V~-15 V,逻辑“0”的电平为+5 V~+15 V。选用该电气标准的目的在于提高抗干扰能力,增大通信距离。RS -232的噪声容限为2V,接收器 将能识别高至+3V的信号作为逻辑“0”,将低到-3 V的信号作为逻辑“1”。
    (4)传送距离较远
    由于RS -232采用串行传送方式,并且将微机的TTL电平转换为RS-232C电平,其传送距离一般可达30 m。若采用光电隔离20 mA的电流环进行传送,其传送距离可以达到1000 m。另外,如果在RS-232总线接口再加上Modem,通过有线、无线或光纤进行传送,其传输距离可以更远。

  • 缺点:
    (1)接口的信号电平值较高,易损坏接口电路的芯片。RS232接口任何一条信号线的电压均为负逻辑关系。即:逻辑“1”为-3— -15V;逻辑“0”:+3— +15V ,噪声容限为2V。即要求接收器能识别高于+3V的信号作为逻辑“0”,低于-3V的信号作为逻辑“1”,TTL电平为5V为逻辑正,0为逻辑负 。与TTL电平不兼容故需使用电平转换电路方能与TTL电路连接。
    (2)传输速率较低,在异步传输时,比特率为20Kbps;因此在51CPLD开发板中,综合程序波特率只能采用19200,也是这个原因。
    (3)接口使用一根信号线和一根信号返回线与地线构成共地的传输形式,这种共地传输容易产生共模干扰,所以抗噪声干扰性弱。
    (4)传输距离有限,最大传输距离标准值为50英尺,实际上也只能用在15米左右。

  • 连接方式
    RS232接口是9针(或引脚),通常是TxD和RxD经过电平转换得到的。要想使得芯片与PC机的RS232接口直接通信,需要也将芯片的输入输出端口也电平转换成RS232类型,再交叉连接。
    经过电平转换后,芯片串口和RS232的电平标准是不一样的:
    单片机是TTL电平:+5V表示1,0V表示0
    RS232是负逻辑电平,-3 ~ -15V为1,+3~+15V为0

RS-232通讯协议标准串口的设备间通讯结构图如下:
请添加图片描述

3.RS232电平与TTL电平的区别

TTL电平标准是 低电平为0,高电平为1(对地,标准数字电路逻辑)。
TTL电平信号被利用的最多是因为通常数据表示采用二进制规定,+5V等价于逻辑“1”,0V等价于逻辑“0”
RS232电平标准 是 正电平为0,负电平为1(对地,正负3-15V皆可,甚至可以用高阻态)。
在RS-232-C中任何一条信号线的电压均为负逻辑关系。即:逻辑“1”为-3到-15V;逻辑“0”为+3到+15V。

4."USB/TTL转232"模块工作原理

USB转串口即实现计算机USB接口到物理串口之间的转换。可以为没有串口的计算机或其他USB主机增加串口,使用USB转串口设备等于将传统的串口设备变成了即插即用的USB设备

4.1基本工作原理

串口发送
串口应用发送数据->USB串口驱动获取数据->驱动将数据经过USB通道发送给USB串口设备->USB串口设备接收到数据通过串口发送

串口接收
USB串口设备接收串口数据->将串口数据经过USB打包后上传给USB主机->USB串口驱动获取到通过USB上传的串口数据->驱动将数据保存在串口缓冲区提供给串口应用读取

4.2CH340芯片模块

CH340 是一个USB 总线的转接芯片,实现USB 转串口、USB 转IrDA 红外或者USB 转打印口。为了增加串口通讯的远距离传输及抗干扰能力,RS-232标准使用-15V 表示逻辑 1, +15V 表示逻辑 0。常常会使用 MH340芯片 对 USB/TTL与RS-232电平的信号进行转换。

USB转串口模块可以使用5V、3V3电压供电,需要将跳线帽进行安装。
USB转串口电路板与单片机的接线图,VCC接线是为了单片机供电,USB转串口的RXD引脚与单片机的TXD引脚相连,USB转串口的TXD引脚与单片机的RXD引脚相连,两者的GND引脚直接相连。
请添加图片描述

二、环境搭建

1.硬件环境

  • STM32F103C8T6核心板
  • USB转TTL
  • 面包板一块
  • 杜邦线(公对公、母对母)若干
  • 连接方法:
    请添加图片描述
    注意将核心板上的BOOT0设置为1,BOOT1设置为0

2.软件环境

  • MDK5、stm32CubeMX
  • CH340驱动(USB串口驱动)
    请添加图片描述
  • FlyMcu 烧录助手
    请添加图片描述
  • 串口通信助手(SSCOM)
    请添加图片描述

三、HAL库中断实现串口通信

1.创建工程

1.1 点击File,创建新项目New Project
请添加图片描述
1.2 选择芯片STM32F103C8T6
请添加图片描述
1.3 配置RCC
请添加图片描述
1.4 配置SYS
请添加图片描述
1.5 配置USART1
请添加图片描述
1.6 配置NVIC
勾选下方选项表示支持中断操作
请添加图片描述
1.7 配置Clock Configuration
请添加图片描述
1.8 配置Project Manager
请添加图片描述
1.9 工程创建完成,用keil打开
请添加图片描述

2.keil代码配置

2.1在usart.c和main.c中添加头文件

#include “stdio.h”
#include “string.h”

解释:因为后面我们需要用到printf和strcmp。
请添加图片描述

2.2重定义printf函数和勾选项

请添加图片描述

  • main函数外定义
int fputc(int ch, FILE *f)
 
{
 
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
 
  return ch;
 
}

2.3设置全局变量

uint8_t aRxBuffer;		
uint8_t Uart1_RxBuff[256]; 
uint8_t start[20] = "start";
uint8_t stop[20] = "stop";
uint8_t Uart1_Rx_Cnt = 0;	
uint8_t cAlmStr[] = "溢出了\r\n";
unsigned int flag = 1;

2.4设置接收中断函数

  • 在main函数中加入
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);

  • 在while循环中添加
while (1)
{
	if(flag == 1){		
	  		printf("Hello windows!\r\n");
		}
	HAL_Delay(1000);
}

  • 重写回调函数(main函数外)
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	
	if (strcmp(Uart1_RxBuff, start) == 0){
			flag = 1;
			printf("start....\r\n");
		
	}
	if (strcmp(Uart1_RxBuff, stop) == 0){
			flag = 0;
			printf("stop....\r\n");
		
	}
	if(Uart1_Rx_Cnt >= 255)  //溢出判断
	{
		Uart1_Rx_Cnt = 0;
		memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff));
		HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);	
	}
	else
	{
		Uart1_RxBuff[Uart1_Rx_Cnt++] = aRxBuffer;   //接收数据转存
	
		if((Uart1_RxBuff[Uart1_Rx_Cnt-1] == 0x0A)&&(Uart1_RxBuff[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
		{
			Uart1_Rx_Cnt = 0;
			memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff)); //6清空数组
		}
	}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断

}

3.编译并烧录

  • 点击魔术棒,在 Output下勾选 Create HEX File
    请添加图片描述
  • Debug里面选择 Use Simulator
    Dailog DLL设置为DARMSTM.DLL,Parameter设置为-pSTM32F103C8;
    请添加图片描述
  • 点击ok 点击编译 编译成功
    请添加图片描述
  • 按照硬件环境部分将硬件连接到电脑串口上,打开 FlyMcu烧录软件
  • 找到生成的 hex 文件,点击打开
  • 搜索串口,设置波特率为115200bps
  • 点击开始编程,进行烧录
    请添加图片描述

4.实现效果

  • 打开SSCOM串口/网络数据调试器
  • 打开串口设置,匹配串口设置
    请添加图片描述
  • 点击打开串口,得到以下效果
    在这里插入图片描述

四、HAL库DMA实现串口通信

DMA

  • DMA,全称Direct Memory Access,即直接存储器访问。DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。
  • DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
  • DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节。
    我们知道,数据传输,首先需要的是数据的源地址、数据传输位置的目标地址、传递数据多少的数据传输量、进行多少次传输的传输模式。DMA所需要的核心参数,便是这四个。
    每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。

1.CubeMX创建项目

芯片选择与上文一致,此处省略

1.1配置RCC

请添加图片描述

1.2配置USART1

选择异步通信
其余参数默认
添加两个通信信道
请添加图片描述

1.3配置NVIC

勾选下方选项表示支持中断操作
请添加图片描述### 1.4创建完成keil打开
请添加图片描述

2.程序配置

定义发送和接收缓冲区,以及标志变量is_sending。
配置UART,设置接收中断。
发送任务:
检查is_sending标志,如果为1则继续发送;否则跳出。
发送字符串"hello windows!"。
判断发送完成标志,如果为1则清除标志并跳回开始发送。
接收任务:
在接收中断服务函数中,将接收到的数据保存到接收缓冲区。
判断接收到的字符,如果为’stop’则设置is_sending为0;如果为’start’则设置为1。
主函数中循环调用发送和接收任务。

uint8_t tx_buf[] = "hello windows!";
uint8_t rx_buf;
uint8_t is_sending = 1;
void UART_Send(void) {
  if(is_sending == 1) {
    HAL_UART_Transmit(&huart, tx_buf, sizeof(tx_buf), 1000); 
  }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
  if(rx_buf == 'stop') 
    is_sending = 0;
  else if(rx_buf == 'start')
    is_sending = 1;
}
int main(void) {
  while(1) {
    UART_Send();
    UART_Receive(); 
  }
}

3.烧录实现效果

请添加图片描述

在这里插入图片描述

五、Keil软件仿真

1.逻辑分析仪功能

  • 点击debug,进入调试页面
    选择逻辑分析仪
    请添加图片描述
  • 选择要观察的引脚
    请添加图片描述
  • 点击右上角,添加USART1_SR引脚,引脚的Display Type选择为Bit
    请添加图片描述

2.波形分析

  • 运行程序
    请添加图片描述
  • 得出波形
    请添加图片描述
  • 发送信息时高电平的持续时间为0.778us
    请添加图片描述
  • 发送信息时低电平的持续时间为87.7us
    请添加图片描述
  • 延时100ms
    请添加图片描述
    通过查看peripherals中的USART1可看到其波特率实际为115200baud
    请添加图片描述
    请添加图片描述

六、总结

在本次基于中断/DMA方式的串口通信实验是上次实验的改进与拓展,从发送一个字符,到改进为发送一个字符串并且要使用中断和DMA两种方式。这次实验虽然要求用两种不同的方式实现串口通信,而在这两种方式的代码撰写过程中设计思路都是相同的,即将收到的字符储存在数组中,然后在回调函数中判断收到的字符串是否与stop或start相同,如果相同对n值进行相应的改变,很明显,在DMA方式中撰写的代码比中断采用的代码更为简单。在本次实验中将理论的学习运用到实践中,过程中虽然出现了不少问题,但通过不断的查询资料最终将问题解决,收获颇多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值