#ifndef __LCD12864_H__
#define __LCD12864_H__
//ST7920 LCD指令集
//基本指令集
//以下2条指令耗时4.6ms
#define LCD12864_CLR_DISP 0x01//清屏
#define LCD12864_ADDR_RET 0x02//地址归零
//以下指令耗时76us
//输入方式设置
#define LCD12864_MODE1 0x04//模式1:读写一个字符后地址指针减1,光标左移一格,字符全部不动
#define LCD12864_MODE2 0x05//模式2:读写一个字符后地址指针减1,光标不动,字符全部右移一格
#define LCD12864_MODE3 0x06//模式3:读写一个字符后地址指针加1,光标右移一格,字符全部不动
#define LCD12864_MODE4 0x07//模式4:读写一个字符后地址指针加1,光标不动,字符全部右移一格
//显示开/关及光标设置
#define LCD12864_DISP_OFF 0x08//关显示
#define LCD12864_DIS_ON 0x0C//开显示,隐藏光标
#define LCD12864_CUS1 0x0E//光标设定模式1:光标会出现在地址计数器所指的位置,光标不闪烁
#define LCD12864_CUS2 0x0F//光标设定模式2:光标会出现在地址计数器所指的位置,光标闪烁
//滚屏选项
#define LCD12864_CUS_ST1 0x10//将光标左移1格同时地址值减1
#define LCD12864_CUS_ST2 0x14//将光标右移1格同时地址值加1
#define LCD12864_CUS_ST3 0x18//字符和光标同时左移1格
#define LCD12864_CUS_ST4 0x1C//字符和光标同时右移1格
//LCD功能设定
#define LCD12864_FUNC_ORG 0x30//基本指令集
#define LCD12864_FUNC_EXT 0x34//扩展指令集
#define SET_CG_ADDR 0x40//设定图形CGRAM地址
#define SET_DD_ADDR 0x80//设定字符DDRAM地址
//扩展指令集
#define ENT_STB 0x01//进入待命模式
#define IRAM_EN 0x02//允许输入IRAM地址
#define VADDR_EN 0x03//允许输入垂直卷动地址
#define REVS_1 0x05//一三行反白显示
#define REVS_2 0x06//二四行反白显示
#define ENT_SLP 0x08//进入睡眠模式
#define ESC_SLP 0x0C//离开睡眠模式
#define GRP_OFF 0x34//绘图显示关
#define GRP_ON 0x36//绘图显示开
#define SET_IRAM_ADDR 0x40//之前0x03:6位垂直卷动地址 0x02:4位IRAM地址
#define SET_GRP_ADDR 0x80//设定绘图CGRAM地址
extern code unsigned char pic_data_1[];
extern code unsigned char pic_data_2[];
extern code unsigned char pic_data_3[];
void init_lcd12864(void);
void lcd12864_disp_char(unsigned char x,unsigned char y,unsigned char disp_data);
void lcd12864_disp_str(unsigned char x,unsigned char y,unsigned char *p_disp_data);
void lcd12864_disp_pic(unsigned char code*p_disp_data);
void lcd12864_clc(void);
void lcd12864_clc_pic(void);
#endif
#include<reg52.h>
#include<absacc.h>
#include"lcd.h"
#include"lcd12864.h"
static void _delay_80us(void)
{
unsigned char i;
for(i = 77;i > 0;i --);
}
static void _delay_4m8s(void)
{
unsigned char i;
for(i = 60;i > 0;i --)
{
_delay_80us();
}
}
static void lcd12864_write(unsigned char lcd_rs,unsigned char lcd_data)
{
if(lcd_rs) set_lcdcr(LCD12864_DI);//写数据
else clr_lcdcr(LCD12864_DI);//写指令
clr_lcdcr(LCD12864_RW);//写指令
LCD_DATA = lcd_data;//准备好数据
set_lcdcr(LCD12864_EN);//EN高电平
clr_lcdcr(LCD12864_EN);//EN低电平
}
void init_lcd12864(void)
{
clr_lcdcr(LCD12864_EN);//EN低电平
lcd12864_write(0,LCD12864_CLR_DISP);//清屏
_delay_4m8s();
lcd12864_write(0,LCD12864_ADDR_RET);//地址归零
_delay_4m8s();
lcd12864_write(0,LCD12864_DIS_ON);//开显示
_delay_80us();
}
void lcd12864_disp_char(unsigned char x,unsigned char y,unsigned char disp_data)//???就是我这里不怎么懂啊!!!!
{
x &= 0x07;//x取值0~15
y &= 0x03;//y取值0~3
x |= ((y & 0x01) << 4);//0-->5
x |= ((y & 0x02) << 2);//1-->4///???就是这里不懂!!!
x |= SET_DD_ADDR;//写地址命令
lcd12864_write(0,LCD12864_FUNC_ORG);//基本指令集
lcd12864_write(0,x);//写入地址
_delay_80us();
lcd12864_write(1,disp_data);//写数据
_delay_80us();
}
void lcd12864_disp_str(unsigned char x,unsigned char y,unsigned char *p_disp_data)
{
lcd12864_disp_char(x,y,*p_disp_data);//设定起始地址并写入第一个字符
x = 0;
while(* ++ p_disp_data && ++ x < 40)//未到字符串末尾,一次最多写入40字符
{
lcd12864_write(1,*p_disp_data);//写数据
_delay_80us();
}
}
void lcd12864_disp_pic(unsigned char code*p_disp_data)
{
unsigned char i,j,k;
lcd12864_write(0,LCD12864_FUNC_EXT);//扩展指令集
_delay_80us();
for(i = 0;i < 2;i ++)
{
for(j = 0;j < 32;j ++)
{
lcd12864_write(0,SET_GRP_ADDR + j);//写入垂直地址
_delay_80us();
lcd12864_write(0,SET_GRP_ADDR + (i << 3));//写入水平地址
_delay_80us();
for(k = 0;k < 16;k ++)
{
lcd12864_write(1,*p_disp_data ++);//写数据
_delay_80us();
}
}
}
lcd12864_write(0,GRP_ON);//绘图显示开
}
void lcd12864_clc(void)
{
lcd12864_write(0,LCD12864_FUNC_ORG);//基本指令集
_delay_80us();
lcd12864_write(0,LCD12864_CLR_DISP);//清屏
_delay_4m8s();
}
void lcd12864_clc_pic(void)
{
unsigned char i,j,k;
lcd12864_write(0,LCD12864_FUNC_EXT);//扩展指令集
_delay_80us();
for(i = 0;i < 2;i ++)
{
for(j = 0;j < 32;j ++)
{
lcd12864_write(0,SET_GRP_ADDR + j);//写入垂直地址
_delay_80us();
lcd12864_write(0,SET_GRP_ADDR + (i << 3));//写入水平地址
_delay_80us();
for(k = 0;k < 16;k ++)
{
lcd12864_write(1,0);//写数据
_delay_80us();
}
}
}
lcd12864_write(0,GRP_ON);
_delay_80us();
} |