⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 st7920.c

📁 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 + -