|
屏驱动
- //lcd12864(ks0108) 无字库
- //128*64点阵液晶显示模块,汉字16*16点阵,字符8*16点阵
- #include <reg52.h>
- #include <intrins.h> //_nop_()
- #include "delay.h" //延时
- #define uchar unsigned char
- #define uint unsigned int
- #define port P2 //DB0~DB7数据口
- sbit lcd_rs=P0^4; //命令数据选择
- sbit lcd_rw=P0^3; //读/写选择
- sbit lcd_en=P0^2; //使能
- sbit lcd_cs1=P0^1; //左半屏选择,1有效
- sbit lcd_cs2=P0^5; //右半屏选择,1有效
- sbit lcd_rst=P0^0; //复位
- sbit busy=P2^7; //忙信号
- //检查是否忙
- void check_busy (void)
- {
- lcd_rs=0; //0命令 1数据
- lcd_rw=1; //0写 1读
- port=0x00; //
- lcd_en=1; //使能,读出信号
- while(port & 0x80); //最高位DB7==1 为busy
- lcd_en=0;
- }
- //写命令
- void lcd_write_cmd(uchar cmd)
- {
- check_busy ();
- lcd_rs=0; //0命令 1数据
- lcd_rw=0; //0写 1读
- port=cmd; //将命令写入P2口
- _nop_(); //空操作,做短暂的延时
- lcd_en=1; //en先置高电平
- _nop_(); //空操作,做短暂的延时
- lcd_en=0; //en的下降沿,数据写入
- }
- //写数据
- void lcd_write_dat(uchar dat)
- {
- lcd_rs=1; //0命令 1数据
- lcd_rw=0; //0写 1读
- port=dat; //将数据写入P2口
- _nop_(); //空操作,做短暂的延时
- lcd_en=1; //en先置高电平
- _nop_(); //空操作,做短暂的延时
- lcd_en=0; //en的下降沿,数据写入
- }
- //初始化
- void lcd_init()
- {
- lcd_rst=0; //液晶复位
- delay_ms(2); //适当延时
- lcd_rst=1; //复位结束
- lcd_cs1=1; //左半屏选通
- lcd_cs2=1; //右半屏选通
- delay_ms(2); //适当延时
- lcd_write_cmd(0x3f); //0011 1111 开显示
- //0x3e 关显示
- //0xb8 页地址 X地址 1页8行 共64行 A0-A2 0-7共8页
- //0x40 列地址 Y地址 1列一个点 A0-A5 0-63 共128点
- //0xc0 起始行
-
- }
-
- //清屏
- void lcd_clear(uchar m)
- {
- uchar j,k;
- lcd_cs1=1; //左半屏选通
- lcd_cs2=1; //右半屏选通
- lcd_write_cmd(0x40+0); //将起始列地址写入
- for(k=0;k<8;k++)
- {
- lcd_write_cmd(0xb8+k); //将起始行地址写入
- for(j=0;j<64;j++) //每行的64列都写0,因为选了左右两屏,
- {
- lcd_write_dat(m); //64列同时写0
- }
- }
- }
- //设定位置座标
- void lcd_set_pos(uchar page,column) //页 列
- {
- page = page & 0x07; //按位与0000 0111限定范围,行不能超过8
- column = column & 0x7f; //按位与0111 1111限定范围,列不能超过128
-
- if(column<64) //如果列小于64
- {
- lcd_cs1=1; //开左半屏
- lcd_cs2=0; //关右半屏
- lcd_write_cmd(0x40+column); //将列地址写入
- }
- else
- {
- lcd_cs1=0; //关左半屏
- lcd_cs2=1; //开右半屏
- column &= 0x3f; //按位与0011 1111 64变0 127变63
- lcd_write_cmd(0x40+column); //将列地址写入
- }
- lcd_write_cmd(0xb8+page); //将起始行地址写入
-
- }
- //写入英文8*16点阵
- void lcd_write_en(uchar page,column,num,uchar *p)
- {
- uchar col=0; //列
- lcd_set_pos(page,column); //设定起始地址
- for(col=0;col<8;col++) //循环写8列
- lcd_write_dat(p[num*16+col]); //先写上半个字,8个字节
- lcd_set_pos(page+1,column); //设定起始地址,将行地址加1,写下行
- for(col=0;col<8;col++) //循环写8列
- lcd_write_dat(p[num*16+8+col]); //再写下半个字,8个字节
- }
- //写入英文16*32点阵
- void lcd_write_num(uchar page,column,num,uchar *p)
- {
- uchar col;
- uchar k;
- uchar n=0; //列 页 字符数
- for(k=0;k<4;k++) //循环写入4页
- {
- lcd_set_pos(page+k,column); //设定起始地址
- for(col=0;col<16;col++) //循环写16列
- {
- lcd_write_dat(p[num*64+n+col]);
- } //先写上半个字
- n=n+16;
- }
- }
- //写入中文16*16点阵
- void lcd_write_cn(uchar page,column,num,uchar *p)
- {
- uchar col=0; //列
- lcd_set_pos(page,column); //设定起始地址
- for(col=0;col<16;col++)
- lcd_write_dat(p[num*32+col]); //先写上半个字,共16个字节
- lcd_set_pos(page+1,column); //设定起始地址,行地址加1,写下行
- for(col=0;col<16;col++)
- lcd_write_dat(p[num*32+16+col]); //再写下半个字,共16个字节
- }
- //写入图片
- void lcd_write_pic(uchar *pic)
- {
- uchar i,j;
- for(i=0;i<8;i++)
- {
- lcd_cs1=1; //开左半屏
- lcd_cs2=0; //关右半屏
- lcd_write_cmd(0xb8+i); //将列地址写入
- for(j=0;j<64;j++)
- lcd_write_dat(pic[i*128+j]);
- lcd_cs1=0; //开左半屏
- lcd_cs2=1; //关右半屏
- lcd_write_cmd(0xb8+i); //将列地址写入
- for(j=64;j<128;j++)
- lcd_write_dat(pic[i*128+j]);
- }
- }
复制代码 |
|