ADC实现电压测量,XPT2046芯片可测电压范围为 0 ~ 6V,分辨率为4095
点击了解XPT2046
单片机晶振为11.0592
实验源代码:
- XPT2046.h
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DIN = P3^4;
sbit ADCS = P3^5;
sbit DCLK = P3^6;
sbit DOUT = P3^7;
sbit led2 = P2^2;
sbit led3 = P2^3;
sbit led4 = P2^4;
XPT2046.c
#include "XPT2046.h"
void WRITE_AD(uchar dat) //写入数据函数
{
uchar i;
DCLK = 0;
for(i=0;i<8;i++)
{
DIN = dat >> 7; //将dat右移7位赋值给DIN,值得注意的是dat本身并没有变化
dat <<= 1; //将dat左移1位赋值给dat,此时dat本身发生了变化
DCLK = 0;
DCLK = 1;
}
}
uint READ_AD() //读取写入的数据
{
uchar i;
uint dat=0;
DCLK = 0;
for(i=0;i<12;i++)
{
dat <<= 1; //读取时要先位移
DCLK = 1;
DCLK = 0;
dat |= DOUT; //将DOUT口的数据取反再赋值给dat
}
return dat;
}
uint LOAD_AD(uchar cmd) //载入数据函数
{
uint AD_value;
uchar i;
ADCS = 0; //拉低片选
DCLK = 0;
WRITE_AD(cmd); //先写入数据
for(i=6;i>0;i--); //给写入的数据一点转换的时间
DCLK = 1;
_nop_(); //_nop_()延时一个机器周期
_nop_();
DCLK = 0;
_nop_();
_nop_();
AD_value = READ_AD(); //读取写入后的数据
ADCS = 1; //调高片选
return AD_value;
}
- Main.c
#include "reg52.h"
#include "XPT2046.h"
uint LOAD_AD(uchar cmd); //声明函数存在
number[5]; //数组用于P0的段选
uchar code duanxuan_xs[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd}; //带小数点的数字 0 ~ 6
uchar code duanxuan[] = {0x3f,0x06,0x5b,0x4f, //0,1,2,3
0x66,0x6d,0x7d,0x07, //4,5,6,7
0x7f,0x6f,0x77,0x7c, //8,9,A,B
0x39,0x5e,0x79,0x71}; //C,D,E,F 段选
void delay_xms(uchar i) //延时函数
{
uchar m;
for(;i>0;i--)
for(m=110;m>0;m--);
}
void data_AD() //获得电位器的数据
{
static uchar n=0; //声明静态无符号字符型n,注意这里一点要是静态变量
uint temp; //临时变量
uint Vol; //存储电压
if(n == 50) //n用于调控使用LOAD_AD获取数据的频率
{
temp = LOAD_AD(0x94);
Vol = (60000/4095)*temp; //将十分微小的电压值放大10000倍,最大为6V,放大后为60000
n=0;
}
n++;
number[0] = duanxuan_xs[Vol/10000]; //存储个位上的数据
number[1] = duanxuan[Vol%10000/1000]; //十分位
number[2] = duanxuan[Vol%1000/100]; //百分位
number[3] = duanxuan[Vol%100/10]; //千分位
number[4] = duanxuan[Vol%10]; //万分位
}
void dispaly() //数码管显示函数
{
int i;
for(i=0;i<6;i++) //6代表只有前六位数码管显示,第六位为单位“ V ”
{
switch(i)
{
case(0):led2=1,led3=1,led4=1;break;
case(1):led2=0,led3=1,led4=1;break;
case(2):led2=1,led3=0,led4=1;break;
case(3):led2=0,led3=0,led4=1;break;
case(4):led2=1,led3=1,led4=0;break;
case(5):led2=0,led3=1,led4=0;break;
case(6):led2=1,led3=0,led4=0;break;
case(7):led2=0,led3=0,led4=0;break;
}
if(i==5)
{
P0 = 0x3e; //在数字结尾显示“ V ”
}
else
{
P0 = number[i]; //P0的段选来调控每一位显示的内容
}
delay_xms(10); //延时10ms
P0 = 0x0; //消影
}
}
void main()
{
while(1)
{
data_AD(); //获取数据
dispaly(); //将数据显示
}
}
实验结果