STM32与Proteus的串口仿真详细教程与源程序

ops/2024/10/20 18:51:27/

资料下载地址:STM32与Proteus的串口仿真详细教程与源程序

资料内容

包含LCD1602显示,串口发送接收,完美实现。
文档内容齐全,包含使用说明,相关驱动等。
解决了STM32的Proteus串口收发问题。    注意:每输入一个字符后,要按一次“手动发送”按钮,才能收到正确字符。

Proteus的串口仿真

打开串口调试助手,如图11-30所示。进入串口调试助手后,需要设置相关参数,串口号为图11-29所查到的端口号,其他参数根据实际程序来确定。打开串口后,按开发板上的reset按键,显示区就能接收到从开发板发送过来的“Welcome to HBEU”,每按复位键一次,就会接收一次,如图11-31所示;在发送区输入字符,如图11-32所示,点击“手动发送”,开发板上就能收到对应的字符,根据要求,不是以“x”结束的字符串,当超过20个字符后也接收到字符串。

图11-29 查看串口
   在Proteus中仿真串口时,先安装“虚拟串口”驱动,如图11-33所示,安装完之后也可以查看虚拟串口的端口号,查看方法与图11-29一致。在串口助手中设置好串口参数后,按Proteus中运行按钮,也可以在串口助手收到信息,如图11-34所示,注意串口波特率。

        由于Proteus没有对stm32的时钟树做仿真模型,只固定了一套时钟值,可以用GETSYS/HCLK/PCLK函数看。Proteus不是实时仿真,所以串口速率不是硬件速率对应的值,可能更高,可能更低,好在Proteus的虚拟终端是可以输入非标准波特率的,推荐波特率设为9600bit/s。另外,在Proteus仿真的程序中加了一条语句:
        RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
        若没有该系统配置语句,则看不到仿真效果。仿真时钟跟实际时钟存在一定的延时误差,在上位机发送数据时,一次发送一个字符串时,接收会出现乱码,因此需要一个一个字符发送,如图11-35所示,在发送区依次输入“e1x”之后(注意:每输入一个字符后,要按一次“手动发送”按钮),虚拟终端(Virtual Terminal)会显示所发送的所有字符,当STM32的串口接收到字符“x”后,表示结束,在LCD屏上显示“e1”。
        为了接收方便,将最多发送20个字符改为最多发送5个字符,当我们依次输入“123456”后(注意:每输入一个字符后,要按一次“手动发送”按钮),LCD显示收到的字符串“12345”,如图11-36所示。

 

图11-35  STM32串口遇到“x”结束接收   图11-36  STM32串口收到6个字符自动结束 

程序代码

#include "stm32f10x.h"
#include "stdio.h"
//#include "led.h"
#include "delay.h"
#include "lcd1602.h"uint8_t USART_RXBUF[5];
extern uint8_t RXOVER;
/* Private function prototypes -----------------------------------------------*/
void NVIC_Configuration(void);
//void Delay_Ms(uint32_t nTime);
void USART_Config(void);
//void USART_SendString(int8_t *str);
void USART_SendString(unsigned char *buf);int main(void)
{uint8_t i;RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//SysTick_Init();SysTick_Config(SystemCoreClock/100000);GPIO_Configuration(); LCD1602_Init();LCD1602_Show_Str(0,0,"Receive:");        USART_Config();//USART_SendString(Tx_Buf);//发送字符串USART_SendString("Welcome to HBEU\r\n");//发送字符串while(1){if(RXOVER == 1){LCD1602_Show_Str(0,2,USART_RXBUF);                for(i=0;i<5;i++){USART_RXBUF[i] =' ';  //清空接收区}RXOVER = 0;USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);/}/*if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET){USART_SendData(USART1,USART_ReceiveData(USART1));delay_ms(1000);}*/}
}/*void USART_Config(void)
{GPIO_InitTypeDef  GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);//RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//NVIC_Configuration();//配置USART2 TX引脚工作模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//配置USART2 RX引脚工作模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);//串口2工作模式配置USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_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);//USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);USART_Cmd(USART1, ENABLE);
}*/void USART_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 打开串口GPIO的时钟//DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);// 打开串口外设的时钟//DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);NVIC_Configuration();// 将USART Tx的GPIO配置为推挽复用模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);// 将USART Rx的GPIO配置为浮空输入模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置串口的工作参数// 配置波特率USART_InitStructure.USART_BaudRate = 9600;// 配置 针数据字长USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 配置停止位USART_InitStructure.USART_StopBits = USART_StopBits_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);// 使能串口USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1, ENABLE);            
}/*** @说明     USART2字符串发送函数* @参数     str: 指向字符串的指针* @返回值   None*/
/*void USART_SendString(int8_t *str)
{uint8_t index = 0;do{USART_SendData(USART1,str[index]);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);index++;        }while(str[index] != 0);  //检查字符串结束标志}*/void USART_SendString(unsigned char *buf)
{while (*buf != '\0'){while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);USART_SendData(USART1, *buf++);}
}/*** @说明     配置中断向量控制器* @参数     None* @返回值   None*/
void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* Enable the RTC Interrupt */NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}


