您的位置:首页 > 其它

基于友善之臂ARM-ContexA9-ADC驱动开发

2016-02-21 13:40 351 查看
ADC,就是模数转换器,什么是模数转换器?

模数转换器,在电子技术中即是将模拟信号转换成数字信号,也称为数字量化。

当然还有一种叫DAC,就是数模转换,意思相反,即是将数字信号转换成模拟信号。

在友善之臂ARM-contexA9这款开发板上的4412芯片本身就自带了一个ADC的接口,我们来看看基本介绍:



数据手册开篇介绍了这么多,最有用的一句话:精度10位或12位CMOS模数转换器(ADC)包括多路模拟输入。灵敏度为1M,一共有4路输入,支持较低的电源模式等。

接下来我们还是跟以前一样:

1、先看电路原理图:





从原理图和核心板上可以看出可调电阻的IO对应数据手册的是AIN[0]。





2、看数字手册相关的寄存器

(1)ADC控制寄存器



寄存器的地址为:0x126C0000

在这里,我们要如何配置呢?

[0] 第0位:判断A/D转换有没有开始

[2] 第2位:配置模式位(正常的,标准的,我们这里选择默认为0)

[6:13]第6~13位:这里要配置预分频系数,我们配置为49,对应的公式就是:ADCCLK=PCLK/(49+10)=100MHZ / 50 =2MHZ

[14]第14位:选择使能预分频,写1到这个位去就可以了

[15]第15位:判断A/D转换结束了没有

[16]第16位:设置转换的精度(10或者12,自己选)

(2)ADC数据寄存器






基地址:0x126C000C

[11:0] 第0~11位:ADC转换的数据

(2)ADC通道选择寄存器






基地址:0x12C001C

ADCMUX[0:3]:这里我们配置为0000,也就是通道0

3、写代码

config.h

<span style="font-size:18px;">#ifndef	__CONFIG_H__
#define __CONFIG_H__

#define udelay	((void (*)(unsigned int ))0x43e25e88)     //定义udelay在uboot中的地址,这样我们就可以使用这个函数
#define print	((int (*)(const char *, ...))0x43e11434)  //定义printf在uboot中的地址

typedef unsigned int u32;
typedef volatile u32 v32;
//设置位
#define set_one(reg, bit)	\
((*(v32 *)reg) |= (1<<bit))
#define set_zero(reg, bit)	\
((*(v32 *)reg) &= (~(1<<bit)))
#define set_bit(reg, bit, val)	\
(*(v32 *)reg = (((*(v32 *)reg) & (~(1<<bit))) | (val << bit)))
#define set_2bit(reg, bit, val)	\
(*(v32 *)reg = (((*(v32 *)reg) & (~(3<<bit))) | (val << bit)))
#define set_nbit(reg, bit, n, val)	\
(*(v32 *)reg = (((*(v32 *)reg) & (~( ((1<<n)-1) <<bit))) \
| (val << bit)))
#define set_val(reg, val)	\
((*(v32 *)reg) = val)

#define get_bit(reg, bit)	\
(((*(v32 *)reg) & (1<<bit)) >> bit)
#define get_2bit(reg, bit)	\
(((*(v32 *)reg) & (3<<bit)) >> bit)
#define get_nbit(reg, bit, n)	\
(((*(v32 *)reg) & (((1<<n)-1) <<bit)) >> bit)
#define get_val(reg)		\
(*(v32 *)reg)

#endif</span>
adc.h

<span style="font-size:18px;">#ifndef	__ADC_H__
#define __ADC_H__

#define ADCCON 0x126C0000     //ADC控制寄存器
#define ADCDAT 0x126C000C     //ADC数据寄存器
#define ADCMUX 0x126C001C     //ADC通道寄存器
#define CLRINTADC	0x126C0018  //清除ADC中断

#endif</span>


adc.c

<span style="font-size:18px;">#include <adc.h>
#include <config.h>

void select_mux(void)
{
set_nbit(ADCMUX, 0, 4, 0x0);   //设置通道为通道0
}

void adc_init(void)
{
set_val(ADCCON, ((1<<16)|(1<<14)|(49<<6)));	//按照数据手册参数来配置adc控制寄存器的初始化部分
}

void adc_start(void)
{
set_one(ADCCON, 0);   //adc转换开始的配置,默认参数为0
}

int adc_wait_flag(void)
{
return get_bit(ADCCON, 15);<span style="white-space:pre">	</span>//AD转换是否成功
}

int adc_data(void)
{
return get_nbit(ADCDAT, 0, 12); //获取ADC数据
}

void clear_adc(void)
{
set_val(CLRINTADC, 0);<span style="white-space:pre">	</span>//清ADC
}</span>


main.c

<span style="font-size:18px;">#include <config.h>
#include <adc.h>
int main(void)
{
//设置ADC通道为通道0
select_mux();
//adc初始化
adc_init();
//adc转换开始
adc_start();
while(1)
{
//判断是否已经转换
if(adc_wait_flag())
{
//打印相应的数据
print("data = %d\n",adc_data());
//重新adc转换开始
adc_start();
}
}
return 0;
}</span>


4、makefile略

5、观察结果

先让uboot启动






然后用dnw下载程序:






最后旋转电阻观察数据变化:




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: