文章目录
- 一、ADC
- 1、分辨率
- 2、转换误差
- 3、转换速率
- 二、ADC转换原理
- 1、ADC转换原理
- 2、主要方法
- 3、逐次逼近型ADC
- 4、双积分型ADC
- 三、XPT2046芯片
- 1、主要特性
- 2、芯片引脚说明
- 3、模式选择
- 四、原理图
- 五、代码实例
- 1、电位器
- XPT2046.h
- XPT2046.c
- main.c
- 2、光敏传感器
- main.c
- 3、热敏传感器
- main.c
- 4、外部通道电压采集
- main.c
一、ADC
ADC(analog to digital converter)也称为模数转换器,是指一个将模拟信号转变为数字信号。
单片机在采集模拟信号时,通常都需要在前端加上A/D 芯片。
1、分辨率
ADC 的分辨率是指对于允许范围内的模拟信号,它能输出离散数字信号值的个数。
这些信号值通常用二进制数来存储,因此分辨率经常用比特作为单位,且这些离散值的个数是2的幂指数。
例如:12位ADC的分辨率就是12位,或者说分辨率为满刻度的1/(2^12)。
一个10V满刻度的12位ADC能分辨输入电压变化最小值是10V×1/(212)=2.4mV。
2、转换误差
转换误差通常是以输出误差的最大值形式给出。
它表示A/D转换器实际输出的数字量和理论上的输出数字量之间的差别。
常用最低有效位的倍数表示。
例如:给出相对误差≤±LSB/2,这就表明实际输出的数字量和理论上应得到的输出数字量之间的误差小于最低位的半个字。
3、转换速率
ADC 的转换速率是能够重复进行数据转换的速度,即每秒转换的次数。
而完成一次A/D转换所需的时间(包括稳定时间),则是转换速率的倒数。
二、ADC转换原理
1、ADC转换原理
AD 转换器(ADC)将模拟量转换为数字量通常要经过4个步骤:采样、保持、量化和编码。
采样:即是将一个时间上连续变化的模拟量转换为时间上离散变化的模拟量。
保持:将采样结果存储起来,直到下次采样,这个过程叫做保持。一般采样器和保持电路一起总称为采样保持电路。
量化:将采样电平归化为与之接近的离散数字电平,这个过程叫做量化。
编码:将量化后的结果按照一定数制形式表示就是编码。
2、主要方法
将采样电平(模拟值)转换为数字值时,主要有两类方法:直接比较型与间接比较型。
直接比较型:就是将输入模拟信号直接与标准的参考电压比较,从而得到数字量。常见的有并行ADC和逐次比较型ADC。
间接比较型:输入模拟量不是直接与参考电压比较,而是将二者变为中间的某种物理量在进行比较,然后将比较所得的结果进行数字编码。常见的有双积分型ADC。
3、逐次逼近型ADC
采用逐次逼近法的AD转换器是有一个比较器、DA转换器、缓冲寄存器(比较寄存器)和控制逻辑电路组成。
原理:
从高位到低位逐次试探比较,就像用天平秤物体,从重到轻逐级增减砝码进行试探。
过程:
1)通过置数选择寄存器置SRA最高位"1",其余为"0",经过AD转换成模拟电压Uo。与输入模拟电压Ui比较:
若Ui >=Uo,保留最高位"1"。
若Ui < Uo,置最高位"0"。
2)次高位"1",其余"0",重复以上过程,直到确定SAR的最低位应取"1"或"0"为止。
3)此时,SAR的内容就是对应输入模拟电压转换后的数字量。
4、双积分型ADC
采用双积分法的AD转换器由电子开关、积分器、比较器和控制逻辑等部件组成。
原理:
将输入电压变换成与其平均值成正比的时间间隔,再把此时间隔转换成数字量,属于间接转换。
过程:
先将开关接通待转换的模拟量Vi,Vi采样输入到积分器,积分器从零开始进行固定时间T的正向积分,时间T到后,开关再接通与Vi极性相反的基准电压Vref,将Vref输入到积分器,进行反向积分,直到输出为0V时停止积分。
Vi越大,积分器输出电压越大,反向积分时间也越长。
计数器在反向积分时间内所计的数值,就是输入模拟电压Vi所对应的数字量,实现了AD转换。
三、XPT2046芯片
XPT2046 是一款 4 线制电阻式触摸屏控制器,内含 12 位分辨率 125KHz转换速率逐步逼近型 A/D 转换器。
XPT2046 支持从 1.5V 到 5.25V 的低电压I/O 接口。
XPT2046 能通过执行两次 A/D 转换查出被按的屏幕位置,除此之外,还可以测量加在触摸屏上的压力。
内部自带 2.5V 参考电压,可以作为辅助输入、温度测量和电池监测之用,电池监测的电压范围可以从 0V 到 6V。
1、主要特性
①工作电压范围为 1.5V~5.25V
②支持 1.5V~5.25V 的数字 I/O 口
③内建 2.5V 参考电压源
④电源电压测量( 0V~6V)
⑤内建结温测量功能
⑥触摸压力测量
⑦采用 3 线制 SPI 通信接口
⑧具有自动省电功能
2、芯片引脚说明
3、模式选择
ADC可以配置为单端或差分模式。
选择VBAT、Temp和AUX时应该配置为单端模式;作为触摸屏应用时,应该配置为差分模式。
A2、A1、A0 和SER/DFR 控制位与XPT2046的配置关系:
单端输入配置:
差分输入配置:
控制时序:
控制命令格式:
四、原理图
XPT2046芯片的控制管脚接至单片机P3.4~P3.7 管脚上。
XPT2046芯片的ADC输入转换通道分别接入了AD1电位器、NTC1 热敏传感器、GR1光敏传感器,还有一个外接通道AIN3接在DAC(PWM)模块的J52端子上供外部模拟信号检测。
电位器对应的采集通道命令:0X94
光敏电阻对应的采集通道命令:0XA4
热敏电阻对应的采集通道命令:0XD4
外部输入AIN3对应的采集通道命令:0XE4
五、代码实例
1、电位器
数码管上显示AD模块采集电位器的电压值。
XPT2046.h
#ifndef_xpt2046_H#define_xpt2046_H#include"public.h"//管脚定义sbit DOUT=P3^7;//输出sbit CLK=P3^6;//时钟sbit DIN=P3^4;//输入sbit CS=P3^5;//片选//函数声明u16xpt2046_read_adc_value(u8 cmd);#endifXPT2046.c
#include"xpt2046.h"#include"intrins.h"/******************************************************************************* * 函 数 名 : xpt2046_wirte_data * 函数功能 : XPT2046写数据 * 输 入 : dat:写入的数据 * 输 出 : 无 *******************************************************************************/voidxpt2046_wirte_data(u8 dat){u8 i;CLK=0;_nop_();for(i=0;i<8;i++)//循环8次,每次传输一位,共一个字节{DIN=dat>>7;//先传高位再传低位dat<<=1;//将低位移到高位CLK=0;//CLK由低到高产生一个上升沿,从而写入数据_nop_();CLK=1;_nop_();}}/******************************************************************************* * 函 数 名 : xpt2046_read_data * 函数功能 : XPT2046读数据 * 输 入 : 无 * 输 出 : XPT2046返回12位数据 *******************************************************************************/u16xpt2046_read_data(void){u8 i;u16 dat=0;CLK=0;_nop_();for(i=0;i<12;i++)//循环12次,每次读取一位,大于一个字节数,所以返回值类型是u16{dat<<=1;CLK=1;_nop_();CLK=0;//CLK由高到低产生一个下降沿,从而读取数据_nop_();dat|=DOUT;//先读取高位,再读取低位。}returndat;}/******************************************************************************* * 函 数 名 : xpt2046_read_adc_value * 函数功能 : XPT2046读AD数据 * 输 入 : cmd:指令 * 输 出 : XPT2046返回AD值 *******************************************************************************/u16xpt2046_read_adc_value(u8 cmd){u8 i;u16 adc_value=0;CLK=0;//先拉低时钟CS=0;//使能XPT2046xpt2046_wirte_data(cmd);//发送命令字for(i=6;i>0;i--);//延时等待转换结果CLK=1;_nop_();CLK=0;//发送一个时钟,清除BUSY_nop_();adc_value=xpt2046_read_data();CS=1;//关闭XPT2046returnadc_value;}main.c
#include"public.h"#include"smg.h"#include"xpt2046.h"/******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/voidmain(){u16 adc_value=0;floatadc_vol;//ADC电压值u8 adc_buf[3];while(1){adc_value=xpt2046_read_adc_value(0x94);//测量电位器adc_vol=5.0*adc_value/4096;//将读取的AD值转换为电压adc_value=adc_vol*10;//放大10倍,即保留小数点后一位adc_buf[0]=gsmg_code[adc_value/10]|0x80;adc_buf[1]=gsmg_code[adc_value%10];adc_buf[2]=0x3e;//显示单位Vsmg_display(adc_buf,6);}}2、光敏传感器
数码管上显示光敏传感器采集的电压值。
main.c
#include"public.h"#include"smg.h"#include"xpt2046.h"voidmain(){u16 adc_value=0;u8 adc_buf[4];while(1){adc_value=xpt2046_read_adc_value(0xA4);//测量光敏电阻adc_buf[0]=gsmg_code[adc_value/1000];adc_buf[1]=gsmg_code[adc_value%1000/100];adc_buf[2]=gsmg_code[adc_value%1000%100/10];adc_buf[3]=gsmg_code[adc_value%1000%100%10];smg_display(adc_buf,5);}}3、热敏传感器
数码管上显示热敏传感器采集的电压值。
main.c
#include"public.h"#include"smg.h"#include"xpt2046.h"voidmain(){u16 adc_value=0;u8 adc_buf[4];while(1){adc_value=xpt2046_read_adc_value(0xD4);//测量热敏电阻adc_buf[0]=gsmg_code[adc_value/1000];adc_buf[1]=gsmg_code[adc_value%1000/100];adc_buf[2]=gsmg_code[adc_value%1000%100/10];adc_buf[3]=gsmg_code[adc_value%1000%100%10];smg_display(adc_buf,5);}}4、外部通道电压采集
数码管上显示AD模块采集外部通道AIN3的电压值
main.c
#include"public.h"#include"smg.h"#include"xpt2046.h"voidmain(){u16 adc_value=0;floatadc_vol;//ADC电压值u8 adc_buf[3];while(1){adc_value=xpt2046_read_adc_value(0xE4);//测量外部输入通道AIN3adc_vol=5.0*adc_value/4096;//将读取的AD值转换为电压adc_value=adc_vol*10;//放大10倍,即保留小数点后一位adc_buf[0]=gsmg_code[adc_value/10]|0x80;adc_buf[1]=gsmg_code[adc_value%10];adc_buf[2]=0x3e;//显示单位Vsmg_display(adc_buf,6);}}