9、ADC
在将ADC之前,先聊聊其前因后果——由于计算机在自动控制、检测以及其他领域广泛应用数字电子技术,而大自然的信号全是模拟信号,如果通过计算机保存自然信号呢?那么就需要ADC(模数转换器Analog-Digital Converter)来讲模拟信号转换为数字信号,这样才能存储到计算机中。
那么ADC是如何转换的呢?
l首先对选定一个瞬间对模拟信号进行采样;
l然后将值转换为数字量;
l最后按照一定编码格式转换。
—>
一个模拟信号肯定是不能采样一个点的,而是许多点集合而成。当长方形又窄又长时几乎接近竖线时,就可以很好的还原之前的波形了。
用官方的话说:抽样定理——若原图的最大频率是fmax,那么采样频率要比原图的最大频率2倍还要大,这样才能准备无误的还原原来的波形。
如图,0-1V是连续的电压量,而0-0.125V被当做0△,那么就会存在最小误差△;接着通过一定的编码方式转换,如二进制、八进制、十六进制等。
至于ADC的转换过程如何,可以通过网上的介绍来深入了解。现在我们来看看AVR的ADC特点以及如何操作。
ATmega16单片机内部自带ADC,不需要外部ADC芯片来转换。其主要特点是:
l10位精度的逐次逼近型ADC,±2LSB的绝对精度
l65-260us的转换时间
l最高分辨率时采样率高达15kSPS
l8路复用的单端输入通道
l0-AVcc的ADC输入电压范围,包括内部2.56V参考电压
l支持连续转换或单词转换模式
l可触发ADC中断
再来看看ADC时序图——连续转换
可以发现前面13个时钟周期是没有采集的,主要是为了初始化模拟电路。ADC的转换结果为——ADC=Vin*1024/Vref,Vin是ADC通道的输入电压,Vref是参考电压。
下面开始介绍ADC的主要寄存器:
ADMUX(多工选择寄存器):
6-7位:用来设置参考电压是内部、外部还是都要,具体如下图
第5位:ADC转换结果左对齐,主要影响ADC值在寄存器中存放形式;
0-4位:用来选择ADC通道
本案例使用的是外部AVcc参考电压,以及通道0,右对齐,所以ADMUX = 0x00。
ADCSRA(控制和状态寄存器):
7位:ADC使能位;
6位:ADC开始转换位;
5位:ADC自动触发使能,启动自动触发,触发信号的上升沿驱动转换;
4位:ADC中断标志,在ADC转换结束后,ADIF置位,需要软件清零;
0-2位:ADC预分频器选择。
最后还有一个老朋友——SFIOR寄存器(设置过IO是否上拉)
5-7位:这3位的设置是当ADCSRA中的ADATE位置1才有效,被选中的中断在上升沿时触发ADC转换(本案例例程不做该功能,了解一下)。
现开始代码讲解:
初始化ADC,选择通道,分频128,并使能即可。
采集ADC值,开启转换,等待转换完毕,清零标志位,得到ADC值。
最后将采集的值通过公式转换为电压即可。
仿真视频
/**
******************************************************************************
* @file main.c
* @author Alex——小白
* @version V1.0
* @date 2021.1.20
* @brief 头文件调用,类型重定义
* @store Proteus仿真店子——公众号
* @Link https://shop484534014.taobao.com/
* @Email 844545015@qq.com
******************************************************************************
* @attention All Rights Reserved
**/
#include /* Touch Pad的步进值为0.5V,即10档 这里将电压放大100倍,便于数据处理 */ void main(void) { uint16_t adcValue = 0; uint16_t vol = 0; uint8_t cnt = 0; DDRB_DDB3 = 1; AD.ADC_Init(0); //ADC通道0 LCD.LCD1602_Init(); LCD.LCD1602_WriteStr(0,2,"ADC:"); LCD.LCD1602_WriteStr(1,2,"Vol:"); Delay.Delay_ms(1000); while(1) { adcValue = AD.ADC_GetValue(); //ADC数据采集 vol = (uint16_t)(adcValue * 5.0 * 100 / 1024); //放大100倍 LCD.LCD1602_WriteChar(0,8,adcValue/1000 + '0'); LCD.LCD1602_WriteChar(0,9,adcValue%1000/100 + '0'); LCD.LCD1602_WriteChar(0,10,adcValue%1000%100/10 + '0'); LCD.LCD1602_WriteChar(0,11,adcValue%1000%100%10 + '0'); LCD.LCD1602_WriteChar(1,8,vol/100 + '0'); LCD.LCD1602_WriteChar(1,9,'.'); LCD.LCD1602_WriteChar(1,10,vol%100/10 + '0'); LCD.LCD1602_WriteChar(1,11,vol%100%10 + '0'); if(vol > 250) //实际电压值>2.5V时,蜂鸣器报警 { for(cnt = 0;cnt < 80;cnt++) { PORTB_PORTB3 = 0; Delay.Delay_us(2); PORTB_PORTB3 = 1; Delay.Delay_us(2); } } } } /******************************************************** End Of File ********************************************************/
上一篇:ATmega16开发板教程(9)——KeyPad
下一篇:ATmega16开发板教程(7)——LCD1602
推荐阅读最新更新时间:2024-11-11 22:46
设计资源 培训 开发板 精华推荐
- AM2G-2409DZ ±9V 2 瓦 DC-DC 转换器的典型应用
- 2021年电赛K题
- AT91SAM9G10-EK2、SAM9G10-EK2 评估套件基于 SMART AT91SAM9G10 SAM9G MCU
- 17W、-33V、-12V、3.3V、5V、8V、12V交流转直流多路输出电源
- AD8051AR-EBZ,AD8051ARZ 单高速运算放大器评估板,采用 8 引脚 SOIC 封装
- LT1021DCN8-5 电压基准作为超线性铂金温度传感器的典型应用
- FUSB15201DUAL60WGEVB:使用 FUSB15201 和 NCV81599 的双端口 60W 参考设计
- HSC-ADC-EVALA-SC,使用 DT72V283、16 位、133 MSPS 高速模数转换器的评估板
- NSI45020AT1G 大电流 LED 灯串的典型应用
- 基于ESP8266的远程开机模块