/************************************************************************************** * 电位器AD实验 * 实现现象:下载程序后数码管后4位显示电位器检测的AD值,范围是0-4095,一般达不到最大,这个受 你供电电压的影响. 注意事项:如果不想让点阵模块显示,可以将74HC595模块上的JP595短接片拔掉。 ***************************************************************************************/ #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 #include"XPT2046.h" typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; u8 disp[4]; u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; /******************************************************************************* * 函 数 名 : delay * 函数功能 : 延时函数,i=1时,大约延时10us *******************************************************************************/ void delay(u16 i) { while(i--); } /******************************************************************************* * 函数名 :datapros() * 函数功能 :数据处理函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void datapros() { u16 temp; static u8 i; if(i==50) //表示隔多长时间就读一次选通的数据(选通的通道) { i=0; temp = Read_AD_Data(0x94); // AIN0 电位器 读取数据 } i++; disp[0]=smgduan[temp/1000];//千位 因为是12位的AD转换芯片,故而最大最为4095 故而为四位 disp[1]=smgduan[temp%1000/100];//百位 disp[2]=smgduan[temp%1000%100/10];//十位 disp[3]=smgduan[temp%1000%100%10]; } /******************************************************************************* * 函数名 :DigDisplay() * 函数功能 :数码管显示函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void DigDisplay() { u8 i; for(i=0;i<4;i++) { switch(i) //位选,选择点亮的数码管, { case(0): LSA=0;LSB=0;LSC=0; break;//显示第0位 case(1): LSA=1;LSB=0;LSC=0; break;//显示第1位 case(2): LSA=0;LSB=1;LSC=0; break;//显示第2位 case(3): LSA=1;LSB=1;LSC=0; break;//显示第3位 } P0=disp[3-i];//发送数据 delay(100); //间隔一段时间扫描 P0=0x00;//消隐 } } /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main() { while(1) { datapros(); //数据处理函数 DigDisplay();//数码管显示函数 } } #include"XPT2046.h" /**************************************************************************** *函数名:SPI_Write *输 入:dat:写入数据 *输 出:无 *功 能:使用SPI写入数据 ****************************************************************************/ void SPI_Write(uchar dat) // 先将选通的通道值写入 { uchar i; CLK = 0; for(i=0; i<8; i++) //读取dat 也就是 选通的是哪一个通道 { DIN = dat >> 7; //放置最高位 按照时序图,最高位在右边 控制字节的输入 dat <<= 1; //存放数据时,最高位又在最左边,将最高位移走,次高位就成为最高位 CLK = 0; //上升沿放置数据 CLK = 1; } } /**************************************************************************** *函数名:SPI_Read *输 入:无 *输 出:dat:读取 到的数据 *功 能:使用SPI读取数据 ****************************************************************************/ uint SPI_Read(void) // 再读取 { uint i, dat=0; CLK = 0; for(i=0; i<12; i++) //接收12位数据 { dat <<= 1;//如果是写的话,先赋值后移位, 读的话就要先移位后赋值 CLK = 1; CLK = 0; dat |= DOUT; // 因为开始的时候,dat =0,这样就可以将输入的12位数据与0进行或运算,才会保证DOUT这个值的准确性 ,数字信号的输出 } return dat; } /**************************************************************************** *函数名:Read_AD_Data *输 入:cmd:读取的X或者Y *输 出:endValue:最终信号处理后返回的值 *功 能:读取触摸数据 ****************************************************************************/ uint Read_AD_Data(uchar cmd) //读取数据, 读取的时候,先写入要选通的那种通道(有四种选择),然后从该通道中再读取数据 ,之后再令CS片选为高电平,关闭该芯片 { uchar i; uint AD_Value; CLK = 0; CS = 0; SPI_Write(cmd); for(i=6; i>0; i--); //延时等待转换结果 CLK = 1; //发送一个时钟周期,清除BUSY DIN输入已经发送完成 _nop_(); _nop_(); CLK = 0; _nop_(); _nop_(); AD_Value=SPI_Read(); //此时,得到的不是电压值,只是一个12位的数据,如果要得到电压值,就必须要经过处理,比如5V*(AD_Value/(2^12))此时,才是电压值,并且为mV然后在扩大一定的倍数既可以 CS = 1; //之后,将片选信号拉高,这样这个芯片就不起作用 return AD_Value;//通过返回值得到读取后的值 } #ifndef __XPT2046_H_ #define __XPT2046_H_ //---包含头文件---// #include<reg52.h> #include<intrins.h> //---重定义关键词---// #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif #ifndef ulong #define ulong unsigned long #endif //---定义使用的IO口---// sbit DOUT = P3^7; //输出 sbit CLK = P3^6; //时钟 sbit DIN = P3^4; //输入 sbit CS = P3^5; //片选 uint Read_AD_Data(uchar cmd); uint SPI_Read(void); void SPI_Write(uchar dat); #endif