第001节——ADC硬件原理 模数转换器即A/D转换器,或简称ADC,通常是指一个将模拟信号转变为数字信号的电子元件。 通常的模数转换器是把经过与标准量比较处理后的模拟量转换成以二进制数值表示的离散信号的转换器。
故任何一个模数转换器都需要一个参考模拟量作为转换的标准,比较常见的参考标准为最大的可转换信号大小。而输出的数字量则表示输入信号相对于参考信号的大小。 对于数字信号我们需要得到它的几个属性
*用多少位来存储这个数据(假设10bit)。 *最大值0b111111111 *它对应的电压是多少伏(模拟信号输入的最大值是多少)我们就可以根据模拟信号(电压)的最大值,来计算出对应的数值。 *采样/转换速度。
对于程序员,我们不关心ADC的内部机制,我们只关心:
*怎么启动ADC *启动之后怎么得到数据, 总之:我们都是通过寄存器操作的。 下面是编写程序要做的步骤:
确定是哪一路信号:设置8:1MUX,选择要测量哪一个引脚,(看原理图选择要测量的引脚) 设置工作时钟(从工作室中,可以算出转换一次,需要多长时间) 启动 读状态,判断ADC转换是否成功。 读数据
ADC寄存器介绍 1.ADC 控制寄存器(ADCCON)
ADCCON控制寄存器,用于标志转换是否完成,控制是否使能预分频器,输入通道选择,工作模式,ADC是否启动。
2.ADC 启动延时寄存器(ADCDLY)
ADCDLY 启动延时寄存器用于启动或初始化延时寄存器。
3.ADC 转换数据寄存器(ADCDAT0)
ADCDAT0转换数据寄存器,本节中只用到该寄存器的前10位(用于保存转换后的结果)。
第002节_ADC编程 编程步骤:
初始化ADC 读数据, 在串口上显示出来。
一.初始化ADC
下面的函数实现对ADC的初始化。
03 void adc_init(void)
04 {
05 /* [15] : ECFLG, 1 = End of A/D conversion
06 * [14] : PRSCEN, 1 = A/D converter prescaler enable
07 * [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1)
08 * [5:3] : SEL_MUX, 000 = AIN 0
09 * [2] : STDBM
10 * [0] : 1 = A/D conversion starts and this bit is cleared after the startup.
11 */
12 ADCCON = (1<<14) | (49<<6) | (0<<3);
13
14 ADCDLY = 0xff;
15 }
第12行:配置ADCCON寄存器,使能A/D 转换器预分频器,设置A/D 转换器预分频值,上拉使能。
第14行:设置ADC 转换启动延时值。
二.读数据
在这个读函数中启动ADC,并且等待ADC转换成功。然后返回数据,
17 int adc_read_ain0(void) 18 { 19 /* 启动ADC / 20 ADCCON |= (1<<0); 21 22 while (!(ADCCON & (1<<15))); / 等待ADC结束 */ 23 24 return ADCDAT0 & 0x3ff; 25 }
第20行:启动ADC。 第22行:等待A/D转换结束(ADCCON第15位置1), 第24行:返回转换的值。(ADCDAT0寄存器的前10位,是保存转换后的值)。
三.ADC测试
函数代码如下: 函数功能:在串口/LCD上打印ADC转换后的结果。
04 void adc_test(void)
05 {
06 int val;
07 double vol;
08 int m; /* 整数部分 /
09 int n; / 小数部分 /
10
11 adc_init();
12
13 while (1)
14 {
15 val = adc_read_ain0();
16 vol = (double)val/10233.3; /* 1023----3.3v /
17 m = (int)vol; / 3.01, m = 3 /
18 vol = vol - m; / 小数部分: 0.01 /
19 n = vol * 1000; / 10 /
20
21 / 在串口上打印 /
22 printf("vol: %d.%03dv", m, n); / 3.010v /
23
24 / 在LCD上打印 */
25 //fb_print_string();
26 }
27 }
*第11行:初始化ADC. *第15行:把ADC转换得到的值赋值给变量val. *第16行:把变量val的值转化为电压值。 *第17行:取vol整数部分赋值给变量m。 *第18行:取vol的小数部分赋值给vol。
测试
把生成的二进制文件烧录到开发板上,接上SPI模块,旋转可变电阻就可以在串口上看到电压值发生变化。
第003节_电阻触摸屏硬件原
这节课我们来讲电阻触摸屏的硬件原理
假设有一个比较长的电阻,电阻是R 上面接3.3V电压,下面接地
假设整个电阻的阻值是R某一个触电它的阻值是R1 根据欧姆定律
3.3v/R = V/R1 V=3.3 *(R1/R) 假设R1是x坐标 R的长度是l 这个电阻非常的均匀,那么这个电压就等于 3.3V * (x / l) 这个电压和这个触电的x坐标有一个线性关系 我使用ADC把这个电压算出来,就可以间接得到这个触电的x坐标 电阻触摸屏就是使用欧姆定律使用电阻原理作出来的
可以上百度图片搜索触摸屏,就知道了触摸屏的样子,它是一个透明的薄膜,注意 LCD是LCD 触摸屏是触摸屏它是两个设备, 我们只不过是把触摸屏做的和LCD大小一样,粘在LCD上面, 实际上触摸屏是由两层膜组成,他们靠的非常近 上面这层右边引出来,代表xp ,p代表正极 上面这层左边引出来,代表xm, m代表负极
下面这层膜 前面这条边引出来为yp,后面这层边为ym
假设我们手指要点击触摸屏,那么上下就会粘贴在一起,我怎么算出这个 x y点的坐标呢? 测量触电x坐标: xp接3.3v,xm接GND
2 测yp电压 上下膜连接在一起,我就可以通过yp测量这个触电的电压 这个yp就像探测一样,从前面的原理我们可以知道,当这个触电越靠近左边这个电压越小,越靠近右边电压越大 这个yp的电压就可以认为是这个触电的坐标(x坐标) 类似的我们怎么测量触电y坐标 类似的xp xm不接电源,同样yp接3.3v, ym接GND,这时候电流就从 yp这里流向ym,让后我们就可以测量xp电压 当按下屏幕时,上下两层膜链接在一起,这个xp就像探针一样,这个触电越靠近yp电压值越大,越靠近ym电压值越小 yp接3.3V ym接GND,xp xm不接电源 测量xp电压,就是y坐标 注意 x y坐标都是电压值,不是屏幕上480 * 272 这些值,我们需要把电压值转换为坐标值,这需要经过一些转换 我们测量xp yp可以得到触点的两个方向的电压值,这些电压值和坐标是线性关系
我们现在总结下使用触摸屏的流程 <1>按下触摸屏 按下触摸屏时,对于一个高效的系统,产生中断,这是触摸屏中断 <2>在触摸中断程序中 启动ADC,(获得数据,xy坐标)启动ADC就开始模数转换,不可能瞬间完成, <3>ADC完成, 产生中断 <4>ADC中断中读取x y坐标,我们来想想,在这个流程里,启动触摸屏的源头是按下触摸屏,那如果长按触摸屏,我按下之后一直不松开 滑动手指呢 那么谁来触发后续的多次ADC转换呢 不可能只启动一次吧, 为了支持 长按 滑动操作,我们需要启用定时器. <5> 启动定时器 <6> 定时器中断发生,判断触摸屏是否仍被按下,如果按下就循环上述过程 <6.1>在触摸中断程序中 启动ADC,(获得数据,xy坐标)启动ADC就开始模数转换,不可能瞬间完成 <6.2>ADC完成, 产生中断 <6.3>ADC中断中读取x y坐标,) <7> 松开结束一个流程 这就是整个触摸屏的使用流程
第004节_S3C2440触摸屏接口
在不使用触摸屏的时候,必须要把 S1 S2 S3断开,S4 S5闭合,只有这样当我按下触摸屏,上面的电平才能从高变低,会产生一个中断信号,而当我去读取X坐标的值时 必须让S1 S3闭合,这样电流才可以通过,同时让S2 S4 S5断开,这时候YP这层膜就相当于探针一样去测量电压
当我读取y坐标值 必须让S2 S4闭合,这样电流才可以流 下来,同时S1 S3 S5断开,这个时候XP这层膜就相当于探针一样,我可以来测量这里的电压,从而得到Y坐标的电压值
在测量x y坐标时,这个S5上拉电阻都要断开, 我们需要控制这几个开关,实际上2440就提供了这几个开关的控制方法, 打开2440的芯片手册看触摸屏时怎么操作的, 从440到450总共10页不到, 我们看有一个8:1 MUX的多路选择器,以及XP YP 正常模式,在上节视频中我们有讲解过 x y分离转换模式, 看看我们的X Y坐标原理图,可以单独转换X坐标 单独转换Y坐标 换句话说就是逐个去测量X Y坐标, 他首先会启动X坐标的ADC转换,转换成功后数据会保存在ADCDAT0里,同时会产生一个中断,在这个中断服务程序里,就可以把X坐标读取出来,让后可以启动Y坐标的转换,转换成功后数据会保存在ADCDAT,同时会产生一个中断,进入这个中断把Y坐标读取出来 测量一次会产生2个中断,一个时X坐标中断,一个是Y坐标中断
自动的或连续的X/Y坐标转换模式 也就是说不需要单独控制,不需要单独去读取X坐标Y坐标,可以设置寄存器,让它一次性的测量X坐标测量Y坐标,X坐标保存在ADCDAT0 Y坐标保存在ADCDAT1,最后产生一个中断,也就是读取X/Y坐标只需要产生一次中断
等待中断模式 所谓等待中断模式,就是等待按下或者等待松开 对于下面这幅图,我按下的时候XP从高电平变为低电平,松开时,XP从低电平变为高电平,这就是按下松开都可以检测到
我们要等待按下或者松开时 需要设置rADCTSC =0xd3这个值 AD转换数据时可以通过中断或者查询模式来得到数据,使用中断模式时,从AD转换开始,到得到数据可能会有些延迟,因为中断服务程序的进入和退出需要一定的时间,(也就是说,如果你对数据转换的速度要求的非常高,就可以使用查询方式),可以查询ADCCON[15]来判断是否转换结束
ECFLG状态位 AD转换是否结束 PRSCEN 使能ADC转换 PRSCVL 设置A/D转换预分频值 SEL_MUX选择输入通道,后面我们使用自动转换XY坐标,所以这里不需要设置 ENABLE_START 启动转换 ADCTSC这个寄存器是重要的 UD_SEN Bit8是用来判断触摸屏是被按下还是被松开 0表明被按下,1表明被松开 YM_SEN Bit7 YM开关使能控制S4
SRCPND寄存器 31位为ADC中断
INTMOD寄存器 来决定是普通中断还是快中断模式
INTMSK寄存器 用来表示是否屏蔽这个中断
INTPND 设置Bit[31]表示中断是否正在处理
到底是ADC中断还是触摸屏中断,肯定有其他寄存器可以设置 SUBSOURCE PENDING寄存器 INT_ADC_S Bit[10]表示ADC中断 INT_TC Bit[9]表示触摸屏中断
INTSUBMSK 应该也是同样的位 INT_ADC_S Bit[10]表示ADC中断激活/屏蔽 INT_TC Bit[9]表示触摸屏中断激活/屏蔽
我们可以通过INTSUBMSK来屏蔽ADC中断或者TouchScreen中断 当然也可以是能某个中断 可以通过SUBSRCPND来分辨到底产生那个中断 INTSUBMSK 和SUBSOURCPND这两个寄存器都会汇集到一起 变成一个叫做INT_ADC的中断来发送给CPU
我们怎么写程序? 写出一个框架 1 初始化ADC/TouchScreen接口ADCCON时钟接口 2 一开始触摸屏是没有被按下的,设置TS处于等待中断模式 3 设置中断 INTSUBMSK使能ADC中断和触摸屏中断,还有INTMSK设置这个寄存器使能ANT_ADC让他能够发给CPU 4 按下触摸屏,进入TS中断 4.1 进入自动采集模式(自动转换XY坐标) 4.2 启动ADC 5.转换完之后产生ADC中断 5.1 读数据 5.2 再次进入 “’等待中断”’模式 5.3 启动定时器,处理长按或者滑动 6 定时器中断 6.1 判断是否松开,若松开结束 6.2 若按下重新执行 4.2启动ADC步骤