📄 st7920.c
字号:
/*******************************************************************
*这里是ST7920芯片驱动的液晶的核心驱动程序,提供的接口函数如下
********************************************************************/
unsigned char code img[128*64];
unsigned char code chn[8*4];
void delay(int t);
void delay2(int t)
void wr_command(unsigned char t);
void wr_data(unsigned char t);
void LCM_Init(void);
void chn_disp_full(unsigned code *chn);
void chn_disp_half(unsigned code *chn);
void img_disp_full(unsigned code *img);
void TextClear(void);
void chk_busy(void);
#define DEBUG 1
#ifdef DEBUG
RS = P2^1; //H=data; L=command;
RW = P2^2; //H=read; L=write;
E = P2^4; //input enable;
PSB= P2^5; //H=并口; L=串口;
RST= P2^3; //Reset Signal 低电平有效
//P0 对应了DB0-DB7
Busy=P0^7
#endif
void LCM_Init(void)
{
//关于液晶的各个管脚的定义应该在这里
Delay(400);
RESET = 1; //????
PSB = 1; //并行工作方式 psb置高电平
wr_command(0x30);//8BIT,基本指令控制
delay(10);
wr_command(0x0c);//开显式,关游标
delay(10);
wr_command(0x01);//清除显式,讲AC设置为0x00
delay(5);
wr_command(0x06);//光标的移动方向
}
void delay(int t)
{
int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<10;j++)
/*do nothing*/;
}
}
void delay2(int t)
{
int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<5;j++)
/*do nothing*/;
}
}
void wr_command(unsigned char t)
{
delay(1);
RS = 0;RW = 0; //写指令到指令暂存器
P0 = t; //传输命令
E = 0;
E = 1; //这里使用上升沿来提供命令或者数据的写入操作
E = 0; //如果保持高电平,将进行命令或者数据的读取操作,
//所以平时记得保持电平为低
}
void wr_data(unsigned char t)
{
delay(1);
RS = 1;RW = 0; //写数据到数据暂存器
P0 = t;
E = 0;
E = 1;
E = 0;
}
/*显式中文,这里是将表中的16*4个字符全部显式*/
void chn_disp_full(unsigned code *chn)
{
unsigned i,j;
chk_busy();
wr_command(0x30);
wr_command(0x80); //0x80+AC地址,这里指向首地址
for(j=0;j<4;j++) //竖行,共4行
{
for(i=0;i<16;i++) //横排16个字符
wr_data(chn[j*16+i]);
}
}
/*显式中文,只显式上半屏幕16*2汉字*/
void chn_disp_half(unsigned code *chn)
{
chk_busy();
unsigned i,j;
wr_command(0x30);
//上半屏幕第一行
wr_command(0x80);
for(i=0;i<16;i++)
wr_data(chn[i]);
//上半屏幕第二行
wr_command(0x90); //注意,这里涵盖了AC地址了
for(i=0;i<16;i++)
wr_data(chn[16+i]);
}
/****************************************************
*显式图像 128(16*8)*64的图像大小,屏幕上安排的地址是:
*但是下面的地址的设定实在是让人恼火
*
*0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87
*0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97
*0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f
*0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f
****************************************************/
void img_disp_full(unsigned code *img)
{
unsigned i,j;
chk_busy();
wr_command(0x34); //关闭绘图显式
//图像的上半部份
for(j=0;j<32;j++)
{
for(i=0;i<8;i++)
{
//使用扩充指令
wr_command(0x34);
wr_command(0x80+j); //先设置垂直位置,共A6-A0 7比特
wr_command(0x80+i); //后设置水平位置,共A3-A0 4比特
//使用基本指令
wr_command(0x30);
//这里是以字(2字节)为单位写入的,共8次循环,刚好是16个字节一行的像素
wr_data(img[j*16+i*2]);
wr_data(img[j*16+i*2+1]);
}
}
//图像的下半部份
for(j=32;j<64;j++)
{
for(i=0;i<8;i++)
{
wr_command(0x34);
wr_command(0x80+j-32);
wr_command(0x88+i);
wr_command(0x30);
wr_data(img[j*16+i*2]);
wr_data(img[j*16+i*2+1]);
}
}
wr_command(0x36); //打开绘图显式
}
/*清空显式字符,实际是将全部的显式内容设置为空字符*/
void TextClear(void)
{
int i,j;
chk_busy();
wr_command(0x30);
delay(10);
wr_command(0x80); //写资料到RAM
delay(10);
for(i=0;i<4;i++) //将64个字符全部清空
{
for(j=0;j<16;j++)
wr_data(0x20); //空白字符
}
}
void chk_busy(void)
{
P0 = 0xff;
RS = 0;RW = 1; //读忙寄存器值BF
E = 1;
while(Busy==1)
/*waiting ...*/;
E = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -