单片机实验11:ADC实现电位器
时间:2022-09-20 08:00:00
ADC实验中使用的芯片信号模拟信号转换为数字信号STC89C52,A/D芯片为XPT2046。
点击了解XPT2046
单片机晶振为11.0592
实验源代码:
- XPT2046.h
#include #include #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[4]; //数组用于P0的段选
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;
if(n == 50) //n用于调控使用LOAD_AD获取数据的频率
{
temp = LOAD_AD(0x94);
n=0;
}
n++;
number[0] = duanxuan[temp/1000]; //给数组内的数组分别赋值,千
number[1] = duanxuan[temp%1000/100]; //百
number[2] = duanxuan[temp%100/10]; //十
number[3] = duanxuan[temp%10]; //个
}
void dispaly() //数码管显示函数
{
int i;
for(i=0;i<4;i++) //4代表只有前四位数码管显示
{
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;
}
P0 = number[i]; //P0的段选来调控每一位显示的内容
delay_xms(10); //延时10ms
P0 = 0x0; //消影
}
}
void main()
{
while(1)
{
data_AD(); //获取数据
dispaly(); //将数据显示
}
}
静态变量
1、 未被初始化的静态变量自动初始化为0
2、静态存储区的数据不会因为函数退出而释放空间,在定义静态变量之后只初始化一次,以后的再次调用不会再重新初始化,而是用上次运行后的结果。
3、因为静态变量的值存储在静态存储区,而函数的参数存储在堆中,所以静态变量不能作为形参进行传递。
4、静态局部变量作用域需要注意,静态局部变量与静态全局变量不同,静态局部变量只在作用域内起作用。
这个实验的源代码中Main.c中的static uchar n 就必须使用static静态局部变量,如果没有static,每次主函数调用data_AD()函数n就会被重新初始化为0,从而影响 if 的判定而且还不会报错,而静态局部变量则不会,这样就可以做为 if 的条件来调节LOAD_AD()函数的使用频率。(对应静态变量第二条)