当前位置:文档之家› LCD显示的触摸屏控制器的制作

LCD显示的触摸屏控制器的制作

LCD显示的触摸屏控制器的制作1.问题的引入现代社会随着信息及电子设备产品市场的迅速壮大,以及人们对电子产品智能化、人性化要求的不断提高,触摸屏作为一种便捷的输入接口,得到了广泛的应用。

现在市面上已有的触摸屏控制器普遍价格比较高且性能相对比较固定,一些场合下无法满足用户的实际需求。

基于这些原因,我们设计并制作了最基本的基于51单片机的触摸屏控制器。

为了更好的学习51单片机,在制作控制器时,我们尽量的驱动了更多的外围模块。

使用12864液晶及LED数码管动态扫描作为显示模块;AT24C02作为掉电保护存储模块;4*4矩阵键盘作为输入控制模块。

2.方法的研究2.1系统总设计方案图:系统的总设计方案图如图1所示。

2.2主要模块的设计:2.2.1 51单片机采用89C52作为单片机控制芯片。

89C52有8K程序存储器,256字节数据存储器,32条I/O口线,2个可编程定时/计数器,5个中断源,2个优先级,一个全双工串行通信口,片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。

最高振荡频率为12M。

2.2.212864液晶12864A-1汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。

我们采用并行的方式传输数据,接口的时序如图所示:MPU写资料到模块MPU从模块读出资料按照其时序可编程实现,12864液晶的显示。

还应当注意汉字显示的坐标:2.2.3 XPT2046触摸屏控制芯片XPT2046内部有一个由多个模拟开关组成的供电测量电路网络和12位的A/D转换。

XPT2046根据微控制器发来的不同测量命令导通不同的模拟开关,以便向工作面电极对提供电压,并把相应测量电极上的触点坐标位置所对应的电压模拟量引入A/D 转换器。

我们采用的是差动控制模式,可根据XPT2046芯片的典型电路和时序图进行电路的连接和软件的编程控制。

系统总设计方案图:信息采集、A/D转换触屏信号控制核心信息处理信息显示图1 系统总设计方案图输入控制3.算法的实现3.1 电路原理图3.2程序流程图4.程序设计及运行结果4.1程序的设计见附录14.2运行结果:5.结果分析与设计体会5.1结果分析实现了触摸屏控制器的基本功能。

即在触摸屏上点击一点,将在12864液晶上显示该点的X,Y坐标(为量化了的坐标,范围在0到100之间),数码管上也将动态扫描显示该坐标值。

在触摸屏上点击若干次,将存储以前点击的14次坐标值。

当按动1到14号按键时,将在12864液晶及数码管上显示相应的14次坐标值(是前14次记录的坐标值)。

当按动第15号按键时将显示点击的次数(掉电后仍然存在)。

当按动第16号按键时,当前坐标值、存储坐标的数组及点击次数将清零,液晶将显示“系统复位!”要实现触摸屏更复杂的功能,需要更进一步地进行设计。

5.2设计体会学习了单片机的基本原理,收获了不少东西,但是只是学习书本上的东西是远远不够的,要不断地实践,多做实验,调通单片机外围电路最基本的模块,这样才能够学好。

不仅如此,还要学会设计单片机的外围电路,学会使用画图软件,画出电路板,这样才能够学有所获。

在制作该触摸屏控制器时,也让我知道了单独调通单片机的每个模块不是很难,但是同时进行多个模块设计时,编程的结果不一定能在实际中正确地调试出来。

实际的结果和自己想象的理想结果有一定的差距,所以要多多编写程序,注意编程和程序调试时的一些技巧。

通过这次单片机课程设计,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。

创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。

设计结果能够符合题意,们在学会创新的基础上,同时还懂得合作精神的重要性,学会了与他人合作。

同时在具体的制作过程中我发现现在书本上的知识与实际的应用存在着不小的差距,书本上的知识很多都是理想化后的结论,忽略了很多实际的因素,或者涉及的不全面,可在实际的应用时这些是不能被忽略的,我们不得不考虑这方的问题,这让我们无法根据书上的理论就轻易得到预想中的结果,有时结果甚至很差别很大。

通过这次实践使我更深刻的体会到了理论联系实际的重要性,我们在今后的学习工作中会更加的注重实际,避免称为只会纸上谈兵的赵括。

总之,这次单片机课程的设计让我受益匪浅,以后我会更加注重自己的实践能力。

