- 什么是ADC?
- ARM7-LPC2148中的ADC
- ARM7-LPC2148中的ADC引脚
- ARM7-LPC2148中的ADC寄存器
- LPC2148中的ADxCR寄存器
- ADxGDR:ADC全局数据寄存器
- 所需组件
- 电路原理图
- 为ADC编程ARM7-LPC2148
在电子世界中,市场上有许多种类的模拟传感器用于测量温度,速度,位移,压力等。模拟传感器用于产生随时间连续变化的输出。来自模拟传感器的这些信号的值往往很小,从几微伏(uV)到几毫伏(mV),因此需要某种形式的放大。为了在微控制器中使用这些模拟信号,我们需要将模拟信号转换为数字信号,因为微控制器只能理解和处理数字信号。因此,大多数微控制器都有一个内置的重要功能,称为ADC(模数转换器)。我们的微控制器ARM7-LPC2148还具有ADC功能。
在本教程中,我们将看到如何通过向模拟引脚提供变化的电压并在模数转换后将其显示在16x2 LCD屏幕上来在ARM7-LPC2148中使用ADC。因此,让我们从简短的ADC简介开始。
什么是ADC?
如前所述,ADC代表模数转换,它用于将现实世界中的模拟值转换为数字值,例如1和0。那么这些模拟值是多少?这些是我们日常生活中看到的,例如温度,速度,亮度等。这些参数由相应的传感器作为模拟电压进行测量,然后将这些模拟值转换为微控制器的数字值。
让我们假设我们的ADC范围是从0V到3.3V,并且我们有一个10位ADC,这意味着我们的输入电压0-3.3 V将被分成1024个离散模拟值电平(2 10 = 1024)。含义1024是10位ADC的分辨率,类似地,8位ADC的分辨率为512(28),而16位ADC的分辨率为65,536(216)。LPC2148具有10位分辨率ADC。
这样,如果实际输入电压为0V,则MCU的ADC会将其读取为0;如果它为3.3V,则MCU会读取1024;如果介于1.65v之间,则MCU会读取512。根据ADC的分辨率和工作电压来计算将由MCU读取的数字值的公式。
(ADC分辨率/工作电压)=(ADC数字值/实际电压值)
例如,如果参考电压为3v:
我们在上一篇文章中详细介绍了ADC。
ARM7-LPC2148中的ADC
- LPC2148包含两个模数转换器。
- 这些转换器是单个10位逐次逼近式模数转换器。
- ADC0具有六个通道,而ADC1具有八个通道。
- 因此,LPC2148的可用ADC输入总数为14。
- 它仅在(0至3.3V)范围内转换输入电压。它不得超过基准电压3.3V。因为这会损坏IC并提供不确定的值。
LPC2148中ADC的一些重要功能
- 每个转换器每秒能够执行超过400000个10位采样。
- 每个模拟输入都有一个专用的结果寄存器,以减少中断开销。
- 突发转换模式,用于单个或多个输入。
- 输入引脚或定时器匹配信号转换时的可选转换。
- 两个转换器的全局启动命令。
还要检查如何在其他微控制器中使用ADC:
- 如何在Arduino Uno中使用ADC?
- ADC0808与8051单片机的接口
- 使用PIC单片机的ADC模块
- Raspberry Pi ADC教程
- 如何在MSP430G2中使用ADC-测量模拟电压
- 如何在STM32F103C8中使用ADC
ARM7-LPC2148中的ADC引脚
如前所述,在ARM7-LPC2148中,有两个通道ADC0具有6个模拟输入引脚,而ADC1具有8个模拟输入引脚。因此,总共有14个模拟输入引脚。下图显示了可用于模拟输入的引脚。
由于ADC输入引脚与其他GPIO引脚复用。我们需要通过配置PINSEL寄存器来选择ADC功能来使能它们。
下表显示了LPC2148中ADC的引脚和相关的ADC通道编号。AD0是通道0,AD1是通道1
LPC2148引脚 |
ADC通道号 |
P0.28 |
AD0.1 |
P0.29 |
AD0.2 |
P0.30 |
AD0.3 |
P0.25 |
AD0.4 |
P0.4 |
AD0.6 |
P0.5 |
AD0.7 |
P0.6 |
AD1.0 |
P0.8 |
公元1.1 |
P0.10 |
AD1.2 |
P0.12 |
AD1.3 |
P0.13 |
AD1.4 |
P0.15 |
AD1.5 |
P0.21 |
公元1.6 |
P0.22 |
公元1.7 |
ARM7-LPC2148中的ADC寄存器
寄存器在编程中使用LPC2148中的A / D转换功能。
以下是LPC2148中用于A / D转换的寄存器列表
1. ADCR:模数控制寄存器
用途:该寄存器用于在LPC2148中配置A / D转换器
2. ADGDR:模数全球数据寄存器
使用:该寄存器具有A / D转换器的DONE位,转换结果存储在此处。
3. ADINTERN:模数中断允许寄存器
使用:这是一个中断允许寄存器。
4. ADDR0 – ADDR7:模数通道数据寄存器
使用:该寄存器包含各个通道的A / D值。
5. ADSTAT:模数状态寄存器。
使用:该寄存器包含相应ADC通道的DONE标志和相应ADC通道的OVERRUN标志。
在本教程中,我们将仅使用ADCR和ADGDR寄存器。让我们详细了解一下
LPC2148中的ADxCR寄存器
分别用于通道0和通道1的AD0CR和AD1CR。这是一个32位寄存器。下表列出了ADCR寄存器的位字段。
31:28 |
27 |
26:24 |
23:22 |
21 |
20 |
19:17 |
16 |
15:8 |
7:0 |
已预留 |
边缘 |
开始 |
已预留 |
PDN |
已预留 |
时钟 |
爆裂 |
克拉克迪夫 |
SEL |
让我们来看看如何配置单个寄存器
1. SEL:(0至7)位用于选择ADC转换的通道。每个通道分配一位。例如,设置位0将使ADC采样AD0.1进行转换。并将位设置为-1将使AD0.1; 同样,将bit-7设置为AD0.7即可进行转换。重要的步骤是根据要使用的端口获取PINSEL,例如PLC2148中PORT0的PINSEL0。
2. CLCKDIV:(8至15)位用于时钟分频器。在这里,APB时钟(ARM外围总线时钟)除以该值加1即可生成A / D转换器所需的时钟,该时钟应小于或等于4.5 MHz,因为我们在LPC2148中使用逐次逼近方法。
3.突发:位16用于突发转换模式。
设置1:ADC将对SEL位中选择的所有通道进行转换。
设置0:将禁用BURST转换模式。
4. CLCKS:由于是连续A / D转换模式,从(17到19)三个位用于选择突发模式下A / D转换的分辨率和时钟数。
位的值(17到19) |
位(精度) |
没有时钟 |
000 |
10 |
11 |
001 |
9 |
10 |
010 |
8 |
9 |
011 |
7 |
8 |
100 |
6 |
7 |
101 |
5 |
6 |
110 |
4 |
5 |
111 |
3 |
4 |
5. PDN:位21用于选择LPC2148中ADC的掉电模式。
- A / D处于PDN模式。
- A / D处于操作模式
6. START:(24至26)位用于START。通过将0设置为BURST转换模式时,这些START位对于何时开始A / D转换很有用。START也用于边沿控制的转换。即当LPC2148的CAP或MAT引脚中有输入时,A / D开始转换。让我们检查下表
位的值(24到26) |
LPC2148的引脚 |
ADC的功能 |
000 |
用于将ADC设置为PDN模式 没有开始 |
|
001 |
开始A / D转换 |
|
010 |
CAP0.2 / MAT0.2 |
在LPC2148的CAP / MAT引脚的引脚27(上升或下降)上选择的EDGE上开始A / D转换 |
011 |
CAP0.0 / MAT0.0 |
|
100 |
MAT0.1 |
|
101 |
MAT0.3 |
|
110 |
MAT1.0 |
|
111 |
MAT1.1 |
7. EDGE: 27个位是用于EDGE仅当起始位包含010-111被使用。当有CAP或MAT输入时,它将开始转换,您可以在上面的表格中看到。
设定:0-下降沿
1-上升沿
ADxGDR:ADC全局数据寄存器
AD0GDR和AD1GDR分别用于ADC通道0和ADC通道1。
它是一个32位寄存器,包含A / D转换的结果和DONE位,指示完成A / D转换。下表列出了ADGDR寄存器的位字段。
31 |
30 |
29:27 |
26:24 |
23:16 |
15:6 |
5:0 |
完成 |
超限 |
已预留 |
中国 |
已预留 |
结果 |
已预留 |
1.结果:这些位(6至15)包含ADCR SEL寄存器中所选通道的A / D转换结果。该值仅在A / D转换完成后才能读取,并由DONE位指示。
示例:对于10位ADC结果,存储的值在(0到1023)之间变化。
2.通道:这些位24到26包含完成A / D转换的通道号。转换后的数字值存在于RESULT位中。
示例:000表示ADC通道0,001表示ADC通道1,依此类推
3.超支: 30个用于覆盖位在突发模式中使用。设置为1时,先前转换的ADC值将被新转换的ADC值覆盖。读取寄存器后,它将清除OVERRUN位。
4. DONE:第31位为DONE位。
设置1:A / D转换完成时。
设置0:读取寄存器并写入ADCR时。
我们已经了解了LPC2148中ADC中使用的重要寄存器。现在开始在ARM7中使用ADC。
所需组件
硬件
- ARM7-LPC2148微控制器
- 3.3V稳压器IC
- 5V稳压器IC
- 10K电位器– 2号
- LED(任何颜色)
- 液晶显示器(16X2)
- 9V电池
- 面包板
- 连接线
软件
- Keil uVision5
- 魔术闪光工具
电路原理图
下表显示了LCD与ARM7-LPC2148之间的电路连接。
ARM7-LPC2148 |
液晶屏(16x2) |
P0.4 |
RS(寄存器选择) |
P0.6 |
E(启用) |
P0.12 |
D4(数据引脚4) |
P0.13 |
D5(数据引脚5) |
P0.14 |
D6(数据引脚6) |
P0.15 |
D7(数据引脚7) |
了解有关将LCD与ARM 7 – LPC2148一起使用的更多信息。
重要信息:在这里,我们使用两个稳压器IC,一个用于5V LCD显示,另一个3.3V用于模拟输入,可通过电位计来改变。
带LCD和ARM7 Stick的5V稳压器之间的连接
5V稳压器IC |
引脚功能 |
LCD和ARM-7 LPC2148 |
1.左销 |
+ Ve来自电池9V输入 |
数控 |
2.中心销 |
-来自电池的Ve |
LCD的VSS,R / W,K ARM7的GND |
3.右销 |
稳压+ 5V输出 |
LCD的VDD,A + 5V的ARM7 |
液晶电位器
电位计用于改变LCD显示的对比度。一个电位计具有三个引脚,左引脚(1)连接到+ 5V,而中心(2)连接到LCD模块的VEE或V0,右引脚(3)连接到GND。我们可以通过旋转旋钮来调整对比度。
LPC2148与带有3.3V稳压器的电位计之间的连接
3.3V稳压器IC |
引脚功能 |
ARM-7 LPC2148 |
1.左销 |
-来自电池的Ve |
GND引脚 |
2.中心销 |
稳压+ 3.3V输出 |
至电位计输入和电位计输出至P0.28 |
3.右销 |
+ Ve来自电池9V输入 |
数控 |
为ADC编程ARM7-LPC2148
要编程ARM7-LPC2148,我们需要keil uVision和Flash Magic工具。我们正在使用USB电缆通过微型USB端口对ARM7 Stick进行编程。我们使用Keil编写代码并创建一个十六进制文件,然后使用Flash Magic将HEX文件闪存到ARM7 Stick。要了解有关安装keil uVision和Flash Magic以及如何使用它们的更多信息,请单击链接ARM7 LPC2148微控制器入门并使用Keil uVision对其进行编程。
在本教程中,我们通过使用LPC2148中的ADC将模拟输入电压(0至3.3V)转换为数字值,并在LCD显示屏上显示模拟电压(16x2)。电位计将用于改变输入模拟电压。
要了解有关LCD与ARM7-LPC2148 4位模式接口的更多信息,请单击此链接。
本教程的结尾给出了将ADC与ARM 7一起使用的完整代码,在这里我们解释了其中的几个部分。
LPC2148-ADC编程涉及的步骤
1. PINSEL寄存器用于选择LPC2148的端口引脚,而ADC用作模拟输入。
PINSEL1 = 0x01000000; //选择P0.28作为AD0.1
2.通过将值写入ADxCR(ADC控制寄存器)来选择要转换的时钟和位精度。
AD0CR = 0x00200402; //将ADC操作设置为10位/ 11 CLK进行转换(000)
3.通过将值写入ADxCR中的START位开始转换。
在这里,我已写入AD0CR寄存器的第24位。
AD0CR = AD0CR-(1 << 24);
4.现在,我们检查对应的ADxDRy(ADC数据寄存器)的DONE位(第31位)从0变为1的情况。因此,我们使用 while 循环不断检查是否在数据寄存器的第31位上完成了转换。
while(!(AD0DR1&0x80000000));
5.将done位设置为1后,转换成功,接下来我们从同一ADC数据寄存器AD0DR1中读取结果,并将该值存储在变量中。
adcvalue = AD0DR1;
接下来,我们使用公式将数字值转换为电压并将其存储在名为 voltage 的变量中。
电压=((adcvalue / 1023.0)* 3.3);
5.在模拟到数字转换之后,以下几行用于显示数字值(0至1023)。
adc = adcvalue; sprintf(displayadc,“ adcvalue =%f”,adc); LCD_DISPLAY(displayadc); //显示ADC值(0到1023)
6.在模拟到数字转换之后以及在步骤5之后,以下几行用于显示输入模拟电压(0至3.3V)。
LCD_SEND(0xC0); sprintf(voltvalue,“ Voltage =%。2f V”,电压); LCD_DISPLAY(电压值); //显示(输入模拟电压)
7.现在,我们必须在LCD显示屏上显示输入电压和数字值。在此之前,我们必须初始化LCD显示屏并使用适当的命令来发送要显示的消息。
以下代码用于初始化LCD
void LCD_INITILIZE(void)//准备LCD的功能 { IO0DIR = 0x0000FFF0; //将引脚P0.12,P0.13,P0.14,P0.15,P0.4,P0.6设置为OUTPUT delay_ms(20); LCD_SEND(0x02); //以4位工作模式初始化LCD LCD_SEND(0x28); // 2行(16X2) LCD_SEND(0x0C); //在光标旁边显示 LCD_SEND(0x06); //自动递增光标 LCD_SEND(0x01); //显示清晰的 LCD_SEND(0x80); //第一行第一位置 }
下面的代码用于在LCD上显示值
空隙LCD_DISPLAY(字符* MSG)//函数来打印字符发送逐个{ uint8_t I = 0; while(msg!= 0) { IO0PIN =((IO0PIN&0xFFFF00FF)-(((msg&0xF0)<< 8));; //发送高位半字节 IO0SET = 0x00000050; // RS HIGH&ENABLE HIGH以打印数据 IO0CLR = 0x00000020; // RW LOW写模式 delay_ms(2); IO0CLR = 0x00000040; // EN = 0,RS和RW不变(即RS = 1,RW = 0) delay_ms(5); IO0PIN =((IO0PIN和0xFFFF00FF)-((msg&0x0F)<< 12)); //发送低位半字节 IO0SET = 0x00000050; // RS&EN HIGH IO0CLR = 0x00000020; delay_ms(2); IO0CLR = 0x00000040; delay_ms(5); i ++; } }
下面的函数用于创建延迟
void delay_ms(uint16_t j)//产生延迟的函数,以毫秒为单位 { uint16_t x,i; 对于(i = 0; i
带有演示视频的完整代码如下。