ADC的基本原理及编写基于ARM的裸机程序的方案解析

一口Linux
关注

通道选择

由上图可知,A/D控制器一共有4个通道,通用寄存器地址为0x126c0000。

A/D控制器寄存器

对ADC控制器的操作主要是通过配置寄存器来实现的,查看datasheet,必须掌握寄存器的使用。以下是A/D控制器寄存器汇总。

1、A/D控制寄存器ADCCON

   RES     : 选择A/D转换精度,0:划分成1024份  1:划分成4096份

   ECFLG   :转换是否结束  0:转换中  1:转换完毕;对于轮询模式需要根据该位判断数据是否转换完毕。

   PRSCEN:A/D转换预分频是否使能

   PRSCVL:预分频的值,转换公式见下面

   STANDBY:待机模式  0:正常工作模式 1:待机模式。处于待机模式时要将PRSCEN设置为0

   READ_START: A/D转换由读操作触发,设置为1后,每次读取A/D值的操作都会触发一次A/D转换。

   ENABLE_START: 单次开启A/D转换,转换完毕后该位自动清零,当READ_START设置为1的时候,该位无效。

通常设置值为(1 << 16 | 1 << 14 | 99 <<6 | 1 << 1)。

2、A/D转换数据寄存器ADCDAT0

注意该寄存器的值只有低12位有效。

3、A/D清中断寄存器CLRINTADC

黄色部分可知,中断例程负责清中断,中断结束后写入任意值就可以清中断。

4、A/D通道选择寄存器ADCMUX

每次操作都要先设置通道,因为 4个通道是共用同一套寄存器,如果有其他任务也在使用A/D,就会产生混乱。在此我们选择通道3,置3即可。

5、ADC中断ID

参见9.2.2GIC Interrupt Table

由此可知,ADC中断号对应的SPI值是10,inturrupt ID 为42。对于终端查询方式和编写终端的驱动需要知道SPI id和inturrupt ID,后面讲解基于Linux驱动还会再分析设备树节点如何填写。

6、Combiner中断控制器

combiner的配置寄存器:IMSRn、IECRn、ISERn、ISTRn,类似于GPIO 对中断源分组。只有中断模式才需要考虑combiner中断控制器的操作。

7、Combiner分组

参考章节:10.2.1Interrupt CombinerTable 10-1Interrupt Groups of Interrupt Combiner

可见ADC在INTG10,即第10组。

8、Combiner IESR2

参考章节:10.4.2.9IESR2

如果要用中断模式设置为1即可。

9、Combiner IECR2

参考章节:10.4.2.10IECR2

此处用于关闭中断,采用默认值即可,注意,如果设置了1,那么中断功能就关闭了。

10、A/D转换的转换时间计算

例如:PCLK为100MHz,PRESCALER = 65 ;所有10位转换时间为

100MHz/(99+1) = 1MHz

转化时间为1/(1MHz/5 cycles) = 5us。

完成一次A/D转换需要5个时钟周期。A/D转换器的最大工作时钟为5MHz,所以最大采样率可以达到1Mit/s.

电路连接图

由该电路图可知,外设是一个滑动变阻器,根据接触点的不同,会导致输入电压的模拟值不同。连接的A/D控制器通道为3。该电路利用一个电位计输出电压到4412的AIN3管脚。输入的电压范围为0~1.8V。

ADC裸机开发程序实例

ADC数据的读取通常由2种方法:中断模式、轮训模式。

轮训模式

轮询模式读取数据步骤如下:

1.要读取数据首先向ADC寄存器ADCCON的bit:1写1,发送转换命令,采用读-启动模式来开启转换。

2.当ADC控制器转换完毕会将ADCCON的bit:15设置为1,

3.轮询检测ADCCON的bit:15是否设置为1,如果设置为1,就读走数据,否则继续等待。

这种方式比较占用CPU资源。

//注:这里使用读-启动模式

**********************ADC *****************
#define   ADC_CFG  __REG(0x10010118)
#define  ADCCON  __REG(0x126C0000)
#define  ADCDLY  __REG(0x126C0008)
#define  ADCDAT  __REG(0x126C000C)
#define  CLRINTADC __REG(0x126C0018)
#define  ADCMUX  __REG(0x126C001C)
#include "exynos_4412.h"
#include "pwm.h"
#include "uart.h"
unsigned char table[10] = {'0','1','2','3','4','5','6','7','8','9'};
void mydelay_ms(int time)

 int i, j;
 while(time--)
 {
   for (i = 0; i < 5; i++)
   for (j = 0; j < 514; j++);
 }

adc_init(int temp)

 ADCCON = (1 << 16 | 1 << 14 | 99 <<6 | 1 << 1);
 ADCMUX = 3;
 temp = ADCDAT & 0xfff;

*  裸机代码,不同于LINUX 应用层, 一定加循环控制

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存