一、ADC原理
模数转换器即A/D转换器,或简称ADC,通常是指一个将模拟信号转变为数字信号的电子元件。
对于数字信号我们需要得到它的几个属性:
- 用多少位来存储这个数据(假设10bit)。
- 最大值0b111111111
- 模拟信号输入的最大值是多少=>它对应的电压是多少伏
我们就可以根据模拟信号(电压)的最大值,来计算出对应的数值。
比如0b111111111为3.3v 那么0b111111111>>1就为1.65v - 采样/转换速度。
对于程序员,我们不关心ADC的内部机制,我们只关心:
- 怎么启动ADC
- 启动之后怎么得到数据,
总之:我们都是通过寄存器操作的。
从图可以看出ADC有8个多路选择器,显然,以后我们写程序的时候,我们可以8个多路选择之一。
下面是编写程序要做的步骤:
我们选择正常模式编程
- 确定是哪一路信号:设置8:1MUX,选择要测量哪一个引脚(看原理图选择要测量的引脚)
- 设置工作时钟(从公式中,可以算出转换一次,需要多长时间)
启动 - 读状态,判断ADC转换是否成功。
- 读数据
看原理图选择要测量的引脚AIN0:
将ADC的AIN0引脚接入到这个模块上,就可以使用ADC了
实物图:
二、ADC编程
PCLK frequency is 50MHz and the prescaler value is 49, total 10-bit conversion time is as follows.
A/D converter freq. = 50MHz/(49+1) = 1MHz
Conversion time = 1/(1MHz / 5cycles) = 1/200KHz = 5 us
ADCCON | val |
---|---|
ECFLG [15] | 1 = End of A/D conversion 表示转换结束 |
PRSCEN [14] | 1 = Enable 预分频 |
PRSCVL [13:6] | 预分频系数=49 ==> PCLK/(49+1) = 1MHz |
SEL_MUX [5:3] | 000 = AIN 0 |
STDBM [2] | 0 = Normal operation mode |
ENABLE_START [0] | 1 = A/D conversion starts and this bit is cleared after the start- up |
#include "../s3c2440_soc.h"
void adc_init(void)
{
/* [15] : ECFLG, 1 = End of A/D conversion
* [14] : PRSCEN, 1 = A/D converter prescaler enable
* [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1)
* [5:3] : SEL_MUX, 000 = AIN 0
* [2] : STDBM
* [0] : 1 = A/D conversion starts and this bit is cleared after the startup.
*/
ADCCON = (1<<14) | (49<<6) | (0<<3);
ADCDLY = 0xff; //等待转换时间
}
int adc_read_ain0(void)
{
/* 启动ADC */
ADCCON |= (1<<0);
while (!(ADCCON & (1<<15))); /* 等待ADC结束 */
return ADCDAT0 & 0x3ff;
}
vol = (double)val/10233.3; / 1023----3.3v */
(1023是0x11,1111,1111的16进制)
#include "adc.h"
void adc_test(void)
{
int val;
double vol;
int m; /* 整数部分 */
int n; /* 小数部分 */
adc_init();
while (1)
{
val = adc_read_ain0();
vol = (double)val/1023*3.3; /* 1023----3.3v */
m = (int)vol; /* 3.01, 整数部分m = 3 */
vol = vol - m; /* 小数部分: 0.01 */
n = vol * 1000; /* 只要3位有效位 */
/* 在串口上打印 */
printf("vol: %d.%03dv\r", m, n); /* 3.010v */
/* 在LCD上打印 */
//fb_print_string();
}
}