STM32单片机多串口通信仿真测试技术研究:方法探究与实验分析
eeskill 2023-12-04


引言


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 <S1IN> S1OUT


MODE COM6115200, 0, 8, 1


ASSIGN COM6 <S2IN> S2OUT


MODE COM8115200, 0, 8, 1


ASSIGN COM8 <S3IN> S3OUT


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多串口通信的测试。


声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 对话周祖成教授 - 清华大学与西门子EDA的合作之旅


  • 相关技术文库
  • EDA
  • 仿真
  • CAD
  • 芯片
  • 变容二极管的应用和仿真,用Multisim软件轻松实现

    仿真前仿真中XSC1XSC2XSC3波特图变容二极管的结电容,不仅与PN结的结构与加工工艺有关,还与所加的反向

    02-26
  • 如何使步进电机效率最大化?

    电机是常用机械装置,很多朋友都见过电机。但是问题来了,你真的会有效使用电机吗?为增进大家对电机的认识,本文将探讨如何使步进电机的效率最大化。如果你对电机、步进电机具有兴趣,不妨和小编一起继续往下阅读哦...

    02-21
  • 以太网接入中存在哪些技术问题?

    以太网是应用最普遍的局域网技术,可以说,以太网是现实世界中最普遍的一种计算机网络。为增进大家对以太网的认识,本文将对以太网介入中的主要技术问题予以介绍。如果你对以太网具有兴趣,不妨和小编一起继续往下...

    02-21
  • 芯片的IP核是什么?

    芯片的重要性不言而喻,这也是各国都在大力发展芯片的原因之一。为增进大家对芯片的认识,本文将对芯片的IP核,以及芯片的市场需求予以介绍。如果你对芯片以及芯片的相关内容具有兴趣,不妨和小编一起继续往下阅读...

    02-21
  • 内存故障的惊险故事!12大解决方案

    内存对于电脑的重要性不言而喻,缺少内存,电脑将无法正常运转。如果内存发生故障,笔记本将同样产生一些令人疑惑的错误。本文中,小编将对内存可能出现的故障以及相应的解决措施予以介绍。如果你对内存具有兴趣,...

    02-21
  • 如何用MATLAB进行电路仿真

    本文演示如何用MATLAB进行电路仿真,测量RLC电路的电压。

    02-20
  • 一文教你QC、IQC、IPQC、QA有什么区别

    QC、IQC、IPQC、QA到底有什么区别,傻傻分不清,看完这篇你就懂了。

    02-20
  • 74ls283原理及应用

    1、74ls283概述    74ls283这类全加法器执行两个4位二进制数的加法。为每一位提供sum()输出,从第4位获得合成进位(C4)。这些加法器的特点是全内部向前看所有四个位。这为系统设计人员提供了部分的经济前瞻性性能,并...

    01-30
  • 什么是 LM386 芯片?LM386 引脚图及功能详解

        今天是 LM386 音频放大电路,主要是以下几个方面:1、什么是 LM386芯片?2、LM386 引脚图及功能3、LM386 CAD 模型4、LM386 的主要性能参数5、LM386 的工作原理6、LM386 音频放大电路图讲解7、LM386 功放电路8、L...

    01-29
  • SN74HC245系列芯片说明及逻辑电路图

    SN74HC245系列八进制总线收发器被设计用于数据总线之间的异步双向通信。它的控制功能的实现将外部时序要求最小化。SN74HC245系列芯片说明及逻辑电路图:SN74HC245系列允许数据传输从A总线到B总线或从B总线到A总线,...

    01-29
下载排行榜
更多
评测报告
更多
广告