为什么 PIC32 上的某些模拟引脚在断开连接时报告为零,而其他模拟引脚则报告非零?
我正在使用 PIC32MX534F064L (数据表),并尝试阅读其一些模拟引脚(标记为 AN0 至 AN15)。
由于这些引脚都没有连接到任何东西,我希望读取到零值。相反,在 AN0 到 AN5 上,我读取了 650 到 900 之间的值。仅从其余部分(AN6 到 AN15)我得到的值为零。
当每个引脚连接到源时,它们会正确报告。每个引脚(AN0 到 AN15)将报告 0(表示 0.0V)和 1023(表示 3.3V)。
我尝试对值进行成对采样,并分别对每个值进行采样。无论是一起采样还是分开采样,AN0 都会报告非零值(通常在 700-800 左右),AN13 将报告 0。
我的第一个想法是我未能正确设置 ADC。这是我的代码:
#include <stdio.h>
#include <plib.h>
unsigned int an0;
unsigned int offset;
char buffer[100];
int main(void)
{
SYSTEMConfigPerformance(72000000L);
CloseADC10();
#define ADC_CONFIG1 ADC_MODULE_ON | ADC_FORMAT_INTG | \
ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON
#define ADC_CONFIG2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | \
ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_2 | \
ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON
#define ADC_CONFIG3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15
#define ADC_CONFIGSCAN SKIP_SCAN_ALL
#define ADC_CONFIGPORT ENABLE_AN0_ANA
SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN0 );
OpenADC10( ADC_CONFIG1, ADC_CONFIG2, ADC_CONFIG3, \
ADC_CONFIGPORT, ADC_CONFIGSCAN );
EnableADC10();
while ( ! mAD1GetIntFlag() ) { }
while (1)
{
offset = 8 * ((~ReadActiveBufferADC10() & 0x01));
an0 = ReadADC10(offset);
sprintf(buffer, "AN0 = %u", an0);
}
return 0;
}
查看 PIC 的数据表,我注意到两件事:
引脚 AN0 到 AN5(错误报告非零值的引脚)也是 CNx 引脚。这些引脚是“更改通知”引脚,旨在当引脚上的值发生变化时引发中断。
有一个可以在所有 CNx 引脚上启用的“弱上拉”。
因此,我尝试使用以下行禁用“弱上拉”:
mCNClose();
这会禁用所有 CNx 引脚及其上拉。可悲的是,这没有帮助。当我检查 CN 上拉寄存器的值时(CNPUE
我还能尝试什么?我的代码中做错了什么吗?
I am using a PIC32MX534F064L (datasheet), and trying to read several of its analog pins (marked AN0 to AN15).
With none of those pins connected to anything, I expect to read a value of zero. Instead on AN0 through AN5 I read values between 650 and 900. Only from the rest (AN6 through AN15) I get a value of zero.
When each of the pins is connected to a source, they report correctly. Each of the pins, AN0 through AN15 will report 0 for 0.0V, and 1023 for 3.3V.
I've tried sampling the values in pairs, and each separately. Whether sampled together or apart, AN0 will report non-zero values (usually around 700-800), and AN13 will report 0.
My first thought was that I somehow failed to properly set up the ADC. Here's my code:
#include <stdio.h>
#include <plib.h>
unsigned int an0;
unsigned int offset;
char buffer[100];
int main(void)
{
SYSTEMConfigPerformance(72000000L);
CloseADC10();
#define ADC_CONFIG1 ADC_MODULE_ON | ADC_FORMAT_INTG | \
ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON
#define ADC_CONFIG2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | \
ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_2 | \
ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON
#define ADC_CONFIG3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15
#define ADC_CONFIGSCAN SKIP_SCAN_ALL
#define ADC_CONFIGPORT ENABLE_AN0_ANA
SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN0 );
OpenADC10( ADC_CONFIG1, ADC_CONFIG2, ADC_CONFIG3, \
ADC_CONFIGPORT, ADC_CONFIGSCAN );
EnableADC10();
while ( ! mAD1GetIntFlag() ) { }
while (1)
{
offset = 8 * ((~ReadActiveBufferADC10() & 0x01));
an0 = ReadADC10(offset);
sprintf(buffer, "AN0 = %u", an0);
}
return 0;
}
Looking in the PIC's datasheet, I noticed two things:
The pins AN0 to AN5, the ones mis-reporting non-zero values, are also CNx pins. These pins are "Change Notification" pins, that are meant to raise an interrupt when the value on the pins changes.
There is a "weak pull-up" that can be enabled on all CNx pins.
So I tried disabling the "weak pull-up" by using this line:
mCNClose();
Which disables all the CNx pins and their pull-ups. Sadly, this did not help. And when I checked the value of the CN-pull-up-register (CNPUE
What else can I try? Am I doing something wrong in my code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
那么,你的期望是错误的!
源的最小输入电阻应仅为几千欧姆,请检查数据表。
如果 ADC 引脚悬空(未连接),内部寄生电流的不可预测值将导致测量值大于 0。请记住 ADC 采样电容器只有几个 pF 容量,因此悬空引脚也可以在外部 EM 的宽电压范围内振荡(电磁)影响。
因此,在 ADC 引脚上连接至少 1M 电阻来下拉电压,下拉电阻的阻值取决于 ADC 采样时间。如果 ADC 采样时间短,则减小电阻的下拉值。
编辑:
查看数据表第214页参数AD17:模拟电压推荐阻抗源为 5 KOhms。 AD15 表示最大。 ADC 输入引脚上的漏电流可为 +/-0.61 uA。
Well, your expectation is wrong!
The minimum input resistance for source should be only few kilo ohms check datasheet.
If ADC pins is floating (not connected) the unpredicted value of internal parasitic current will cause that measuring value will be bigger than 0. Remember the ADC sample capacitor has only few pF capacity so floating pins can oscillate in wide voltage range also from external EM (electromagnetic) influences.
So, connect at least 1M resistors to pull down voltage on ADC pin, the resistance of pull down resistor is depended of ADC sample time. If ADC sample time is short than decrease the pull down value of resistor.
EDIT:
Check datasheet page 214 parameter AD17: Recommended Impedance of Analog Voltage Source is 5 KOhms. And AD15 say that that max. Leakage Current on ADC input pins can be +/-0.61 uA.
这可能只是噪声,因为当没有连接任何东西时输入处于高阻抗。尝试将输入接地(连接到 0V)作为实验 - 然后值应该接近 0。如果您需要在未连接任何东西时将输入设置为零,则将下拉电阻器连接到每个输入(在输入和 0V 之间)降低阻抗 - 10k 欧姆的值就可以了。
It's probably just noise, since the inputs are high impedance when nothing is connected. Try grounding the inputs (connect to 0V) as an experiment - the values should then be close to 0. If you need the inputs to be zero when nothing is connected then connect a pull-down resistor to each input (between input and 0V) to lower the impedance - a value of 10k ohms should do it.
不要让引脚处于未连接状态!未连接的引脚本质上是一个天线,可以拾取 Vss 和 Vdd 范围之外的电压。数据表第 2.10 节规定不要让任何引脚保持未连接状态(或者如果这样做,请将它们配置为输出并将它们驱动为低电平。)
如果您想测试 A2D,您可以将引脚配置为数字输出(仅限模拟设置)覆盖数字输入),然后将其驱动为高电平和低电平进行测试。
Do not leave pins unconnected! The unconnected pin is essentially an antenna which could pick up voltages outside of the Vss and Vdd range. Section 2.10 of the datasheet says to not leave any pins unconnected (or if you do, configure them as outputs and drive them low.)
If you want to test your A2D, you can configure the pin as a digital output (the analog setting only overrides the digital input) and then drive it high and low to test.