×
单片机 > 单片机程序设计 > 详情

怎样用AVR微控制器集成的ADC从周围环境中获取模拟读数

发布时间:2020-12-28 发布时间:
|

原理图

ADC的快速回顾

大多数人认为模拟领域已经落后于他们,但事实是模拟领域从未如此强大!随着物联网的兴起和传感器的生产,全球每秒都在进行数十亿的模拟读数。这只是微控制器生产商将ADC外设直接集成到其器件中的众多原因之一。


ADC将模拟信号转换为数字信号

通常测量ADC

由于ADC是数字的,模拟信号被量化为离散的步骤

这意味着ADC只能准确无误地实现它们的位宽(即10位ADC)测量特定电压电平

最大数字值等于ADC 正参考电压(通常为VCC)

最小数字值等于ADC 负参考(通常为GND)

ADC需要时间来转换信号

在ATmega168中,ADC具有以下特性:

10位分辨率(+ Vref和-Vref之间的1024个离散电压电平)

精度为2LSB(高8位精度保证)

高达15,000个样本/秒

6个多路复用输入源

1.1V 带隙参考

配置ADC


左对齐还是右对齐?

当ADC完成转换操作后,结果存储在一对中8位寄存器(10位结果不适合单个8位寄存器)。由于ATmega是原生的8位器件,因此使用8位ADC不如10位结果更有意义,但这会降低结果的分辨率。但是,必须正确读取10位数的8位结果,否则结果将不正确。为此,我们需要读取前8位(位9-2),而不是后8位。使用ADLAR位很容易实现,当设置为1时,将使ADC结果保持正确。这意味着我们不需要读取结果寄存器(ADCH和ADCL)并进行一些操作,而是直接读取ADCH并忘记ADCL。

配置I/O端口

现在我们可以直接读取ADCH以获得8位结果,而不必担心位操作(在分辨率的成本),我们现在需要配置我们的模拟引脚。默认情况下,ATmega168上的I/O引脚配置为数字引脚,这意味着它们只能处理1和0。因此,要将输入配置为模拟引脚,我们使用DIDR0寄存器,它代表数字输入禁用寄存器。不幸的是,并非每个引脚都具有模拟输入的能力,因此请务必注意带有标签ADCx的引脚。例如,引脚23至28是ATmega168上的模拟输入引脚。

配置ADC模块

配置ADC的最后阶段包括打开ADC,设置预缩放器时间以及确定ADC的参考值。

通过将ADCSRA寄存器中的ADEN位置1来打开ADC模块。

在大多数情况下,预缩放器不是太重要了,为了简单起见,我们将预缩放器设置为其最大值(设置ADCSRA寄存器中的所有ADPSx位)。

ATmega168上的ADC可以介于0V和某个参考电压之间,通常设置为VCC。由于大多数电路都是这种情况,我们需要将Aref引脚连接到也接地的电容,我们还需要将REFSx位设置为使用AVCC作为参考。

使用ADC

使用ADC非常简单。选择将从中取出模拟读数的通道,然后,为了开始转换,ADSC位(在ADCSRA中找到)将打开。转换完成后,ADC硬件会自动清零ADSC位。

通过设置ADMUX寄存器中的相应多路复用器位MUX3-MUX0来选择要读取的模拟引脚。

软件示例

此示例从ADC0(PC0,引脚23)读取模拟值并进行比较他们到一个特定的价值。如果模拟读数超出指定值(定义为TRIGPOINT),LED(连接到PD0,引脚2)将打开。一旦ADC读数低于指定值,LED就会关闭!

/*

* AVR IO.c

*

* Created: 03/01/2018 11:25:21

* Author : RobinLaptop

*/

#define F_CPU 1000000UL

#define TRIGPOINT 128

#include

#include

int main(void)

{

// Configure PORT D bit 0 to an output

DDRD = 0b00000001;

// Configure PORT C bit 0 to an input

DDRC = 0b00000000;

// Configure ADC to be left justified, use AVCC as reference, and select ADC0 as ADC input

ADMUX = 0b01100000;

// Enable the ADC and set the prescaler to max value (128)

ADCSRA = 0b10000111;

// Main program loop

while (1)

{

// Start an ADC conversion by setting ADSC bit (bit 6)

ADCSRA = ADCSRA | (1 《《 ADSC);

// Wait until the ADSC bit has been cleared

while(ADCSRA & (1 《《 ADSC));

if(ADCH 》 TRIGPOINT)

{

// Turn LED on

PORTD = PORTD | (1 《《 PD0);

}

else

{

// Turn LED off

PORTD = PORTD & ~(1 《《 PD0);

}

}

}


结论

本文仅介绍ADC背后的基础知识,但我们已经开始从现实世界中进行模拟测量。当然,您可以阅读数据表并了解其他更高级的功能,包括触发和其他电压参考。但就目前而言,这应该为您提供足够的知识,开始制作需要读取模拟值的AVR项目!

关键字:AVR微控制器  ADC  模拟读数 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址