附录:1.程序的设计:#include<reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar b,c,d,i,a1,a2,bai,shi,ge,bai1,shi1,ge1;uint ADS_Y,ADS_X;sbit PEN=P1^7; //XPT2046引脚sbit DCLK=P1^3;sbit CS=P1^4;sbit DIN=P1^5;sbit DOUT=P1^6;sbit scl=P1^1; //AT24C02引脚sbit sda=P1^2;sbit wp=P1^0;sbit rs=P2^4; //12864引脚sbit rw=P2^5;sbit en=P2^6;uchar code table_led[]={//数码管编码表0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x3f};/uchar cunchushu1[15]={0};uchar cunchushu2[15]={0};uchar table_12864[]={0x58,0x3a,0,0,0,0x20,0x20,0x59,0x3a,0,0,0};//12864显示{X: Y: };uchar code table_wenzi1[]={"触摸屏坐标:"};//12864显示文字各种情况uchar code table_wenzi2[]={"触摸屏点击次数:"};uchar code table_wenzi3[]={"系统复位! "};uchar table_wenzi4[]={"触摸屏历史记录"};uchar table_wenzi5[]={" "};uchar table_wenzi6[]={" "};//子函数的申明uchar keyscan1(void);uchar keyscan();void delay(uint x);void led_display();void delay_10us(void);init_A T24C();start();stop();void delay_50us(uint);write(uchar);uchar read();respon();norespon();write1(uchar,uchar);uchar read1(uchar);write_com(uchar);write_date(uchar);display_12864();init_12864();display_wenzi1();display_wenzi2();display_wenzi3();display_wenzi4();display_wenzi5();display_wenzi6();void Write_2046(uchar);uint Read_2046();void XPT2046();init_bianliang()//初始化变量{bai=shi=ge=bai1=shi1=ge1=0;b=c=d=a1=a2=i=0;for(i=0;i<15;i++){cunchushu1[i]=0;}for(i=0;i<15;i++){cunchushu2[i]=0;}wp=0;table_12864[2]=0x30;table_12864[3]=0x30;table_12864[4]=0x30;table_12864[9]=0x30;table_12864[10]=0x30;table_12864[11]=0x30;ADS_X=0;ADS_Y=0;}main(){ init_12864();init_bianliang();display_wenzi1();//第一行显示"触摸屏坐标:"display_12864(); //第三行显示"X: Y: "XPT2046();while(1){if(b==1)//触摸屏是否有新的点击(是否有笔中断){ b=0;//如果有则进行数据处理,得到在12864和bai=ADS_X/100;//数码管上显示的数据bai1=ADS_Y/100;table_12864[2]=bai+0x30;table_12864[9]=bai1+0x30;shi=ADS_X%100/10;shi1=ADS_Y%100/10;table_12864[3]=shi+0x30;table_12864[10]=shi1+0x30;ge=ADS_X%10;ge1=ADS_Y%10;table_12864[4]=ge+0x30;table_12864[11]=ge1+0x30;display_12864();}led_display();//进行数码管上的动态扫描显示if(PEN==0) //是否有触摸屏的点击(是否有笔中断){ XPT2046();//如果有,则控制XPT2046b=1; //进行电压的模数转换,ADS_X/=40;//得到横纵坐标的数字电压,并进行处理ADS_Y/=40;//得到横纵坐标值cunchushu1[0]=ADS_X;for(i=14;i>0;i--){cunchushu1[i]=cunchushu1[i-1];} //将处理的横纵坐标值存储到数组中cunchushu2[0]=ADS_Y;for(i=14;i>0;i--){cunchushu2[i]=cunchushu2[i-1];}a1=1;while(PEN==0);//等待笔触中断结束}d=keyscan();//进行键盘扫描if(d!=0){ if((d!=15)&&(d!=16))//按下1到14号键在{ADS_X=cunchushu1[d];//12864和数码管上分别显示ADS_Y=cunchushu2[d]; //以往14次记录的点击坐标值display_wenzi4();}b=1;if(d==15) //按下15号键显示点击的次数{a2=read1(2); display_wenzi2();display_wenzi6();bai1=bai=a2/100;shi1=shi=a2%100/10;ge1=ge=a2%10;b=0;}if(d==16) //按下16号键,进行系统复位{ a2=0; //即12864显示系统复位wp=0; //数码管显示的值为零write1(2,a2); //将存储下来的14次记录值清零wp=1; //将存放在24C02中的点击次数值清零for(i=0;i<15;i++){cunchushu1[i]=0;cunchushu2[i]=0;}display_wenzi3();display_wenzi5();bai=0;shi=0;ge=0;bai1=0;shi1=0;ge1=0;b=0;}}if(a1==1) //将点击次数存储到AT24C02{a1=0;a2=read1(2);a2++;wp=0;write1(2,a2);wp=1;display_wenzi1();}}}void led_display()//数码管动态扫描显示子程序{ P2=0x89;P0=table_led[bai];delay(2);P2=0x8a;P0=table_led[shi];delay(2);P2=0x8b;P0=table_led[ge];delay(2);P2=0x8d;P0=table_led[bai1];delay(2);P2=0x8e;P0=table_led[shi1];delay(2);P2=0x8f;P0=table_led[ge1];delay(2);}uchar keyscan()//键盘子函数{uchar key;key=keyscan1(); //调用键盘扫描,switch(key) // 按下相应的键显示相对应的码值{case 0x7e:c=4;break;case 0x7d:c=8;break;case 0x7b:c=12;break;case 0x77:c=16;break;case 0xbe:c=3;break;case 0xbd:c=7;break;case 0xbb:c=11;break;case 0xb7:c=15;break;case 0xde:c=2;break;case 0xdd:c=6;break;case 0xdb:c=10;break;case 0xd7:c=14;break;case 0xee:c=1;break;case 0xed:c=5;break;case 0xeb:c=9;break; case 0xe7:c=13;break;case 0xff:c=0;break; }return c;}uchar keyscan1(void) //键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值中间变量P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{ cord_h=P3&0x0f; //读入列线值P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}return(0xff); //返回该值}//延时子函数void delay(uint x){ unsigned char a,b,c;for(;x>0;x--){for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}}void delay_50us(uint x){ for(;x>0;x--){unsigned char a,b;for(b=1;b>0;b--)for(a=22;a>0;a--);}}void delay_10us(void) //误差0us{ unsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);}//AT24C02子程序I2C时序write1(uchar add,uchar date){init_A T24C();start();write(0xae);respon();write(add);respon();write(date);respon();stop();}uchar read1(uchar add){uchar a;init_A T24C();start();write(0xae);respon();write(add);respon();start();write(0xaf);respon();a=read();norespon();stop();return a;}start(){sda=1;delay_10us();scl=1;delay_10us();sda=0;delay_10us();}stop(){sda=0;delay_10us();scl=1;delay_10us();sda=1;delay_10us();}write(uchar x){uchar i;for(i=0;i<8;i++){scl=0;delay_10us();x=x<<1;sda=CY;delay_10us();scl=1;delay_10us();}scl=0;delay_10us();sda=1;delay_10us();}uchar read(){ uchar i,x;scl=0;delay_10us();sda=1;delay_10us();for(i=0;i<8;i++){scl=1;delay_10us();x=(x<<1)|sda;scl=0;delay_10us();}return x;}respon(){uchar i;scl=1;delay_10us();while((sda==1)&&(i<250))i++;scl=0;delay_10us();}norespon(){ scl=1;delay_10us();sda=1;delay_10us();scl=0;delay_10us();}init_A T24C(){ scl=1;delay_10us();sda=1;delay_10us();}//液晶12864write_com(uchar com)//写指令{ rs=0;en=0;P0=com;en=1;delay_50us(1);en=0;}write_date(uchar date)//写数据{ rs=1;en=0;P0=date;en=1;delay_50us(1);en=0;}display_12864()//显示所需文字{ uchar i;write_com(0x88);for(i=0;i<12;i++){write_date(table_12864[i]);}}display_wenzi1(){ uchar i;write_com(0x90);for(i=0;i<16;i++){write_date(table_wenzi1[i]);}}display_wenzi2(){ uchar i;write_com(0x90);for(i=0;i<16;i++){write_date(table_wenzi2[i]);}}display_wenzi3(){ uchar i;write_com(0x90);for(i=0;i<16;i++){write_date(table_wenzi3[i]);}}display_wenzi4(){ uchar i;write_com(0x90);for(i=0;i<14;i++){write_date(table_wenzi4[i]);}if(d<10){write_date(0x30+d);}if(d>9){write_date(0x30+d+7);}}display_wenzi5(){ uchar i;write_com(0x88);for(i=0;i<16;i++){write_date(table_wenzi5[i]);}}display_wenzi6(){ uchar i;write_com(0x88);table_wenzi6[3]=a2/100+0x30;table_wenzi6[4]=a2%100/10+0x30;table_wenzi6[5]=a2%10+0x30;for(i=0;i<16;i++){write_date(table_wenzi6[i]);}}init_12864()//初始化12864{rw=0;delay(10);write_com(0x30);write_com(0x30);write_com(0x0c);write_com(0x01);delay(10);write_com(0x06);}//XPT2046void Write_2046(uchar num)//向2046写指令{ uchar count=0;DCLK=0;for(count=0;count<8;count++){num<<=1;DIN=CY;DCLK=0; _nop_();_nop_();_nop_(); //上升沿有效DCLK=1; _nop_();_nop_();_nop_();}}uint Read_2046() //从2046中读出数据{ uchar count=0;uint Num=0;for(count=0;count<12;count++){Num<<=1;DCLK=1; _nop_();_nop_();_nop_(); //下降沿有效DCLK=0; _nop_();_nop_();_nop_();if(DOUT) Num++;} for(count=0;count<4;count++) //无用的四个时钟{DCLK=1; _nop_();_nop_();_nop_();DCLK=0; _nop_();_nop_();_nop_();}return(Num);}void XPT2046()//读X坐标读Y坐标{ CS=0;Write_2046(0x90); //送控制字10010000即用差分方式读X坐标DCLK=1; _nop_();DCLK=0; _nop_();ADS_Y=Read_2046(); //读Y值Write_2046(0xD0); //送控制字11010000即用差分方式读Y坐标DCLK=1; _nop_();DCLK=0; _nop_();ADS_X=Read_2046(); //读X值CS=1;}。

相关主题