如何编写基于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 应用层, 一定加循环控制
图片新闻
最新活动更多
-
11月22日立即报名>> 【线下论坛】华邦电子与莱迪思联合技术论坛
-
即日-11.30免费预约申请>>> 燧石技术-红外热成像系列产品试用活动
-
11月30日立即试用>> 【有奖试用】爱德克IDEC-九大王牌安全产品
-
即日-12.26火热报名中>> OFweek2024中国智造CIO在线峰会
-
限时免费下载立即下载 >>> 2024“机器人+”行业应用创新发展蓝皮书
-
即日-2025.8.1立即下载>> 《2024智能制造产业高端化、智能化、绿色化发展蓝皮书》
推荐专题
- 1 同源共创 模式革新 | 华天软件皇冠CAD(CrownCAD)2025新品发布会圆满举行
- 2 上海国际嵌入式展暨大会(embedded world China )与多家国际知名项目达成合作
- 3 史上首次,大众终于熬不住开启40亿降本计划!关3个工厂,裁员万名...
- 4 iEi威强电新品丨IMBA-AM5:工业计算的强劲引擎
- 5 守护绿色学习空间,EK超低温热泵服务对外经济贸易大学图书馆
- 6 颜值高 有“门”道|贝特威汽车门板内饰AI视觉检测解决方案
- 7 观众登记启动 优解制造未来,锁定2025 ITES深圳工业展
- 8 “秸”尽全力,防患未“燃” | 秸秆焚烧智能监控解决方案
- 9 揭秘:「全球知名跨境电商」构建核心竞争力的“独门绝技”是?
- 10 3大场景解读 | 红外热像仪赋能科研智造创新应用
发表评论
请输入评论内容...
请输入评论/评论长度6~500个字
暂无评论
暂无评论