http://www.ppmy.cn/ops/25424.html

相关文章

Maven如何解决jar包冲突的问题?

在使用Maven进行项目构建的应用中&#xff0c;如果在应用运行期发生了NoSuchMethodError、ClassNotFoundException等异常或者错误时&#xff0c;需要考虑Jar包冲突的问题。 如果在应用中&#xff0c;我们同时依赖了两个第三方的jar包A&#xff0c;B&#xff0c;而A&#xff0c;…

使用Vue实现返回到上一个页面的时候进行参数的传递

需求&#xff1a;点击按钮进入到下一个页面&#xff0c;在新的页面进行一系列操作&#xff0c;操作完成之后点击按钮会返回到上一个页面&#xff0c;返回的时候还要携带这个页面的一些数据。 实现方式&#xff1a;使用组件内守卫&#xff0c;在组件进入到上一个页面时使用路由…

深入理解C语言中的 extern`和 static

1. extern 关键字 定义和用途 extern 关键字用于声明一个变量或函数&#xff0c;表示其定义在另一个文件或本文件的其他位置。使用 extern 可以在多个文件之间共享全局变量或函数。 示例 假设有两个源文件&#xff1a;main.c 和 helper.c。 helper.c #include <stdio.…

react-mosaic-component-一个React库--窗格布局

import { Mosaic, MosaicWindow, MosaicZeroState } from "react-mosaic-component";从名为react-mosaic-component的npm包中引入三个组件&#xff1a;Mosaic&#xff0c;MosaicWindow和MosaicZeroState。 react-mosaic-component是一个React库&#xff0c;用于创建…

笨蛋学C++【C++基础第六弹】

C基础第六弹 C面向对象1.C类 & 对象1.1C类定义1.2C对象1.3访问数据成员1.4类成员函数1.5类访问修饰符公有public成员私有private成员受保护protected成员继承中的特点 1.6构造函数 & 析构函数类的构造函数带参数的构造函数使用初始化列表来初始化字段类的析构函数 1.7拷…

JAVA面试题分享---多线程与线程池

多线程 什么是线程?线程和进程的区别?&#xff08;了解&#xff09; 线程&#xff1a;是进程的一个实体&#xff0c;是 cpu 调度和分派的基本单位&#xff0c;是比进程更小的 可以独立运行的基本单位。 进程&#xff1a;具有一定独立功能的程序关于某个数据集合上的一次运…

Spring Boot的热部署工具“AND”Swagger测试工具

Spring Boot的热部署&Swagger测试页面的使用 热部署指的是在项目无需重启的情况下&#xff0c;只需要刷新页面&#xff0c;即可获得已经修改的样式或功能。要注意该工具一般用于开发环境&#xff0c;在生产环境中最好不要添加这个工具。 对于无需重启便可刷新这么方便的工…

手持LED弹幕,超炫特效,让你的每一次出场都耀眼夺目!

在这个快节奏的数字时代&#xff0c;沟通不再局限于言语和文字&#xff0c;就连表白、追星、晚会互动&#xff0c;甚至日常的提词都需要一点科技的火花来点燃气氛。于是&#xff0c;手持LED弹幕滚动屏&#xff0c;这个集实用与趣味于一身的神器&#xff0c;悄然成为了社交场上的…