单片机
返回首页

如何在ARM7-LPC2148中使用ADC

2023-02-09 来源:zhihu

在电子世界中,市场上有多种模拟传感器用于测量温度、速度、位移、压力等。模拟传感器用于产生随时间不断变化的输出。这些来自模拟传感器的信号的值往往很小,从几微伏 (uV) 到几毫伏 (mV),因此需要某种形式的放大。为了在微控制器中使用这些模拟信号,我们需要将模拟信号转换为数字信号,因为微控制器只理解和处理数字信号。因此,大多数微控制器都有一个内置的重要功能,称为ADC(模数转换器)。我们的微控制器ARM7-LPC2148还具有 ADC 功能。


在本教程中,我们将了解如何在 ARM7-LPC2148 中使用 ADC,方法是向模拟引脚提供不同的电压,并在模数转换后将其显示在16x2 LCD 屏幕上。


什么是ADC?

如前所述,ADC 代表模数转换,它用于将模拟值从现实世界转换为数字值,如 1 和 0。那么这些模拟值是什么?这些是我们在日常生活中看到的,例如温度、速度、亮度等。这些参数由各自的传感器作为模拟电压测量,然后这些模拟值被转换为微控制器的数字值。


让我们假设我们的 ADC 范围是从 0V 到 3.3V,并且我们有一个 10 位 ADC,这意味着我们的输入电压 0-3.3 伏将被分成 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:

pYYBAGMtdjGABlq3AAAT0D4NqgI682.png

我们在上一篇文章中详细解释了 ADC。

ARM7-LPC2148 中的 ADC

LPC2148 包含两个模数转换器。

这些转换器是单个 10 位逐次逼近模数转换器。

ADC0 有六个通道,ADC1 有八个通道。

因此, LPC2148 的可用 ADC 输入总数为 14 。

它仅转换(0 至 3.3V)范围内的输入电压。它不能超过 3.3V 的参考电压。因为它会损坏 IC 并提供不确定的值。

LPC2148中ADC的一些重要特性

每个转换器每秒能够执行超过 400000 个 10 位样本。

每个模拟输入都有一个专用的结果寄存器来减少中断开销。

单个或多个输入的突发转换模式。

输入引脚或定时器匹配信号转换时的可选转换。

两个转换器的全局启动命令。

ARM7-LPC2148 中的 ADC 引脚

如前所述,在 ARM7-LPC2148 中有两个通道 ADC0 带有 6 个模拟输入引脚和 ADC1 带有 8 个模拟输入引脚。所以总共有14个模拟输入引脚。下图显示了可用于模拟输入的引脚。

pYYBAGMtdjaAQlh-AADIPErUgzY027.jpg

由于 ADC 输入引脚与其他 GPIO 引脚复用。我们需要通过配置PINSEL 寄存器来启用它们以选择 ADC 功能。


下表显示了 LPC2148 中 ADC 的引脚和相应的 ADC 通道号。AD0 为通道 0,AD1 为通道 1

pYYBAGMtdfuAE-t1AAAdUtLzp9E000.png

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 寄存器

AD0CR & AD1CR 分别用于通道 0 和通道 1。它是一个 32 位寄存器。下表显示了 ADCR 寄存器的位域。

poYBAGMtdfaAC0evAAANP9auuEs155.png

让我们看看如何配置单个寄存器

1. SEL:(0 到 7)位用于选择 ADC 转换的通道。为每个通道分配一位。例如,设置 Bit-0 将使 ADC 对 AD0.1 进行采样以进行转换。设置位-1将使AD0.1;同样设置第 7 位将为 AD0.7 进行转换。重要的一步是我们根据我们使用的端口有 PINSEL,例如 PLC2148 中 PORT0 的 PINSEL0。

2. CLCKDIV:(8 到 15)位用于时钟除数。这里将 APB 时钟(ARM 外设总线时钟)除以该值加 1 以产生 A/D 转换器所需的时钟,由于我们在 LPC2148 中使用逐次逼近法,该时钟应小于或等于 4.5 MHz。

3. BURST:第 16 位用于 BURST 转换模式。

设置 1:ADC 将对在 SEL 位中选择的所有通道进行转换。

设置 0:将禁用 BURST 转换模式。

4. CLCKS:(17 到 19)三个位用于选择突发模式下 A/D 转换的分辨率和时钟数,因为它是连续 A/D 转换模式。

poYBAGMtdfGAemp_AAASYla1-yQ418.png

5. PDN:第 21 位用于选择LPC2148 中 ADC 的掉电模式。

A/D 处于 PDN 模式。

A/D 处于操作模式

6. START:(24 到 26)位用于 START。当 BURST 转换模式通过设置 0 关闭时,这些 START 位对于何时开始 A/D 转换很有用。START 也用于边沿控制转换。即当 LPC2148 的 CAP 或 MAT 引脚有输入时,A/D 开始转换。让我们检查下表

pYYBAGMtdeSATLTLAAAh1un_pHg507.png

7. EDGE:第 27位用于 EDGE,仅当 START 位包含 010-111 时使用。它在有 CAP 或 MAT 输入时开始转换,您可以在上表中看到。

设置:0 -在下降沿

