Proteus仿真STM32的系列问题(供电网、串口、ADC读取问题)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

前言

这是我个人在做Proteus仿真过程中遇到的一些问题以及解决方法,希望对大家有帮助!

一、供电网配置

原理图连接完后的重要一步,在菜单栏的设计里点击“配置供电网”,选择需要连接到GND和VCC/VDD端口。 仿真提示错误“VCC and GND nets are connected - check net GND! ”。
搜索以下经验贴,说要把VSSA、VDDA都加进来VCC/VDD,但结果还是错误。然后搜了一下VSSA是公共地的意思,把这一项加到GND后,问题解决!
https://blog.csdn.net/laoxue123456/article/details/120596516
http://www.51hei.com/bbs/dpj-191206-1.html
在这里插入图片描述

二、串口调试

虚拟终端(Virtual Terminal)没有显示或者乱码的解决方法。
一定要在proteus原理图点击MCU进行编辑,在OSC Frequency里设置主频(别人分享的是Crystal Frequency这一项,可能是软件版本或者芯片不一样),这里我在CubeMx设置主频是32Mhz,所以在Proteus也需要相应输入32Mhz,否则仿真会报错:[RCC] APB1 is overclocked。
在这里插入图片描述

三、关于stm32 ADC采样输出为0的问题

1. ADC数值不为0而转换电压为0的问题

这个问题是由转换公式数据类型不匹配造成的,原公式为ADC_Voltage = ADC_Value / 4096 * 3.3,把4096更换为4096.0后解决问题,因为输出电压ADC_Voltage为浮点型数据。

2. ADC数值为0的问题

我用的proteus8.15版本,然后用F103C8做的仿真,感觉是这款芯片的模型有问题,我后来换成F103C6后ADC就能正常输出数值了。(如下图第一个值是ADC值,第二个值是电压值)
在这里插入图片描述

3. 关于ADC在DMA模式下数值为0或者数值输出不对的问题

(1)数值输出恒为0:把开启DMA语句放入while循环后问题解决。

HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_Value, 2);// 参数2表示开启2个ADC通道

(2)采集数值不对的问题:要根据CubeMax中设置的Data Width定义函数类型,我设置的half word,所以定义如下:

uint16_t ADC_Value[2]; //存放两个ADC通道的值

仿真结果如下:
在这里插入图片描述

4. 附上CubeMx配置以及相应代码

4.1 单通道轮询模式读取数据

(1) CubeMx配置如下

#RCC配置(左图)和ADC配置(右图)

#NVIC配置(左)和串口配置(右)

#时钟配置,这里根据自己需要配置,我直接选择的默认时钟

(2) 代码如下

\\加宏定义(因为用了sprintf和strlen函数)

#include "stdio.h"
#include "string.h"

\\在main函数中定义变量

uint16_t ADC_Value; //存放ADC值
float ADC_Vol; //存放电压值
char str[64];

\\在ADC初始化函数后加这一句

HAL_ADCEx_Calibration_Start(&hadc1); //校准

\\在while循环中添加

HAL_ADC_Start(&hadc1); //开启AD转换
ADC_Value = HAL_ADC_GetValue(&hadc1); //获得AD值
ADC_Vol = ADC_Value/4096.0*3.3; //转换电压值
sprintf(str,"%d, %.3f\r\n",ADC_Value, ADC_Vol); //数据写入字符串
HAL_UART_Transmit(&huart1,(uint8_t*)str,strlen(str),HAL_MAX_DELAY);//串口发送

4.2 双通道DMA模式读取数据

(1) CubeMx配置如下(其他配置跟单通道一样)

在这里插入图片描述
在这里插入图片描述

(2) 代码如下

\\在main函数中定义变量

uint16_t ADC_Value[2];
uint16_t adc1, adc2;
int i;
float ADC_Vol_1, ADC_Vol_2;
char str[128];

\\在while循环中添加

HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_Value, 2); 
for(i=0,adc1=0,adc2=0; i < 10; i++)
{
	adc1 += ADC_Value[0];
	adc2 += ADC_Value[1];
}
ADC_Vol_1 = (float) adc1/i/4096.0*3.3;
ADC_Vol_2 = (float) adc2/i/4096.0*3.3;	
sprintf(str,"Voltage_1 = %.4fV, Voltage_2 = %.4fV\r\n", ADC_Vol_1,ADC_Vol_2);
HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), HAL_MAX_DELAY); 

总结

本人也是新手,第一次用Proteus,更是第一次写博客,以上内容仅供参考,如果有写的不对欢迎大家批评指正!

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值