之前用F1C100s的音频ADC(FMIN、LINEIN)拿来采集模拟电压,但发现音频ADC内部应该有滤波电路之类的,输入阻抗低,所以要求输入信号是高阻抗的才行。毕竟是为音频应用设计的,没打算给人当通用ADC用。
比如把电池电压用两个几十K的电阻分压,或把热敏电阻串一个几十K的电阻测温度,这种情况不能直接把分压端接到ADC上。ADC引脚内部的电路会对分压产生影响,而且是非线性的。更坑的是每片IC还不一致,同样条件下测量出来也会不一样。
所以,对于用ADC采集分压的使用情况,有两个方法:
一是加个便宜的运放做电压跟随,提高输入阻抗,测量的就很准了。
二是用KEYADC(LRADC)。LRADC内部是先经过运放,所以小信号直接输入没问题。缺点是精度只有6bit,量个电池电压勉强够用。
离线
Quotation,你好,我用了你在这个帖子里面的音频ADC驱动,
https://whycan.cn/t_1728.html ,用裸机跑的,参考的这个帖子:
烧进去以后,发现程序一直卡在
while (((read32(0x01C23C00 + ADC_FIFOS) >> 23) & 1) == 0)
{
}
这里。
CCU相关的代码我也加进去了,配置CCU_BUS_CLK_GATE2、CCU_ADDA_CLK、
CCU_PLL_AUDIO_CTRL这几个,还是在while循环这里卡着。
研究了几天也没找出问题,请问这种情况一般是哪里出了问题?
离线
在Quotation的帮助下,ADC卡在while循环的原因找到了。
AUDIO_CODEC _CLK_REG的最高位置1才能打开Gating Special Clock,我看成了最低位。
初始化代码如下:
/* GATE2 */
val = read32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE2);
val |= (0x1);
write32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE2, val);
sdelay(100);
/* AUDIO_CODEC_CLK_REG */
write32(F1C100S_CCU_BASE + CCU_ADDA_CLK, 0x1 << 31);
sdelay(100);
/* CTRL */
val = read32(F1C100S_CCU_BASE + CCU_PLL_AUDIO_CTRL);
val |= (0x1 << 31);
write32(F1C100S_CCU_BASE + CCU_PLL_AUDIO_CTRL, val);
sdelay(100);
/* reset bus */
write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST2, 0x1);
sdelay(100);
最近编辑记录 duckduckgo (2019-02-22 14:34:59)
离线
感谢分享, 音频输入做ADC用,好思路!
离线
@Quotation 你好!我之前是用KEYADC,但是由于精度不够,现在想用音频ADC,想请教两个问题。
1、请问下音频ADC的参考电压怎么设置?我一直没找到那个寄存器,还是说参考电压是直接给某个引脚呢。
2、音频ADC输入检测是分正负的吧,相当于我做ADC检测的时候要把电压分压为正常的一半吗?
离线
@Quotation 你好!我之前是用KEYADC,但是由于精度不够,现在想用音频ADC,想请教两个问题。
1、请问下音频ADC的参考电压怎么设置?我一直没找到那个寄存器,还是说参考电压是直接给某个引脚呢。
2、音频ADC输入检测是分正负的吧,相当于我做ADC检测的时候要把电压分压为正常的一半吗?
1. 参见这篇 https://whycan.cn/t_1727.html ,由AVCC电压决定的。
2. 需不需要分压看输入电压范围,范围也由AVCC决定。
离线
@Quotation 谢谢你了!挖坑网真是个不错的网站!
离线