STM32单片机多串口通信仿真测试技术研究

发布者:EnchantedWish最新更新时间:2021-06-11 来源: eefocus关键字:STM32  单片机  多串口通信  仿真测试 手机看文章 扫描二维码
随时随地手机看文章

引言


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 S1OUT


MODE COM6115200, 0, 8, 1


ASSIGN COM6 S2OUT


MODE COM8115200, 0, 8, 1


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


关键字:STM32  单片机  多串口通信  仿真测试 引用地址:STM32单片机多串口通信仿真测试技术研究

上一篇:基于STM32的Mifare IC卡读写卡器设计
下一篇:关于STM32初学者必知

推荐阅读最新更新时间:2024-11-07 10:31

深耕8位MCU,瑞萨电子凭借RL78助力工业与物联网市场
从我们驾驶的汽车到家中的电器,再到保护家庭安全的烟雾报警器,微控制器 (MCU) 几乎无处不在。瑞萨电子是全球最大的 MCU 供应商,虽然与微处理器相比,MCU 受到的关注较少,但瑞萨正在通过创新来帮助推动汽车和物联网不断实现数字化。 瑞萨从事 MCU 业务已有十多年,起初源于 2010 年 NEC 电子和瑞萨科技的合并,瑞萨科技本身又是 2003 年由日立和三菱合并而来。其总部位于日本,制造设施位于日本 、中国、东南亚和美国,瑞萨电子是全球排名第一的汽车MCU供应商。 我之前写过关于瑞萨的财务增长和公司文化,以及物联网和基础设施业务部门 (IIBU)的有关文章。现在,我想将注意力转向瑞萨电子的主要 MCU,特别是其 R7
[单片机]
单片机之流水灯 AT89C51
流水灯是单片机入门必学的一个实验。这里面主要涉及的操作就是移位操作,还有就是对延时的控制。在没有接触定时器的时候,可以用for语句来进行延时,当然并不能做到精准延时,可以通过在试验箱上的实验现象,来修改延时时间的长短。 #include reg51.h #define uchar unsigned char #define uint unsigned int void delay() { uchar m,s,n; for(m=20;m 0;m--) for(s=20;s 0;s--) for(n=248;n 0;n--); } /*上面这个延时到底延时了多长时间,可以通过keil中的反汇编看到。晶振为12
[单片机]
VM7.1 下Ubuntu10.10 与 51单片机串口通信实验
在VM7.1下给虚拟机增加一个串口(使用物理串口),注意此时在虚拟机中是串口1。 linux端程序(接收): #include stdio.h /*标准输入输出定义*/ #include stdlib.h /*标准函数库定义*/ #include unistd.h /*Unix 标准函数定义*/ #include sys/types.h #include sys/stat.h #include fcntl.h /*文件控制定义*/ #include termios.h /*PPSIX 终端控制定义*/ #include errno.h /*错误号定义*/ #d
[单片机]
stm32通用定时器用做外部脉冲计数器的例程
最近几天要用到stm32对外部输入脉冲进行计数,很自然想到定时器,可是手上资料没有讲解stm32定时器如何用作外部计数器的,在网上找例程,也没找到几个正确的,自己硬着头皮仔细研究参考手册,终于知道如何配置了,并写了一个例程,希望将来对一些网友有用。 其实stm32通用定时器做计数器,对外部脉冲计数,还是比较简单的,使用外部时钟模式2即可轻松实现,但要注意,这种模式下,外部输入脉冲信号一定要接在相应TIM的ETR引脚上,不能接在TIMx_CHy引脚上。 使用stm32定时器的外部时钟模式2,主要就是通过配置TIMx_SMCR寄存器相应位。步骤如下: 1. 若不需要滤波器,置TIMx_SMCR寄存器中的ETF =0000 2
[单片机]
单片机测交流电流
  电流传感器的4-20ma输出如何转换?   两线制电流传感器的输出为4~20 ma,通过250ω的精密电阻转换成1~5v或2-10v的模拟电压信号.转换成数字信号有多种方法,如果系统是在环境较为恶劣的工业现场长期使用,因此需考虑硬件系统工作的安全性和可靠性。系统的输入模块采用压频转换器件lm231将模拟电压信号转换成频率信号,用光电耦合器件tl117进行模拟量与数字量的隔离。   同时模拟信号处理电路与数字信号处理电路分别使用两组独立的电源,模拟地与数字地相互分开,这样可提高系统工作的安全性。利用压频转换器件lm231也有一定的抗高频干扰的作用。   电流输出型与电压输出型有哪些优劣比较?   在单片机控制的许多应用场合,都要
[单片机]
什么是单片机解密?单片机解密原理
单片机解密又叫芯片解密,单片机破解,芯片破解,IC解密,但是这严格说来这几种称呼都不科学,但已经成了习惯叫法,我们把CPLD解密,DSP解密都习惯称为单片机解密。 单片机(MCU)一般都有内部EEPROM/FLASH供用户存放程序和工作数据。什么叫单片机解密呢?如果要非法读出里的程式,就必需解开这个密码才能读出来,这个过程通常称为单片机解密或芯片加密。为了防止未经授权访问或拷贝单片机的机内程序,大部分单片机都带有加密锁定位或者加密字节,以保护片内程序;如果在编程时加密锁定位被使能(锁定),就无法用普通编程器直接读取单片机内的程序,单片机攻击者借助专用设备或者自制设备,利用单片机芯片设计上的漏洞或软件缺陷,通过多种技术手段,就可以
[单片机]
关于使用GD32 MCU实现位带操作的指南
MCS-51单片机可以简单的将P1口的第2位独立操作,如P1.2=0;P1.2=1,就是这样把P1口的第三个脚(BIT2)置0置1。对于32位ARM MCU 我们可以像51单片机一样单独的对某个端口的某一个IO单独操作吗?答案是可以的。并且这样就引入了“位带操作”的概念。简而言之,为了能够实现单独的位控制,所以就有了位带这样的操作机制。 ARM Cortex-M3处理器采用哈佛结构,可以使用相互独立的总线来读取指令和加载/存储数据。指令代码和数据都位于相同的存储器地址空间,但在不同的地址范围。程序存储器,数据存储器,寄存器和I/O端口都在同一个线性的4 GB的地址空间之内。这是Cortex-M3的最大地址范围,因为它的地址总线
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved