一、ADC简介
1.1 ADC
ADC(Analog to Digital Converter)即模数转换器,指一个能将模拟信号转化为数字信号的电子元件
1.2 ADC主要参数
分辨率
ADC的分辨率一般以输出二进制数的位数来表示,当最大输入电压一定时,位数越高,分辨率越高; n位的ADC能区分输入电压的最小值为满量程输入的1/2^n; 比如一个12位的ADC,最大输入电压为1.8v,那么该ADC能区分的最小电压为1.8v/2^12≈0.00044v,当转换的结果为m时,则 实际的电压值为m*(1.8v/2^12);
二、 Exynos4412下的ADC控制器
这4个引脚是ADC专用引脚。(本次实验实验XadcAIN3)
可选10位精度或者12位精度,有四个通道,最大转换速度1M s是采样 ps是秒,采样频率是1M/s。
他有一个前提ADC时钟是5MHz。每五个时钟采样一次。支持采样保持功能和低功耗模式
模拟输入范围是0-1.8V
PCLK是时钟源,是100M的,这里拿66M举例,当分频是65时,分频后的时钟频率就是1MHz
因为他五个周期采样一次,1MHz在除以5是ADC的转换频率,所以转换速度就是200kHz,频率的倒数就是转换周期,也就是5us。
但是注意,时钟频率不能超过5M,因为他的极限转换速度是1M。
三、ADC寄存器
控制寄存器、延迟寄存器、数据寄存器、中断功能寄存器、选择通道寄存器
RES: 设置精度是10位或12位
ECFLG:这个写的有问题,它是只读的位,如果转换完成则会自动置1,否则是0.
PRSCEN: 写1打开分频器,写0关闭分频器
PRSCVL:设置寄存器的分频倍数。如果你往这个区域写了个N,实际的分频倍数则是N+1。ADC的最大转换速度是1MHz,所以时钟频率不能超过5MHz,所以N一定要设置在19-255之间。
STANDBY: 1待机模式(低功耗模式),0正常模式
READ_START: ADC转化的数据会放入一个寄存器,读走数据就会自动进行下次转化,不读就停止转化。写1开启此模式,写0关闭
ENABLE_START:写1开始转换,然后自动变成0。如果开启READ_START模式,则此模式自动失效。
ADCADT寄存器:用于存储转化结果,只用[11:0]位,读的时候要将高20位清零,不然随机结果可能会影响结果。
ADCMUX寄存器:用于选择转换的通道。由于ADC只有一个,而我们有四个引脚支持ADC功能,所以采取分时复用模式,同一时间只有一个通道可以转化。(本次实验实验AIN3)
步骤:对ADCCON寄存器进行设置,然后选择转换的通道,然后设置ADCCON的[0]位开始转换,ADCCON的[15]位变成1,然后区ADCDAT寄存器读取转换结果。
四、ADC编程
#include "exynos_4412.h"int main()
{unsigned int AdcValue;/*将ADC的精度设置为12bit*/ADCCON = ADCCON | (1 << 16);/*使能ADC的分频器*/ADCCON = ADCCON | (1 << 14);/*设置ADC的分频 ADC时钟频率=PLCK/(19+1)=5MHz,ADC的转换频率=5MHz/5=1MHz*/ADCCON = ADCCON & (~(0xFF << 6)) | (19 << 6);/*关闭待机模式,使能正常模式*/ADCCON = ADCCON & (~(1 << 2));/*关闭通过读使能AD转换*/ADCCON = ADCCON & (~(1 << 1));/*选择转换通道 3通道*/ADCMUX = 3;while(1){/*开始转换*/ADCCON = ADCCON | 1;/*等待转换完成*/while(!(ADCCON & (1 << 15)));/*读取转换结果*/AdcValue = ADCDAT & 0xFFF;/*将结果转换成实际的电压值 =AdcValue*(1800/4096) mv*/AdcValue =AdcValue * 0.44;/*打印转换结果*/printf("AdcValue = %dmv\n", AdcValue);}return 0;
}
五、作业
1.编程实现通过LED状态显示当前电压范围
注:
电压在1501mv~1800mv时,LED2、LED3、LED4、LED5点亮
电压在1001mv~1500mv时,LED2、LED3、LED4点亮
电压在501mv~1000mv时,LED2、LED3点亮
电压在0mv~500mv时,LED2闪烁
#include "exynos_4412.h"void Delay(unsigned int Time)
{while(Time--);
}int main()
{unsigned int AdcValue;/*将ADC的精度设置为12bit*/ADCCON = ADCCON | (1 << 16);/*使能ADC的分频器*/ADCCON = ADCCON | (1 << 14);/*设置ADC的分频 ADC时钟频率=PLCK/(19+1)=5MHz,ADC的转换频率=5MHz/5=1MHz*/ADCCON = ADCCON & (~(0xFF << 6)) | (19 << 6);/*关闭待机模式,使能正常模式*/ADCCON = ADCCON & (~(1 << 2));/*关闭通过读使能AD转换*/ADCCON = ADCCON & (~(1 << 1));/*选择转换通道 3通道*/ADCMUX = 3;/*LED2*/GPX2.CON = GPX2.CON | (0x1 << 28);/*LED3*/GPX1.CON = GPX1.CON | 0x1;/*LED4*/GPF3.CON = GPF3.CON | (0x1 << 16);/*LED5*/GPF3.CON = GPF3.CON | (0x1 << 20);while(1){/*开始转换*/ADCCON = ADCCON | 1;/*等待转换完成*/while(!(ADCCON & (1 << 15)));/*读取转换结果*/AdcValue = ADCDAT & 0xFFF;/*将结果转换成实际的电压值 =AdcValue*(1800/4096) mv*/AdcValue =AdcValue * 0.44;/*打印转换结果*/printf("AdcValue = %dmv\n", AdcValue);if(AdcValue > 1501){GPX2.DAT = GPX2.DAT | (1 << 7);GPX1.DAT = GPX1.DAT | 1;GPF3.DAT = GPF3.DAT | (1 << 4);GPF3.DAT = GPF3.DAT | (1 << 5);}else if(AdcValue > 1001){GPX2.DAT = GPX2.DAT | (1 << 7);GPX1.DAT = GPX1.DAT | 1;GPF3.DAT = GPF3.DAT | (1 << 4);}else if(AdcValue > 501){GPX2.DAT = GPX2.DAT | (1 << 7);GPX1.DAT = GPX1.DAT | 1;}else{GPX2.DAT = GPX2.DAT | (1 << 7);Delay(1000000);GPX2.DAT = GPX2.DAT & (~(1 << 7));}}return 0;
}