原理图
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,需要配置用于adc测量的外设和i/o引脚。
左对齐还是右对齐?
当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项目!
夜狼安防推出人体跌倒/人体存在毫米波雷达报警器
4940元的自动系鞋带耐克太贵?那你可以看看这个
5G正在孕育颠覆性的变革全面构建数字化技术是社会的基础
电池的续航与安全能否并存?
为了满足玩家随时随地玩VR游戏 索泰推出旗下首款背包电脑VR GO
怎样用AVR微控制器集成的ADC从周围环境中获取模拟读数
Netty如何实现消息推送
亮相联通、电信等多场5G峰会 虹软科技用5G+AI重新定义智能手机
单片机是怎么烧录程序的
意法半导体发布两款灵活多用的电源模块,简化SiC逆变器设计
微弱电流测试优化方案
华为旗下海思首款OLED驱动IC已开始试产
用LM317制作恒压恒流充电器,LM317 Battery charger
iOS10.3正式版怎么升级:iOS10.3正式版固件下载大全
英特尔正在计划收购以色列AI芯片制造商Habana Labs
802.11物理层测试标准(11n HT-4)汇总详解
dfrobot电机(6V 160RPM 2.8kg.cm)简介
Android的阿喀琉斯之踵
51单片机工程师跳槽到stm32的方法
低功耗蓝牙模块带您了解智能血压计_SKYLAB 蓝牙模块应用