12864液晶屏显示程序(几乎你能用12864干得 我都搞定了 哈哈)
这是用STC89C52单片机为核心板 全部都试验过 可以直接用可作为模版void init()
{ PCON=0x00; //单片机处于正常工作状态
TMOD=0x20; //定时器1工作在方式2 8位自动从装系统
TH1=0xfd;
TL1=0xfd; // 首次的装初值 9600
TI=0; //发送中断标志位
RI=0; //接受中断标志位
TR1=1; //定时器1控制 允许位
TF1=0; //定时器1中断标志位
SM0=0;
SM1=1;
REN=1;
EA=1;
ES=1; //打开串口中断
}
3、12864液晶屏(蓝底黑字) 51单片机显示史上最全的显示内容 (自己总结的)
#include<stdio.h> //调用数据类型
#include<reg52.h> //调用52引脚定义
#include<string.h> //字符操作指令
#include<math.h>
#define uint unsigned int
#define uchar unsigned char
uchar code LCD_data1[];
uchar code LCD_data2[];
uint codeLCD_data4[];
uchar code LCD_picture1[]; //人物图
uchar code LCD_picture2[]; //梦回广德
uchar code LCD_picture3[]; //小兔子
uchar code menu_pic[]; //标签图(6副)
sbit RS = P2^4; //并行指令数据选择信号
sbit RW = P2^5; //读写选择信号
sbit EN = P2^6; //使能端
sbit PSB = P2^1; //H并口数据 L串口数据
sbit RST = P2^3; //复位低电平有效
sbit Dataport = P0;
sbit Busyport = P0^7; //因为写指令时最高位为 BF
///////////////////////////////////////////////
uchar code LCD_data1[]=
{
"菩提本无树, "
"明镜亦非台! "
"本来无一物, "
"何处惹尘埃? "
};
uchar code LCD_data2[] ={
"there is more "
"god is agirl"
"人生若只如初见?"
"何事秋风悲画扇!"
};
uchar code LCD_data3[] ={
"E 通科技社! "
" "
" "
" "
};
uint codeLCD_data4[] = {156};
void delay_10ms(unsigned int n) //n*15ms延迟
{
unsigned int i,j;
for(i=n;i>0;i--)
for(j=2000;j>0;j--);
}
void delay(unsigned int n) //n*1us延迟 可以通过debug测试
{
unsigned int i,j;
for(i=n;i>0;i--)
for(j=10;j>0;j--);
}
///////////////判断 BF 信号////////////////////
void check_LCD_busy(void)
{
Dataport = 0xff;
RS = 0;
RW = 1; //读取液晶状态(BF)
EN = 1;
while(Busyport); //液晶工作时 BF 为1, 等待指令执行完成 后认为置零
EN = 0;
}
//////////////////写指令//////////////
void write_com(uchar command)
{
check_LCD_busy();
RS = 0; //命令
RW = 0;
delay(1);
P0 = command;
EN = 1;
delay(1);
EN = 0;
RS = 0;
delay(2);
RW = 1;
}
/////////////写数据//////////////////////////
void write_data(uchar dat)
{
check_LCD_busy();
RW = 0;
RS = 1;
delay(1);
P0 = dat;
EN = 1;
delay(1);
EN = 0;
RS = 0;
delay(2);
RW = 1;
}
//////////////清屏函数//////////////
void lcdClear(void)
{
write_com(0x01); //清屏指令
}
///////////////复位函数//////////////
void reset(void)
{
RST = 0; //低电平复位
delay(1);
RST = 1;
delay(10);
}
///////////////////////////////////清除GDRAM函数/////////////////////////////////////////////////
void Lcd12864_ClrGdRam(void) //说明一点 在DRAM 中第三行地址连着第一行地址 第四行地址连着第二行地址
{
uchar i,j,x;
i=0x80;
write_com(0x34); //开扩展指令集
for(j = 0;j < 32;j ++) //每一个汉字纵向有16个格
{
write_com(i++); //横坐标
write_com(0x80); //列坐标
for(x = 0;x < 32;x ++)
{
write_data(0x00); //地址清零
}
}
write_com(0x30); //返回基本指令集
}
///////////书写汉字///////////////////////此程序也可用于字符串显示////////////////
void dispSting(uchar X,Y,uchar *mesg) //定点显示字符
{
if(X==0)X=0x80;
else if(X==1) X=0x90;
else if(X==2)X=0x88;
else X=0x98;
Y = X + Y;
write_com(Y);
while(*mesg)
{
write_data(*mesg);
mesg++;
}
}
///////////////全屏字符显示///////////////////////////////////
void lcd_mesg(unsigned char code *adder1) //全屏显示字符
{
unsigned char i;
write_com(0x80);
delay(100);
for(i=0;i<16;i++)
{
write_data(*adder1);
adder1++;
}
write_com(0x90);
delay(100);
for(i=16;i<32;i++)
{
write_data(*adder1);
adder1++;
}
write_com(0x88);
delay(100);
for(i=32;i<48;i++)
{
write_data(*adder1);
adder1++;
}
write_com(0x98);
delay(100);
for(i=48;i<64;i++)
{
write_data(*adder1);
adder1++;
}
}
/////////////////显示字符串(定位写入字符串函数)//////////////////////////////////////////////////////////
void Lcd_wrnum(uchar x,y,uint code *num)
{
write_com(0x30);
y = y % 7 ; //舍去大于八的数据
switch(x)
{
case 1:
write_com(0x80 + y); break;
case 2:
write_com(0x90 + y); break;
case 3:
write_com(0x88 + y); break;
case 4:
write_com(0x98 + y); break;
default:
break;
}
if(*num / 100 != 0)
write_data(0x30 + *num / 100);
if(*num / 10 % 10 != 0)
write_data(0x30 + *num / 10 % 10);
write_data(0x30 + *num % 10);
}
///////////////全屏显示图像(128*64)///////////////////////////////////////////
void disppicture(uchar code *adder)
{
uint i,j;
////////////显示上半屏内容//////////////////////////
for(i=0;i<32;i++)
{
write_com(0x80+i); //写垂直地址 垂直地址不能自动加1
write_com(0x80); //写水平地址 水平地址从00到0f后自动变为00h80h-87h and 90h-97h
for(j=0;j<16;j++) //两个字节一块显示
{
write_data(*adder);
adder++;
}
}
///////////////显示下半屏内容///////////////
for(i=0;i<32;i++)
{
write_com(0x80+i); //写垂直地址 垂直地址不能自动加1
write_com(0x88); //写水平地址 水平地址从00到0f后自动变为00h 88h-8fh 和98h-9fh
for(j=0;j<16;j++)
{
write_data(*adder);
adder++;
}
}
}
///////////////显示半屏(下)内容//////////////////
void disppicture1()
{
uchar i,j,y;
///////////////显示下半屏内容///////////////
for(j=0;j<32;j++)
{
for(i=0;i<8;i++)
{
write_com(0x34);
write_com(0x80+y); //写垂直地址 垂直地址不能自动加1
write_com(0x88+i); //若改为0x80则是显示上半屏
write_com(0x30);
write_data(~LCD_picture3);
write_data(~LCD_picture3);
}
y++;
}
write_com(0x36);
}
/////////////////////////////////不同的位置画图(6副图片)////////////////////////////////////////////////////
void Lcd12864_anti_nor_pic (uchar cpl_sign,uchar menu_num)
{
uchar i,j,x,y;
x=menu_num*3; // 计算图片显示横坐标 为 0x80+(00h 03h 06h 08 0b 0e )
if(x>6) x--;
y=8;
for(j=0;j<24;j++)
{
for(i=0;i<2;i++) //该图片大小为16*24
{
write_com(0x34); //打开扩充指令集
write_com(0x80+y); //写列坐标地址
write_com(0x80+x+i); //分两次显示 16bit (i可以不要因为横坐标是自动加的)
write_com(0x30); //基本指令集
if(cpl_sign==1) // 图片反选
{
write_data(~menu_pic);
write_data(~menu_pic);
}
else // 正常显示
{
write_data(menu_pic);
write_data(menu_pic);
}
}
y++; //24+8=32
// if(y==32&&menu_num<3) {x+=8;y=0;} // 跳入下一屏横坐标地址地址到0x88y 地址变成0x80(个人觉得这句话在这里面很是没有必要 可能就是起到了指针转移的作用了)
}
write_com(0x36); //开绘图显示G=1
}
///////////////显示上下两幅图片/////////////////////////
void Lcd12864_anti_nor_2pic (uchar cpl_sign,uchar menu_num)
{
uchar i,j,x,y;
if(menu_num==0) //写横坐标
x=2;
else
x=10;
y=8;
for(j=0;j<24;j++) // 图片大小为32*24
{
for(i=0;i<2;i++) //连写两个字节
{
write_com(0x34); //开启扩展指令集
write_com(0x80+y); //写列地址
write_com(0x80+x+i); //纵坐标写满横坐标 上下分别为0x82、0x88+02
write_com(0x30);
if(cpl_sign==1) // 图片反选 (跟你的取字模的方式有关)
{
write_data(~menu_pic);
write_data(~menu_pic);
}
else // 正常显示
{
write_data(menu_pic);
write_data(menu_pic);
}
}
y++;
// if(y==32&&menu_num==0) {x+=8;y=0;}
}
write_com(0x36); //图像显示
}
///////////////显示上下4幅图片/////////////////////////
void Lcd12864_anti_nor_4pic (uchar cpl_sign,uchar menu_num)
{
uchar i,j,x,y;
x=menu_num*3;
if(x==0) //0x80
{
x=x+2;
}
else if(x==3) //0x83
{
x=x+2;
}
else if(x==6) //0x8a
{
x=x+4;
}
else if(x==9) //0x8d
{
x=x+4;
}
y=8;
for(j=0;j<24;j++) // 图片大小为32*24
{
for(i=0;i<2;i++) //连写两个字节
{
write_com(0x34); //开启扩展指令集
write_com(0x80+y); //写列地址
write_com(0x80+x+i); //纵坐标写满横坐标 上下分别为0x82、0x88+02
write_com(0x30);
if(cpl_sign==1) // 图片反选 (跟你的取字模的方式有关)
{
write_data(~menu_pic);
write_data(~menu_pic);
}
else // 正常显示
{
write_data(menu_pic);
write_data(menu_pic);
}
}
y++;
}
write_com(0x36); //图像显示
}
////////////////lcd字符初始化//////////////////////////////////
void lcdinit_str(void)
{
delay(100);
PSB=1; //八位并行串口方式
delay(100);
reset(); //复位
write_com(0x30); //设置基本指令集DL 必须为1 G=0;绘图显示off
delay(100);
write_com(0x30); //判断是否设置完
delay(100);
write_com(0x08); //关掉显示关掉游标
delay(100);
write_com(0x10); //设置游标位置允许光标设置移动
delay(100);
write_com(0x0C); //整体显示开
delay(100);
write_com(0x01); //清屏
delay(100);
write_com(0x06); // 光标从右向左加一位移动
delay(100);
}
//////////////LCD图片初始化/////////////////
void lcdinit_pic(void)
{
delay(40); //大于40ms延迟程序
PSB=1; //设置8位并口工作模式
delay(1);
reset();
write_com(0x36); //扩充指令集 开启绘图显示
delay_10ms(10); //延迟100ms
write_com(0x36); //判断是否设置完
delay(50); //大于37us
write_com(0x3E); //是否真需要
delay_10ms(10);
write_com(0x01); //清屏
delay(100);
}
//////////////////主程序////////////////////////////////////////
void main()
{
lcdinit_str(); //全屏字符显示部分
delay_10ms(10);
lcd_mesg(LCD_data1);
delay_10ms(200);
delay_10ms(200);
lcdClear(); //清屏
delay_10ms(10); //利用定点显示字符函数全屏显示
dispSting(0,0,"床前明月光,");
delay_10ms(10);
dispSting(1,0,"疑是地上霜。");
delay_10ms(10); //
dispSting(2,0,"举头望明月,");
delay_10ms(10);
dispSting(3,0,"低头思故乡!");
delay_10ms(200);
delay_10ms(200);
lcdClear(); //清屏
lcdinit_str(); //显示字符和ASICⅡ码
Lcd_wrnum(3,4,LCD_data4); //第 行第 列显示字符串(定点显示字符串)
delay_10ms(200);
delay_10ms(200);
lcdClear(); //清屏
lcdinit_str(); //显示字符和ASICⅡ码
delay_10ms(10);
lcd_mesg(LCD_data2);
delay_10ms(200);
delay_10ms(200);
Lcd12864_ClrGdRam(); //全屏显示人物图片
lcdClear();
delay_10ms(10);
lcdinit_pic();
delay_10ms(10);
disppicture(LCD_picture1);
delay_10ms(500);
delay_10ms(10);
disppicture(LCD_picture2); //显示“梦回广德”艺术字
delay_10ms(500);
Lcd12864_ClrGdRam();
lcdClear();
delay_10ms(10); //显示两幅图片
Lcd12864_anti_nor_2pic (1,0);
delay_10ms(100);
Lcd12864_anti_nor_2pic(1,1);
delay_10ms(1000);
Lcd12864_ClrGdRam(); //字符汉字一块显示
lcdClear();
lcdinit_str();
delay_10ms(1);
lcd_mesg(LCD_data3);
delay_10ms(10);
disppicture1();
delay_10ms(2000);
Lcd12864_ClrGdRam(); //显示四副图片
lcdClear();
delay_10ms(10);
Lcd12864_anti_nor_4pic(1,0);
delay_10ms(100);
Lcd12864_anti_nor_4pic(1,1);
delay_10ms(100);
Lcd12864_anti_nor_4pic(1,2);
delay_10ms(100);
Lcd12864_anti_nor_4pic(1,3);
delay_10ms(1000);
Lcd12864_ClrGdRam(); //显示六副图片
lcdClear();
delay_10ms(10);
Lcd12864_anti_nor_pic(1,0);
delay_10ms(100);
Lcd12864_anti_nor_pic(1,1);
delay_10ms(100);
Lcd12864_anti_nor_pic(1,2);
delay_10ms(100);
Lcd12864_anti_nor_pic(1,3);
delay_10ms(100);
Lcd12864_anti_nor_pic(1,4);
delay_10ms(100);
Lcd12864_anti_nor_pic(1,5);
delay_10ms(100);
delay_10ms(12200);
while(1);
} 太好了!学习一下!谢谢分享!! 太好了!学习一下!谢谢分享!! mark!留着学习! 不错 不错,谢谢 大家都说好
可惜看不懂~~~~~~~~~~~ 貌似没有画任意两点直线~
还可以加清除指定区域的函数 mark , {:lol:}学习学习 留着备用 多谢楼主,收藏学习 谢谢分享{:smile:} 嗯,蛮好的,准备去买一个12864学习一下 st7920,还用并行,浪费, 我想让12864显示温度要怎么做呢? 楼主考虑的果然是很周到啊,谢谢了 收藏了谢楼主 这还不够呢。。。 绘图模式下,什么画圆之类的
页:
[1]