GD32F103,ADC采样端口对电压的影响问题,未解决!!!(已解决!!!)

  1. 设计采集卡,使用了ADC1、ADC2、ADC3,发现ADC采样的通道电压不对,模拟量输入端未0V,输出采用LM358跟随,在ADC采集过程中,发现LM358的输出电压并不为0V,而是为0.2V。
  2. 开始以为线路短路或是LM358的问题。后来停止采集(此时ADC1通道切换了),发现LM358的输出为0V,如果停在此采样通道(调试),发现电压还在缓慢上升,判定LM358没有问题,是GD32模拟采集的问题。
  3. 使用显微镜,发现引脚并没有短路的情况,继续查找原因。通过单步调试发现,在ADC初始化过程中,在使端口变成模拟量(PA-PA7)的时候,输入采样端口的电压会变化,而且变化的一定是ADC1所在通道(此时ADC并没有初始化,当然其默认通道为0通道,测试的是PA0引脚电压),此时PA0电压为0.6V左右,此时LM358的输入为0V,其输出理论也为0V(当然xmV电压忽略)。
  4. 初始化ADC123,此时PA0电压还是为0.6V左右,切换ADC1采样通道到PA1(CH1),此时PA0上的电压变为0.2V左右,切换ADC3通道为7通道(PA7),PA0电压还是为0.2V。
  5. ADC1通道切换到PA6通道,发现PA0通道变为0V(10mV以内),PA6通道电压为0V(10mV以内)。
  6. 问题还未解决,有知道的小伙伴告知一声。.

问题发现及解决:

  1. 使用了另一款板,焊接的同一批次GD32,问题依旧。发出去的那么多东西改怎么办!
  2. 我做了很多通道的ADC采集,大约30个通道的数据,用了芯片的8路ADC输入接口。电路设计上,凡是不接传感器的输出都是0V,唯独有2路位移信号(3.3V供电)做了开路通过LM358 跟随后给GD的ADC采集。没有下拉,在没有接传暗器的时候,LM358输出的电压会很高,LM358供电电压为5V,其最大输出不会超过3.6V,芯片引脚FT。我想着没事。
  3. 在测试过程中,我发现把位移传感器连接上后,发现其他通道数据正常了,想着有没有可能是LM358输出电压过高导致GD32模拟开关漏电流增加了(GD32的IO为3.3V供电,超过了电压,FT虽然可以保护,但是其漏电流变大),于是果断在传感器接口处下拉了1Mohm的电阻(没有找到10M的),问题没有出现了。
  4. 为什么STM32没有出现此问题,待会我还会继续测试,有一个可能是其IO设计较GD耐压高一些,图1是STM32中的数据手册说明的IO输入电压,由图3可以看出,STM32的ADC实际上输入的模拟电压可以到3.9V(3.3V供电,参考3.3V)。图4为GD32的IO参数特性,图5为GD32的ADC参数,手册内并没有ADC结构的说明。图1 通用IO图1 通用IO
    图2 STM32ADC参数图2 STM32ADC参数

图3 STM32ADC输入引脚图图3 STM32ADC输入引脚图

在这里插入图片描述
图4 GD32F103的输入输出电压

在这里插入图片描述图5 GD32F103 ADC参数

从用户手册可以看出,STM32的模拟配置结构图如图6所示,GD32的模拟配置的结构图如图7所示。从这些资料分析,估计STM32 针对模拟输入一样的做了保护,其中二极管导通电压为0.6V左右,这样如果我的输入不超过3.9V,对模拟开关应该没有运行。而按照图示,GD32如果模拟量超过了3.3V,他将运行模拟开关,这将导致如果在ADC1模拟开关内,有一个通道的电压超过了3.3V,超过的电压产生的电流将通过模拟开关流入到采样的IO中,这样的电流有点大(如果跟随输出的信号到GD之间没有电阻的话,中间几乎没有负载),这也将导致前面的问题,使得被采样的端口电压抬升,(可以想象,LM358跟随的电流足够大了,这个都被影响了,幸好我连接了10R电阻)。

此为个人猜想观点。
在这里插入图片描述图6 STM32 ADC输入用户手册给出的结构图
在这里插入图片描述图7 GD32 ADC模拟量时用户手册给出的结构图

5

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
GD32F103 是一款基于ARM Cortex-M3内核的微控制器,它有多个模拟数字转换器(ADC)模块可用于测量电压。下面是一些基本的步骤: 1. 确定要测量的电压范围,以及需要的分辨率 2. 初始化ADC模块,包括设置采样速率、输入通道和参考电压等参数 3. 配置ADC转换触发方式,例如定时器触发或软件触发 4. 开始ADC转换,并等待转换完成 5. 读取ADC转换结果,并将其转换为电压值 以下是一个简单的示例代码,可以用于ADC采集电压: ```c #include "gd32f10x_adc.h" void adc_init(void) { /* enable ADC clock */ rcu_periph_clock_enable(RCU_ADC); /* configure ADC */ adc_deinit(ADC0); adc_mode_config(ADC_MODE_FREE); adc_channel_length_config(ADC_REGULAR_CHANNEL, 1); adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5); adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE); adc_enable(ADC0); /* enable software trigger */ adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL); } float adc_get_voltage(void) { uint16_t adc_val; float voltage; /* start ADC conversion */ adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL); /* wait for conversion to complete */ while(!adc_flag_get(ADC0, ADC_FLAG_EOC)); /* read ADC value and convert to voltage */ adc_val = adc_regular_data_read(ADC0); voltage = (float)adc_val * 3.3 / 4096.0; return voltage; } ``` 这个例子中,我们使用了ADC0模块来采集电压。我们设置了采样时间为55.5个时钟周期,并使用了软件触发方式。在`adc_get_voltage()`函数中,我们启动了ADC转换,并等待转换完成。然后,我们读取ADC值,并将其转换为电压值。最后,我们返回电压值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值