引言
STM32单片机是基于高性能CortexM3内核的32位单片机,其外设功能强大,最大工作频率为72 MHz。本文选用的STM32103VET6芯片,有5个USART、3个SPI口、2个I2C接口,便于产品与上位机的通信。采用基于库函数的编程方法,能很快地进行产品开发。
本文采用基于RealView、VSPD(虚拟串口)和串口调试软件的联合仿真调试技术,可以在没有硬件平台的情况下,完成多串口收发通信软件的开发和测试。
1多串口通信的软件设计原理
使用STM32的USART1~USART3。在不进行引脚重映射的情况下,USART1_Tx引脚为PA9,USART1_Rx引脚为PA10,USART2_Tx引脚为PA2,USART2_Rx引脚为PA3,USART3_Tx引脚为PB10,USART3_Rx引脚为PB11。
软件的设计采用模块化,包括RCC时钟配置模块、NVIC中断向量配置模块、USART1~USART3引脚配置模块、USART1~USART3初始化模块,USART1~USART3通信模块等。软件流程图如图1所示。
1.1RCC时钟设置模块
采用8 MHz外部晶振作为PLL时钟,再倍频到72 MHz。该时钟作为系统时钟,待系统时钟稳定后,再进行各模块时钟的分配。时钟初始化函数为void RCC_Configuration(void),代码如下:
void RCC_Configuration(void){
RCC_HSEConfig(RCC_HSE_ON);//设置外部高速晶振(HSE)
HSEStartUpStatus=RCC_WaitForHSEStartUp();//等待HSE起振
if(HSEStartUpStatus == SUCCESS){
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//预取指缓存使能
FLASH_SetLatency(FLASH_Latency_2);//设置代码延时值,2个延时周期
//设置AHB时钟(HCLK),分频系数为1,AHB时钟=系统时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//设置高速AHB时钟(PCLK2),分频系数为1,
//APB2时钟=HCLK*/
RCC_PCLK2Config(RCC_HCLK_Div1);
/*设置低速AHB时钟(PCLK1),分频系数为2,
//APB1时钟 = HCLK/2*/
RCC_PCLK1Config(RCC_HCLK_Div2);
//PLLCLK = 8MHz*9=72 MHz ,
//设置PLL时钟源及倍频系数
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);RCC_PLLCmd(ENABLE); //使能PLL
//等待PLL初始化成功
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){
}
//设置系统时钟(SYSCLK),设置PLL为系统时钟源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//等待PLL成功用作系统时钟的时钟源,
//0x08:PLL作为系统时钟
while(RCC_GetSYSCLKSource() !=0x08){
}
}
//使能串口1时钟,及引脚GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能串口2时钟
//使能串口3引脚GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能串口3 时钟
}
1.2UASRT通信引脚配置模块
采用全双工通信,STM32单片机功能引脚由GPIO引脚进行映射,仅给出USART1_Tx和USART1_Rx引脚配置的软件代码,USART2和USART3的引脚配置类似。代码如下:
//USART1所用输入/输出引脚的定义
//定义USART1_Tx (PA9) 脚为复用推挽输出
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//I/O口的第9脚
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //I/O口的速度
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//I/O口复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化USART1的TX口
//定义USART1_Rx (PA10) 脚为悬空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
//I/O口的第10脚
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
//I/O口悬空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化USART1的RX口
1.3NVIC中断向量配置模块
NVIC是向量中断控制器,用来控制多个中断向量的优先级,在NVIC中设置USART1中断为最高优先级,USART2次之,USART3中断优先级最低。本文设置发送为顺序发送,接收为中断响应接收。代码如下:
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_DeInit();
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//使能USART1中断
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
//使能USART2中断
NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//使能USART3中断
NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
USART1~USART3的抢占优先级相同,USART1的从优先级值最小,所以USART1的优先级别最高。
1.4USART的通信配置模块
采用全双工通信,对USART1进行配置, USART1的波特率为115 200 b/s,数据位为8位,停止位1位,无校验位,无流量控制,接收、发送使能,采用接收中断方式,USART2和USART3的配置类似。
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=115200; //设定传输速率
USART_InitStructure.USART_WordLength=USART_WordLength_8b; //设定8位数据位
USART_InitStructure.USART_StopBits=USART_StopBits_1;
//设定1个停止位
USART_InitStructure.USART_Parity=USART_Parity_No ;
//无校验位
//不用流量控制
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
//使用发送和接收功能
USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
//初始化USART1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能USART1接收中断
USART_Cmd(USART1, ENABLE);//使能USART1
1.5USART的中断接收模块
在该中断响应函数中,当USART1接收事件完成时,产生中断信号,通知微处理器进行串口通信的接收处理。
void USART1_IRQHandler(void){
static unsigned char rx1_num;
unsigned char temp_rx;
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET){// 如果是接收中断
temp_rx = USART_ReceiveData(USART1);
uart1_rx[rx1_num] = temp_rx;
}
rx1_num++; //静态变量,记录USART1接收数据的个数
}
当USART2和USART3产生接收中断时,进入相应的中断函数进行处理。
2虚拟串口和仿真串口的绑定
传统的USART调试必须有相应的开发板,连接开发板的串口和上位机的串口,开发软件RealView MDK在调试时,有3个串口的仿真输出窗口(UART#1、UART#2、UART #3),但这3个窗口只能仿真串口输出,不能仿真串口的接收通信。采用虚拟串口软件VSPD(Virtual Serial Port Driver ),可以虚拟出多对串口,如图2所示。分别把每一对虚拟串口中的一个与STM32单片机的每个串口进行绑定,就可以进行串口的通信仿真测试。
用VSPD软件虚拟了3对串口,分别是COM4和COM5,COM6和COM7,COM8和COM9。COM4发送数据时,COM5接收数据,反之亦然。为了仿真STM32单片机3个串口的收发通信,把UART1和COM4绑定在一起,把UART2和COM6绑定在一起,把UART3和COM8绑定在一起。因为虚拟串口COM4和COM5互相通信,所以用COM5发数据,可以模拟串口COM4的中断接收数据。配置文件为COM4_OUT.txt,把后缀名改为.ini。内容如下:
MODE COM4 115200, 0, 8, 1
ASSIGN COM4 MODE COM6115200, 0, 8, 1 ASSIGN COM6 MODE COM8115200, 0, 8, 1 ASSIGN COM8 ASSIGN 文件的作用是配置COM4的波特率为115 200 b/s,8个数据位,1个停止位,无校验位。把COM4和STM32的第一个串口绑定在一起,配置COM6的波特率与COM4一样,绑定COM6和STM32的第二个串口在一起,依次类推。把COM4_OUT.ini文件放在工程文件中,编译后,就可以利用RealView MDK软件和串口调试软件进行串口的通信仿真测试。 3USART通信发送、接收数据测试 3.1发送数据测试 设置3个发送数组:uart1_tx[64]、uart2_tx[64]、uart3_tx[64]。因为COM4和COM5相连接,当COM4发送数据时,COM5接收数据,由图3可知,当COM4发送数组uart1_tx[64]的数据时,COM5的接收区正确显示数组uart1_tx[64]的数据。 COM8和COM9相连,由图4可知,COM9的接收区能够正确显示数组uart3_tx[64]的数据。 uart1_tx[64]= {0x11, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f,0x3a, 0x5b, 0x2c, 0x2d, 0x3e, 0x4f, 0x4c, 0x2d,……, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xaf}; uart3_tx[64]= {0x31, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x3f, ……,0x8a, 0x8b, 0x6c, 0x6d, 0xe7, 0xf7, 0xa3, 0xb5, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xcf, 0xcf}; 3.2接收数据测试 用uart1_rx[64]、uart2_rx[64]、uart3_rx[64]分别模拟COM4、COM6和COM8中断接收数据,这时COM5、COM7和COM9分别发出数据。该实验用于测试多串口中断接收通信的准确率。 图5 COM5发送数据测试 COM5发送数据测试略——编者注。uart1_rx[64]正确接收到COM5发出的64个数据,表明COM4中断接收数据正确。 uart2_rx[64]正确接收到COM7发送的64个数据,表明COM6和COM7串口通信正确COM7发送数据测试略——编者注。 图6 COM7发送数据测试 结语 针对目前广泛使用的STM32单片机,提出了一种使用VSPD(虚拟串口)结合串口调试软件进行多串口收发通信的仿真测试方法。本文详细介绍了虚拟串口和仿真串口的绑定方法,给出了各模块的软件代码,并给出了实验结果。 该方法可以在没有硬件平台的条件下,精确地进行多个串口发送和接收通信的测试。测试结果表明,采用该方法可以很好地完成STM32多串口通信的测试。
上一篇:基于STM32的Mifare IC卡读写卡器设计
下一篇:关于STM32初学者必知
推荐阅读最新更新时间:2024-11-07 10:31
设计资源 培训 开发板 精华推荐
- STEVAL-CBL010V1,基于 LNBH25 单 LNB 电源和控制 IC DiSEqC 2.0 的评估板
- 使用 STMicroelectronics 的 LM305 的参考设计
- S12XFSTARTERKITE: S12XF 2节点入门套件
- DER-260 - 1.5W非隔离反激式电源,具有0.00W掉电模式
- 应用笔记 - 基于 Z8 Encore XP F1680 微步控制器的 AN027202-0312
- esp32HIFI播放器
- DC2578A,基于 LTC4281、LTC3886、LTC2975、LTC3887 的演示板,用于热插拔、中间总线、负载点的总体电源管理
- 【物联网】基于Hi3861的鸿蒙智能WIFI开关
- LTC7813EUH 宽输入范围至 24V/5A 低 IQ 级联升压 + 降压稳压器 (VMID = 28V) 的典型应用电路
- LTC7813IUH 宽输入范围至 24V/5A 低 IQ 级联升压 + 降压稳压器 (VMID = 28V) 的典型应用电路