51单片机控制的12864显示,有文字,图片,动态图片,以及PROTUES仿真等非常全面
以上压缩包所有内容下载:
LCD12864.zip
(13.61 MB, 下载次数: 235)
部分程序预览:
- /***
- 程序:LCD12864显示图形
- 内容:在12864上显示正弦曲线——按键可调频率和幅度
- 学习板:HOT-51
- 软件:keil uVision3
- 液晶:QY12864HZ1
- 作者:大海橡树
- 整理日期:2010-12-08
- 修改:无
- 备注:有什么错误的地方,欢迎网友们到空间留言
- O(∩_∩)O~
- *****/
- #include<AT89X52.h>
- #include<math.h>
- #include"ZB.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define LCD_databus P0 //LCD数据总线连接P0口
- sbit RS=P2^5;
- sbit RW=P2^6;
- sbit EN=P2^7;//LCD12864三个控制位
- sbit DQ=P2^3;//DS18B20数据线
- sbit KEY1=P3^2;
- sbit KEY2=P3^3;
- sbit KEY3=P3^4;
- uchar key_value;
- uchar HZ1[]="周期";
- uchar HZ2[]="幅度";
- void delay(uint i) //延时函数
- {
- while(--i);
- }
- void Read_busy() //LCD12864忙检测
- {
- RS=0;
- RW=1;
- EN=1;
- LCD_databus=0xFF;
- while(LCD_databus & 0x80); //判断最高位,1---busy,0---Nobusy
- EN=0;
- }
- void write_LCD_command(uchar value)//写指令
- {
- RS=0;
- RW=0;
- EN=1;
- LCD_databus=value;
- delay(7);
- EN=0;
- }
- void write_LCD_data(uchar value)//写数据
- {
- RS=1;
- RW=0;
- EN=1;
- LCD_databus=value;
- delay(7);
- EN=0;
- }
- void init_LCD() //初始化LCD
- {
- write_LCD_command(0x30); //8位数,基本指令
- delay(100);
- write_LCD_command(0x30);
- delay(37);
- write_LCD_command(0x0C); //开显示,不显示光标,光标不闪烁
- delay(100);
- write_LCD_command(0x01); //清屏指令
- delay(100);
- write_LCD_command(0x06); //没写入数据,地址指针加1
- }
- void Clear_GDRAM() //清楚GDRAM
- {
- uchar x,y;
- for(y=0;y<64;y++)
- {
- for(x=0;x<16;x++)
- {
- write_LCD_command(0x34);
- write_LCD_command(y+0x80); //先送垂直地址
- write_LCD_command(x+0x80); //后送水平地址
- write_LCD_command(0x30); //基本指令
- write_LCD_data(0x00); //写入数据0
- write_LCD_data(0x00);
- }
- }
- }
- uchar ReadByte() //读LCD
- {
- uchar Read_value;
- Read_busy();
- RS=1;
- RW=1;
- EN=0;
- EN=1;
- Read_value=LCD_databus;
- EN=0;
-
- return Read_value;
- }
- void display_BMP(uchar *address)//显示图片
- {
- uchar i,j;
- for(i=16;i<32;i++)
- {
- write_LCD_command(0x80+i); //先送垂直地址
- write_LCD_command(0x80); //再送水平地址
- for(j=0;j<16;j++)
- {
- write_LCD_data(*address);//写入数据
- address++;
- }
- }
-
- for(i=0;i<32;i++)
- {
- write_LCD_command(0x80+i);//先送垂直地址
- write_LCD_command(0x88); //再送水平地址
- for(j=0;j<16;j++)
- {
- write_LCD_data(*address);
- address++;
- }
- }
-
- }
- void Draw_dots(uchar x,uchar y,uchar color)
- {
- uchar ROW,xlabel,xlabel_bit;
- uchar Read_H,Read_L; //读LCD中的数据
- write_LCD_command(0x34); //扩充指令
- write_LCD_command(0x36); //打开绘图指令
- xlabel=x>>4; //取16*16首地址
- xlabel_bit=x & 0x0F; //计算该点在16位数据的第几位
- if(y<32) //如果是上半屏,上下半屏y都是0--31
- {
- ROW=y;
- }
- else //显示的是下半屏
- {
- ROW=y-32;
- xlabel+=8; //规定显示在下半屏
- }
- write_LCD_command(ROW+0x80); //送入垂直地址
- write_LCD_command(xlabel+0x80);//再送入水平地址
- ReadByte(); //读取当前GDRAM数据前腰进行一次空读,接下来就可以读出数据了
- Read_H=ReadByte(); //读高8位
- Read_L=ReadByte(); //读低8位
-
- write_LCD_command(ROW+0x80); //送入垂直地址
- write_LCD_command(xlabel+0x80); //再送入水平地址
-
- if(xlabel_bit<8)
- {
- switch(color)
- {
- case 0:Read_H &= (~(0x01<<(7-xlabel_bit)));//若变白
- break;
- case 1:Read_H |= (0x01<<(7-xlabel_bit));//若涂黑
- break;
- case 2:Read_H ^= (0x01<<(7-xlabel_bit));//若反转
- break;
- default:break;
- }
- write_LCD_data(Read_H);//将数据写入GDRAM
- write_LCD_data(Read_L);//先写高位,再写低位(地址指针顺序)
- }
- else
- {
- switch(color)//color设置
- {
- case 0: Read_L &= (~(0x01<<(15-xlabel_bit)));//若变白
- break;
- case 1: Read_L |= (0x01<<(15-xlabel_bit));//若涂黑
- break;
- case 2: Read_L ^= (0x01<<(15-xlabel_bit));//若反转
- break;
- default:break;
- }
- write_LCD_data(Read_H);
- write_LCD_data(Read_L);//写入数据
- }
-
- write_LCD_command(0x30);//回到普通模式
- }
- void main()
- {
- uchar i,j;
- uchar num;
- uchar w=10,A=6;
- init_LCD();
- Clear_GDRAM();
- write_LCD_command(0x36);
- display_BMP(ZB);
- while(1)
- {
- write_LCD_command(0x30);
- write_LCD_command(0x80);
- write_LCD_data('T');
- write_LCD_data(':');
- write_LCD_data(2*w/100+0x30);
- write_LCD_data(2*w%100/10+0x30);
- write_LCD_data(2*w%10+0x30);
- write_LCD_command(0x83);
- write_LCD_data('A');
- write_LCD_data(':');
- write_LCD_data(A/10+0x30);
- write_LCD_data(A%10+0x30);
- write_LCD_command(0x36);
- for(i=13;i<128;i++)
- {
- j=35-A*sin((i-13)*3.14/w);
- Draw_dots(i,j,1);
- delay(400);
- }
- /**********以下为按键扫描函数**************/
- if(KEY1==0) //模式键按下
- {
- delay(2000);
- if(KEY1==0)
- {
- while(!KEY1);
- key_value++;
- if(key_value>2)
- key_value=0;
- }
- }
- if(key_value==1) //若选择的是周期模式
- {
- write_LCD_command(0x30);
- write_LCD_command(0x86);
- for(num=0;num<4;num++)
- {
- write_LCD_data(HZ1[num]); //显示"周期"汉字
- }
- if(KEY2==0) //加键按下时
- {
- delay(1500);
- if(KEY2==0)
- {
- while(!KEY2);
- w=w+5; //w加
- if(w==65)
- w=10;
- Clear_GDRAM();
- write_LCD_command(0x36);//重新显示图形
- display_BMP(ZB);
- }
- }
- if(KEY3==0)
- {
- delay(2000);
- if(KEY3==0)
- {
- while(!KEY3);
- if(w>=10)
- w=w-5;
- Clear_GDRAM();
- write_LCD_command(0x36);
- display_BMP(ZB); //重新显示图形
- }
- }
- }
- if(key_value==2) //若选择的是幅度模式
- {
- write_LCD_command(0x30);
- write_LCD_command(0x86);
- for(num=0;num<4;num++)
- {
- write_LCD_data(HZ2[num]);
- }
- if(KEY2==0)
- {
- delay(1500);
- if(KEY2==0)
- {
- while(!KEY2);
- A=A+2;
- if(A==22)
- A=8;
- Clear_GDRAM();
- write_LCD_command(0x36);
- display_BMP(ZB);
- }
- }
- if(KEY3==0)
- {
- delay(2000);
- if(KEY3==0)
- {
- while(!KEY3);
- if(A>=6)
- A=A-2;
- Clear_GDRAM();
- write_LCD_command(0x36);
- display_BMP(ZB);
- }
- }
- }
- }
- }
复制代码
|