1 - 在上升沿

ADxGDR:ADC 全局数据寄存器

AD0GDR 和 AD1GDR 分别用于 ADC 通道 0 和 ADC 通道 1。

它是一个 32 位的寄存器,包含 A/D 转换的 RESULT 以及指示 A/D 转换完成的 DONE 位。下表显示了 ADGDR 寄存器的位域。

pYYBAGMtddiAc3MWAAAJPrDpoQ4424.png

1. RESULT:这些位(6 到 15)包含 ADCR SEL 寄存器中所选通道的 A/D 转换结果。该值仅在 A/D 转换完成后才被读取,这由DONE位指示。

示例:对于 10 位 ADC 结果,存储的值从(0 到 1023)变化。

2. CHANNEL:这些位 24 到 26 包含完成 A/D 转换的通道号。转换后的数字值出现在 RESULT 位中。

示例:000 用于 ADC 通道 0,001 用于 ADC 通道 1,依此类推

3. OVERRUN:OVERRUN的第 30位用于 BURST 模式。当设置为 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电池

面包板

连接电线

软件

凯尔uVision5

魔法闪光工具

电路原理图

poYBAGMtddGARgi3AAGt3iw6a6o317.pngpYYBAGMtdjqAXys8AADsEhqHxsI646.jpg

下表显示了LCD 和 ARM7-LPC2148 之间的电路连接。

ARM7-LPC2148液晶显示器 (16x2)

P0.4RS(寄存器选择)

P0.6E(启用)

P0.12D4(数据引脚 4)

P0.13D5(数据引脚 5)

P0.14D6(数据引脚 6)

P0.15D7(数据引脚 7)

pYYBAGMtdcyATFeFAAAZKpvS0r8808.png

重要提示:这里我们使用了两个稳压器 IC,一个用于 5V LCD 显示屏,另一个用于模拟输入,可以通过电位器改变 3.3V。

5V 稳压器与 LCD 和 ARM7 Stick之间的连接

5V稳压IC引脚功能LCD & ARM-7 LPC2148

1.左销+ Ve 来自电池 9V 输入数控

2.中心销- 来自电池的 VeLCD的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接地脚

2.中心销稳压 +3.3V 输出至电位器输入,电位器输出至P0.28

3.右销+ Ve 来自电池 9V 输入数控

为 ADC 编程 ARM7-LPC2148

要对 ARM7-LPC2148 进行编程,我们需要 keil uVision 和 Flash Magic 工具。我们正在使用 USB 电缆通过微型 USB 端口对 ARM7 Stick 进行编程。我们使用 Keil 编写代码并创建一个 hex 文件,然后使用 Flash Magic 将 HEX 文件闪存到 ARM7 棒。要了解有关安装 keil uVision 和 Flash Magic 以及如何使用它们的更多信息,请点击链接 Getting Started With ARM7 LPC2148 Microcontroller and Program it using Keil uVision。

在本教程中,我们使用 LPC2148 中的 ADC 将模拟输入电压(0 至 3.3V)转换为数字值,并在LCD 显示器(16x2)上显示模拟电压。电位器将用于改变输入模拟电压。

在本教程的末尾给出了在ARM 7 中使用 ADC的完整代码,这里我们将解释它的几个部分。

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 位是否完成转换。

而(!(AD0DR1&0x80000000));
5.完成位设置为 1 后,转换成功,接下来我们从同一个 ADC 数据寄存器 AD0DR1 中读取结果并将值存储在一个变量中。

adc 值 = AD0DR1;
接下来我们使用一个公式将数字值转换为电压并存储在一个名为电压的变量中。

电压 = ( (adcvalue/1023.0) * 3.3 );
5.以下行用于显示模数转换后的数字值(0 到 1023)。

adc = adc 值;
sprintf(displayadc, 'adcvalue=%f', adc);
LCD_DISPLAY(displayadc); //显示ADC值(0到1023)
6.以下行用于显示模数转换后和第 5 步后的输入模拟电压(0 至 3.3V)。

LCD_SEND(0xC0);
sprintf(伏特值,“电压=%.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 上显示值

void LCD_DISPLAY (char* msg) //函数将发送的字符一一打印

{
uint8_t i=0;
while(msg[i]!=0)
{
IO0PIN = ( (IO0PIN & 0xFFFF00FF) | ((msg[i] & 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[i] & 0x0F)<<12) ); //发送低半字节
IO0SET = 0x00000050; //RS & EN HIGH
IO0CLR = 0x00000020;
延迟毫秒(2);
IO0CLR = 0x00000040;
延迟毫秒(5);
我++;
}
}
以下函数用于创建延迟

void delay_ms(uint16_t j) // 以毫秒为单位的延迟函数
{
uint16_t x,i;
for(i=0;i {
for(x=0; x<6000; x++); // Forloop 在 Cclk = 60MHz 时产生 1 毫秒的延迟
}
}


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 光控音效发生器电路

  • 基于IC555的可变PWM振荡器电路

  • 优化电路板布局的简单方法

  • 如何使用LED驱动器LM3915制作振动计

  • 一个简单的立体声平衡指示器电路

  • 电谐波图形均衡器示意图

    相关电子头条文章