本文说明
功能要求
- 开机后,向串口1发送“Welcome”
- 串口1接收字节指令“0xA1",打开LED1,回传“LED1 ON”
- 串口1接收字节指令“0xA2",关闭LED1,回传“LED1 OFF”
- 在串口发送过程中,打开LED2作为发送数据指示灯
相关软件使用说明
STM32CubeMX+Keil+Proteus相关的安装、使用、配置等基础操作不再赘述,有关内容的详细介绍如下
串行接口相关知识点
- 通信方式:串行通信和并行通信
- 模式:单工、半双工、全双工(任意时刻是否能同时发送和接收数据)
- 异步串行通信:通信双方在没有同步时钟的前提下,将一个字符按位进行传输的通信方式
- 串口转USB接口:CH340、CP2012
- STM32芯片的串口USART功能十分强大,大多时候采用异步串行通信
USART1_TX与PA9复用, USART1_RX与PA10复用
USART2_TX与PA2复用, USART2_RX与PA3复用
HAL库中串口发送的重要函数
阻塞式发送函数(要等待数据发完才能做其他任务)
HAL_UART_Transmit()
非阻塞式发送函数
HAL_UART_Transmit_IT()
看函数名,多了个_IT, 即在阻塞式发送的基础上可以中断(Interrupt)
串口发送完毕中断回调函数
void HAL_UART_TxCpltCallback()
举例说明串口发送函数的作用
假如我们使用非阻塞式的串口发送函数,将发送数组dat_Txd中的前5个数据发送到
HAL_UART_Transmit_IT(&huart1,dat_Txd,5);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1) //判断发送数据的串口
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
}
}
如果是使用阻塞式发送函数,则代码变为如下内容
HAL_UART_Transmit(&huart1,dat_Txd,5,10000); //超时等待10000ms
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
HAL库中串口接收的重要函数
阻塞式接收函数(要等待数据接收完才能做其他任务,所以不推荐)
HAL_UART_Transmit()
非阻塞式接收函数(推荐使用)
HAL_UART_Transmit_IT()
串口发送完毕中断回调函数
void HAL_UART_RxCpltCallback()
举例说明串口接收函数的作用
假如使用非阻塞式的串口发送函数,接收USART1中的一个字节,将其保存在dat_Rxd,在发送完数据后,若该字节位0x5A,则翻转PB9引脚的输出电平
HAL_UART_Transmit_IT(&huart1,dat_Rxd,1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1) //判断发送数据的串口
{
if(dat_Rxd == 0x5A)
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
}
}
STM32CubeMX配置USART
Mode选择Asynchronous(异步的)
Baud Rate(波特率)选择9600Bits/s
然后使能一下NVIC,勾选USART1 interrupt Enabled即可
其他的配置内容不再赘述,详情可查看本文开头写的本文说明一章
然后生成代码即可
Keil编写代码逻辑
首先定义一些变量
#define LED1_ON HAL_GPIO_WritePin(GPIOA,LED1_Pin,GPIO_PIN_RESET);
#define LED1_OFF HAL_GPIO_WritePin(GPIOA,LED1_Pin,GPIO_PIN_SET);
#define LED2_ON HAL_GPIO_WritePin(GPIOA,LED2_Pin,GPIO_PIN_RESET);
#define LED2_OFF HAL_GPIO_WritePin(GPIOA,LED2_Pin,GPIO_PIN_SET);
uint8_t Tx_str1[]= "Welcome!rn";
uint8_t Tx_str2[]= "LED1 ON!rn";
uint8_t Tx_str3[]= "LED1 OFF!rn";
uint8_t Tx_str4[]= "Command Not Found!rn";
uint8_t Rx_dat = 0; //接收字符变量
然后在主函数内实现开机发送Welcome
/* USER CODE BEGIN 2 */
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str1,sizeof(Tx_str1),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
/* USER CODE END 2 */
发送函数执行结束后,要等待串口发来的字符
这里将HAL_UART_Receive_IT()函数写在循环体内
时时刻刻等待串口发来的字符
while (1)
{
/* USER CODE END WHILE */
HAL_UART_Receive_IT(&huart1,&Rx_dat,3); //等待接收字符
/* USER CODE BEGIN 3 */
}
而每当HAL_UART_Receive_IT()函数执行之后,则进入中断,进入回调函数HAL_UART_RxCpltCallback()
因此我们需要编辑我们的回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
switch(Rx_dat)
{
case 0x4f:
LED1_ON;
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
break;
case 0x43:
LED1_OFF;
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str3,sizeof(Tx_str3),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
break;
default:
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str4,sizeof(Tx_str4),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
break;
}
}
}
简单解释一下程序,进行回调函数,根据接收的字符执行对应的操作
执行完相关操作,跳出switch case继续等待接收串口发来的字符
编译运行生成hex文件,准备仿真
Proteus仿真
原理图如下
第一次仿真串口,查了查,需要在元件库里找名为COMPIM的元件
COMPIM是Proteus中一个极其有用的虚拟元件,COMPIM可以建立起一种映射,把仿真威廉希尔官方网站
中的数字量映射到计算机的物理端口
找到这个元件,拖进原理图,编辑一些属性,如图
其中Physical Port(物理端口)就是我们要在计算机中建立的映射物理端口
波特率都设置成9600
除了虚拟串口,我们还需要一个虚拟终端来查看发送的数据信息
点击左侧长得像电流表的图标,找到VIRTUAL TERMIN(虚拟终端),放进原理图
第一次见比较陌生,介绍一下这个虚拟终端
这个虚拟终端有四个引脚,分别是
RXD 一 数据接收引脚
TXD 一 数据发送引脚
RTS 一 请求发送信号
CTS 一 清除传送,是对RTS的响应信号
左键这个虚拟终端,出现了一堆参数,如图
Baud Rate 一 传输波特率
Data Bits 一 数据传输位数
Parity 一 奇偶校验位
Stop Bits 一 数据传输的停止位
Send XON / XOFF 发送允许/禁止
这些好像哪里见过,找到usart.c文件的UART_Init函数中,发现完全一致
这也就是我们为什么要设置波特率为9600
一开始一脸茫然,不知道怎么将芯片的MCU和这两个元件连线
后来查了查才知道STM32芯片给了专门的TX引脚PA9和RX引脚PA10
那我们就把芯片的TX引脚和COMPIM的TXD相连,芯片的RX引脚和COMPIM的RXD相连,再将COMPIM的RXD与VIRTUAL TERMIN的RXD相连即可。详情可看上方的原理图
老规矩导入Hex文件,设置主频72MHz
虚拟串口VSPD
试用15天,使用方法官网里也有写
我自己用的是老版本的(反正能用就行,学习使用)
打开软件,创建COM3和COM4两个虚拟端口即可
两个串口已经可以正常通信了
串口调试工具XCOM
我用的是XCOM2.6版本的
由于软件是正点原子的
所以你也可以去正点原子的william hill官网
里下载最近发布的版本来使用
打开串口调试工具XCOM,选择串口COM4->COM3,打开串口
(刚才在Proteus里设置COMPIM的串口是COM3)
开始测试串口通信
开机发送Welcome,正确
发送字符O,回传LED1 ON,LED1亮,正确
发送字符C,回传LED1 OFF,LED1灭,正确
发送字符Z,回传Command Not Found,正确
总结
- 主要学习了使用VSPD配置虚拟串口和XCOM串口调试工具
- 熟悉使用Proteus里COMPIM串口元件和虚拟终端
- 学习了串口通信的相关原理和主要函数的运行过程
- 学习使用STM32CubeMX配置USART
- 用一个具体项目来实现串口通信。
本文说明
功能要求
- 开机后,向串口1发送“Welcome”
- 串口1接收字节指令“0xA1",打开LED1,回传“LED1 ON”
- 串口1接收字节指令“0xA2",关闭LED1,回传“LED1 OFF”
- 在串口发送过程中,打开LED2作为发送数据指示灯
相关软件使用说明
STM32CubeMX+Keil+Proteus相关的安装、使用、配置等基础操作不再赘述,有关内容的详细介绍如下
串行接口相关知识点
- 通信方式:串行通信和并行通信
- 模式:单工、半双工、全双工(任意时刻是否能同时发送和接收数据)
- 异步串行通信:通信双方在没有同步时钟的前提下,将一个字符按位进行传输的通信方式
- 串口转USB接口:CH340、CP2012
- STM32芯片的串口USART功能十分强大,大多时候采用异步串行通信
USART1_TX与PA9复用, USART1_RX与PA10复用
USART2_TX与PA2复用, USART2_RX与PA3复用
HAL库中串口发送的重要函数
阻塞式发送函数(要等待数据发完才能做其他任务)
HAL_UART_Transmit()
非阻塞式发送函数
HAL_UART_Transmit_IT()
看函数名,多了个_IT, 即在阻塞式发送的基础上可以中断(Interrupt)
串口发送完毕中断回调函数
void HAL_UART_TxCpltCallback()
举例说明串口发送函数的作用
假如我们使用非阻塞式的串口发送函数,将发送数组dat_Txd中的前5个数据发送到
HAL_UART_Transmit_IT(&huart1,dat_Txd,5);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1) //判断发送数据的串口
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
}
}
如果是使用阻塞式发送函数,则代码变为如下内容
HAL_UART_Transmit(&huart1,dat_Txd,5,10000); //超时等待10000ms
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
HAL库中串口接收的重要函数
阻塞式接收函数(要等待数据接收完才能做其他任务,所以不推荐)
HAL_UART_Transmit()
非阻塞式接收函数(推荐使用)
HAL_UART_Transmit_IT()
串口发送完毕中断回调函数
void HAL_UART_RxCpltCallback()
举例说明串口接收函数的作用
假如使用非阻塞式的串口发送函数,接收USART1中的一个字节,将其保存在dat_Rxd,在发送完数据后,若该字节位0x5A,则翻转PB9引脚的输出电平
HAL_UART_Transmit_IT(&huart1,dat_Rxd,1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1) //判断发送数据的串口
{
if(dat_Rxd == 0x5A)
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
}
}
STM32CubeMX配置USART
Mode选择Asynchronous(异步的)
Baud Rate(波特率)选择9600Bits/s
然后使能一下NVIC,勾选USART1 interrupt Enabled即可
其他的配置内容不再赘述,详情可查看本文开头写的本文说明一章
然后生成代码即可
Keil编写代码逻辑
首先定义一些变量
#define LED1_ON HAL_GPIO_WritePin(GPIOA,LED1_Pin,GPIO_PIN_RESET);
#define LED1_OFF HAL_GPIO_WritePin(GPIOA,LED1_Pin,GPIO_PIN_SET);
#define LED2_ON HAL_GPIO_WritePin(GPIOA,LED2_Pin,GPIO_PIN_RESET);
#define LED2_OFF HAL_GPIO_WritePin(GPIOA,LED2_Pin,GPIO_PIN_SET);
uint8_t Tx_str1[]= "Welcome!rn";
uint8_t Tx_str2[]= "LED1 ON!rn";
uint8_t Tx_str3[]= "LED1 OFF!rn";
uint8_t Tx_str4[]= "Command Not Found!rn";
uint8_t Rx_dat = 0; //接收字符变量
然后在主函数内实现开机发送Welcome
/* USER CODE BEGIN 2 */
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str1,sizeof(Tx_str1),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
/* USER CODE END 2 */
发送函数执行结束后,要等待串口发来的字符
这里将HAL_UART_Receive_IT()函数写在循环体内
时时刻刻等待串口发来的字符
while (1)
{
/* USER CODE END WHILE */
HAL_UART_Receive_IT(&huart1,&Rx_dat,3); //等待接收字符
/* USER CODE BEGIN 3 */
}
而每当HAL_UART_Receive_IT()函数执行之后,则进入中断,进入回调函数HAL_UART_RxCpltCallback()
因此我们需要编辑我们的回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
switch(Rx_dat)
{
case 0x4f:
LED1_ON;
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
break;
case 0x43:
LED1_OFF;
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str3,sizeof(Tx_str3),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
break;
default:
LED2_ON; //发送指示灯LED2亮
HAL_UART_Transmit(&huart1,Tx_str4,sizeof(Tx_str4),1000); //阻塞式发送函数
LED2_OFF; //发送结束时,指示灯LED2灭
break;
}
}
}
简单解释一下程序,进行回调函数,根据接收的字符执行对应的操作
执行完相关操作,跳出switch case继续等待接收串口发来的字符
编译运行生成hex文件,准备仿真
Proteus仿真
原理图如下
第一次仿真串口,查了查,需要在元件库里找名为COMPIM的元件
COMPIM是Proteus中一个极其有用的虚拟元件,COMPIM可以建立起一种映射,把仿真威廉希尔官方网站
中的数字量映射到计算机的物理端口
找到这个元件,拖进原理图,编辑一些属性,如图
其中Physical Port(物理端口)就是我们要在计算机中建立的映射物理端口
波特率都设置成9600
除了虚拟串口,我们还需要一个虚拟终端来查看发送的数据信息
点击左侧长得像电流表的图标,找到VIRTUAL TERMIN(虚拟终端),放进原理图
第一次见比较陌生,介绍一下这个虚拟终端
这个虚拟终端有四个引脚,分别是
RXD 一 数据接收引脚
TXD 一 数据发送引脚
RTS 一 请求发送信号
CTS 一 清除传送,是对RTS的响应信号
左键这个虚拟终端,出现了一堆参数,如图
Baud Rate 一 传输波特率
Data Bits 一 数据传输位数
Parity 一 奇偶校验位
Stop Bits 一 数据传输的停止位
Send XON / XOFF 发送允许/禁止
这些好像哪里见过,找到usart.c文件的UART_Init函数中,发现完全一致
这也就是我们为什么要设置波特率为9600
一开始一脸茫然,不知道怎么将芯片的MCU和这两个元件连线
后来查了查才知道STM32芯片给了专门的TX引脚PA9和RX引脚PA10
那我们就把芯片的TX引脚和COMPIM的TXD相连,芯片的RX引脚和COMPIM的RXD相连,再将COMPIM的RXD与VIRTUAL TERMIN的RXD相连即可。详情可看上方的原理图
老规矩导入Hex文件,设置主频72MHz
虚拟串口VSPD
试用15天,使用方法官网里也有写
我自己用的是老版本的(反正能用就行,学习使用)
打开软件,创建COM3和COM4两个虚拟端口即可
两个串口已经可以正常通信了
串口调试工具XCOM
我用的是XCOM2.6版本的
由于软件是正点原子的
所以你也可以去正点原子的william hill官网
里下载最近发布的版本来使用
打开串口调试工具XCOM,选择串口COM4->COM3,打开串口
(刚才在Proteus里设置COMPIM的串口是COM3)
开始测试串口通信
开机发送Welcome,正确
发送字符O,回传LED1 ON,LED1亮,正确
发送字符C,回传LED1 OFF,LED1灭,正确
发送字符Z,回传Command Not Found,正确
总结
- 主要学习了使用VSPD配置虚拟串口和XCOM串口调试工具
- 熟悉使用Proteus里COMPIM串口元件和虚拟终端
- 学习了串口通信的相关原理和主要函数的运行过程
- 学习使用STM32CubeMX配置USART
- 用一个具体项目来实现串口通信。
举报