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

📄 lcd.c

📁 12864lcd的程序
💻 C
字号:
//******************************	LCD.C	************************************//
//***********************  OCM12864LCD驱动   ********************************//
#include	"iom64v.h"
#include	"macros.h"
#include	"lcd.h"

void wait_ready(void)
{
	set_csa();
	clr_csb();
	DDRE &= 0x1f;	//PE.5~7输入
	DDRB &= 0xe0;	//PB.0~4输入
	set_r_w();		//读操作
	clr_d_i();		//读指令
	set_e();		//读写使能
	NOP();
	while(PINB&0x10)//读LCD状态,1为忙
	{
		;
	}
	clr_e();
}

void write_inst_left(unsigned char I)
{
//	wait_ready();
	set_e();		//读写使能
	clr_d_i();		//选择'指令'
	clr_r_w();		//写操作
	
	set_csa();		//左半屏
	clr_csb();

	if(I&0x01)PORTE |= 0x20;	//PE.5 = 1
	else PORTE &= 0xDF;			//PE.5 = 0
	if(I&0x02)PORTE |= 0x40;	//PE.6 = 1
	else PORTE &= 0xBF;			//PE.6 = 0
	if(I&0x04)PORTE |= 0x80;	//PE.7 = 1
	else PORTE &= 0x7F;			//PE.7 = 0
	if(I&0x08)PORTB |= 0x01;	//PB.0 = 1
	else PORTB &= 0xFE;			//PB.0 = 0
	if(I&0x10)PORTB |= 0x02;	//PB.1 = 1
	else PORTB &= 0xFD;			//PB.1 = 0
	if(I&0x20)PORTB |= 0x04;	//PB.2 = 1
	else PORTB &= 0xFB;			//PB.2 = 0
	if(I&0x40)PORTB |= 0x08;	//PB.3 = 1
	else PORTB &= 0xF7;			//PB.3 = 0
	if(I&0x80)PORTB |= 0x10;	//PB.4 = 1
	else PORTB &= 0xEF;			//PB.4 = 0

	DDRE |= 0xe0;	//PE.5~7输出
	DDRB |= 0x1f;	//PB.0~5输出
	NOP();
	clr_csa();
	clr_e();		//读写禁止
	
	DDRE &= 0x1f;	//PE.5~7输入
	DDRB &= 0xe0;	//PB.0~5输入	
	return;
}

void write_inst_right(unsigned char I)
{
//	wait_ready();
	set_e();		//读写使能
	clr_d_i();		//选择'指令'
	clr_r_w();		//写操作
	
	set_csb();		//右半屏
	clr_csa();

	if(I&0x01)PORTE |= 0x20;	//PE.5 = 1
	else PORTE &= 0xDF;			//PE.5 = 0
	if(I&0x02)PORTE |= 0x40;	//PE.6 = 1
	else PORTE &= 0xBF;			//PE.6 = 0
	if(I&0x04)PORTE |= 0x80;	//PE.7 = 1
	else PORTE &= 0x7F;			//PE.7 = 0
	if(I&0x08)PORTB |= 0x01;	//PB.0 = 1
	else PORTB &= 0xFE;			//PB.0 = 0
	if(I&0x10)PORTB |= 0x02;	//PB.1 = 1
	else PORTB &= 0xFD;			//PB.1 = 0
	if(I&0x20)PORTB |= 0x04;	//PB.2 = 1
	else PORTB &= 0xFB;			//PB.2 = 0
	if(I&0x40)PORTB |= 0x08;	//PB.3 = 1
	else PORTB &= 0xF7;			//PB.3 = 0
	if(I&0x80)PORTB |= 0x10;	//PB.4 = 1
	else PORTB &= 0xEF;			//PB.4 = 0

	
	DDRE |= 0xe0;	//PE.5~7输出
	DDRB |= 0x1f;	//PB.0~4输出
	NOP();
	clr_csb();
	clr_e();		//读写禁止
	
	DDRE &= 0x1f;	//PE.5~7输入
	DDRB &= 0xe0;	//PB.0~4输入	
	return;
}

void write_data_left(unsigned char D)
{
//	wait_ready();
	set_e();		//读写使能
	set_d_i();		//选择数据
	clr_r_w();		//写操作
	
	set_csa();		//左半屏
	clr_csb();
	
	if(D&0x01)PORTE |= 0x20;	//PE.5 = 1
	else PORTE &= 0xDF;			//PE.5 = 0
	if(D&0x02)PORTE |= 0x40;	//PE.6 = 1
	else PORTE &= 0xBF;			//PE.6 = 0
	if(D&0x04)PORTE |= 0x80;	//PE.7 = 1
	else PORTE &= 0x7F;			//PE.7 = 0
	if(D&0x08)PORTB |= 0x01;	//PB.0 = 1
	else PORTB &= 0xFE;			//PB.0 = 0
	if(D&0x10)PORTB |= 0x02;	//PB.1 = 1
	else PORTB &= 0xFD;			//PB.1 = 0
	if(D&0x20)PORTB |= 0x04;	//PB.2 = 1
	else PORTB &= 0xFB;			//PB.2 = 0
	if(D&0x40)PORTB |= 0x08;	//PB.3 = 1
	else PORTB &= 0xF7;			//PB.3 = 0
	if(D&0x80)PORTB |= 0x10;	//PB.4 = 1
	else PORTB &= 0xEF;			//PB.4 = 0
	
	DDRE |= 0xe0;	//PE.5~7输出
	DDRB |= 0x1f;	//PB.0~4输出
	NOP();
	clr_csa();
	clr_e();		//读写禁止
	
	DDRE &= 0x1f;	//PE.5~7输入
	DDRB &= 0xe0;	//PB.0~4输入	
	return;
}

void write_data_right(unsigned char D)
{
//	wait_ready();
	set_e();		//读写使能
	set_d_i();		//选择数据
	clr_r_w();		//写操作
	
	set_csb();		//右半屏
	clr_csa();

	if(D&0x01)PORTE |= 0x20;	//PE.5 = 1
	else PORTE &= 0xDF;			//PE.5 = 0
	if(D&0x02)PORTE |= 0x40;	//PE.6 = 1
	else PORTE &= 0xBF;			//PE.6 = 0
	if(D&0x04)PORTE |= 0x80;	//PE.7 = 1
	else PORTE &= 0x7F;			//PE.7 = 0
	if(D&0x08)PORTB |= 0x01;	//PB.0 = 1
	else PORTB &= 0xFE;			//PB.0 = 0
	if(D&0x10)PORTB |= 0x02;	//PB.1 = 1
	else PORTB &= 0xFD;			//PB.1 = 0
	if(D&0x20)PORTB |= 0x04;	//PB.2 = 1
	else PORTB &= 0xFB;			//PB.2 = 0
	if(D&0x40)PORTB |= 0x08;	//PB.3 = 1
	else PORTB &= 0xF7;			//PB.3 = 0
	if(D&0x80)PORTB |= 0x10;	//PB.4 = 1
	else PORTB &= 0xEF;			//PB.4 = 0

	DDRE |= 0xe0;	//PE.5~7输出
	DDRB |= 0x1f;	//PB.0~4输出	
	NOP();
	clr_csb();
	clr_e();		//读写禁止
	
	DDRE &= 0x1f;	//PE.5~7输入
	DDRB &= 0xe0;	//PB.0~4输入	
	return;
}

unsigned char read_data(unsigned char s)
{
	unsigned char D=0;
	
//	wait_ready();
	set_r_w();		//读操作
	set_d_i();		//选择'指令'
	
	if(s)set_csb();
	else set_csa();
	set_e();		//读写使能
	NOP();
	if(PINE&0x20) D |= 0x01;
	if(PINE&0x40) D |= 0x02;
	if(PINE&0x80) D |= 0x04;
	if(PINB&0x01) D |= 0x08;
	if(PINB&0x02) D |= 0x10;
	if(PINB&0x04) D |= 0x20;
	if(PINB&0x08) D |= 0x40;
	if(PINB&0x10) D |= 0x80;
	if(s)clr_csb();
	else clr_csa();
	clr_e();		//读写禁止
	return D;
}
//初始化
void lcd_init(void)
{
 	PORTE = 0x0C;  			  		  	//PE.2..3 = 1; PE.4..7 = 0 
	DDRE  = 0x1C;						//PE.2..4输出; PE.5..7输入
	PORTB = 0x00;						//PB.0..4 = 0;
	DDRB  = 0xE0;						//PB.0..4输入
	PORTG = 0x00;						//PG.0..1 = 0
	DDRG  = 0x03;						//PG.0..1输出
	write_inst_left(disp_off);			//关显示
	write_inst_right(disp_off);		
	
	set_line(disp_star_line);		//设置开始行为0
	set_page(page_addr_set);		//设置开始页地址为0
	set_col(col_addr_set);			//设置列地址为0
 				
	write_inst_left(disp_on);			//开显示
	write_inst_right(disp_on);
	return;
}

//清屏
void lcd_clr(void)
{
	unsigned char i,page;
 
	for (page=0;page<8;page++)
    {
    	set_page(page);					//设置当前页
 		set_col(0);						//设置当前列
 		set_line(page*8);
  		for (i=0;i<64;i++)
    	{	
			write_data_left(0x00);		//左半屏当前列数据为0
			write_data_right(0x00);		//右半屏当前列数据为0
    	}
	}
	set_line(0);
	return;
}
//设置行
void set_line(unsigned char line)
{
 	write_inst_left(disp_star_line|line);
	write_inst_right(disp_star_line|line);
}
//设置页
void set_page(unsigned char page)
{
    write_inst_left(page_addr_set|page);
    write_inst_right(page_addr_set|page);	
}

//设置列
void set_col(unsigned char col)
{
    write_inst_left(col_addr_set|col); 		
    write_inst_right(col_addr_set|col); 	
	return;
}

//画图
//横坐标x:	0~127
//宽width:	8,16
//纵坐标y:	0~7
//图形数据指针*bmp
//图形高16,分上下2页
void draw_bmp(unsigned char x,unsigned char y,unsigned char width,unsigned char *bmp)
{
	unsigned char p = 0;
	unsigned char address=0;	//显存地址(列)
	unsigned char colume = 0;	//当前列
	unsigned char screen = 0;	//0:左半屏;1:右半屏
	
	for(colume=x;colume<(x+width);colume++)
	{
		if(colume>127)return;		//溢出
		if(colume>63)
		{
			screen = 1;				//右半屏
			address = colume%64;
		}
		else address = colume;		//左半屏
		
		set_page(y);				//设置为上面页
		set_col(address);			//设置列
		
		if(screen)write_data_right(bmp[p]);	//右半屏显示
		else write_data_left(bmp[p]); 		//左半屏显示
		
		set_page(y+1);				//设置为下面页
		set_col(address);			//显示列
		
		if(screen)write_data_right(bmp[p+width]);     
		else write_data_left(bmp[p+width]);       

        p++;
    }
	return;
}

//显示一个字符(8X16)
void disp_one_char(unsigned char x,unsigned char y,const unsigned char *char_data,unsigned char mode)
{
	unsigned char i;
	unsigned char dot_buffer[32];
	for(i=0;i<16;i++)               
	{   
		if(mode)dot_buffer[i]=~char_data[i];	//反白显示
	    else    dot_buffer[i]= char_data[i]; 	//正常显示
	}  
	draw_bmp(x,y,8,dot_buffer);
	return;
}

//显示一个汉字(8X32)
void disp_one_chinese(unsigned char x,unsigned char y,const unsigned char *chinese_data,unsigned char mode)
{
	unsigned char i;
	unsigned char dot_buffer[32];
	for(i=0;i<32;i++)               
	{   
		if(mode)dot_buffer[i]=~chinese_data[i];	//反白显示
	    else    dot_buffer[i]= chinese_data[i]; //正常显示
	}  
	draw_bmp(x,y,16,dot_buffer);
	return;
}

//画点(在液晶屏上任意一点)
//横坐标x0:0~127
//纵坐标y0:0~63
void draw_point(unsigned char x0,unsigned char y0)
{
	unsigned char c,point_data;
	unsigned char x,y,page,colume,screen;
	
	if(x0>127)return;		//溢出
	if(x0<64)				//左半屏...列
	{
		colume = x0;
		screen = 0;
	}
	else					//右半屏
	{
		colume = x0%64;
		screen = 1;
	}
	page = y0/8;			//页
	c = y0%8;
	
	set_page(page);
	set_col(colume);
	
	read_data(screen);
	set_page(page);
	set_col(colume);
	point_data = read_data(screen);
	point_data ^= (1<<c);
	set_page(page);
	set_col(colume);
	if(screen)write_data_right(point_data);
	else write_data_left(point_data);
	return;
}
	
//画线
//横坐标x1,x2:0~127	
//纵坐标y1,y2:0~63
void draw_line(unsigned char x1,unsigned y1,unsigned char x2,unsigned char y2)
{
	unsigned char i;
	signed char incx,incy;
	signed char xerr=0,yerr=0;
	signed char delta_x,delta_y,distance;
	
	delta_x = x2-x1;			//x方向的长度
	delta_y = y2-y1;			//y方向的长度
	
	if(delta_x>0)incx = 1;		//x方向增加量1
	else if(delta_x==0)incx = 0;//x方向增加量0(即垂直)
	else
	{
		incx = -1;				//x方向增加量-1
		delta_x = -delta_x;
	}
	
	if(delta_y>0)incy = 1;		//y方向增加量1
	else if(delta_y==0)incy = 0;//y方向增加量0(即垂直)
	else
	{
		incy = -1;				//y方向增加量-1
		delta_y = -delta_y;
	}
	
	if(delta_x>delta_y)distance = delta_x;//画线范围
	else distance = delta_y;
	
	for(i=0;i<=distance+1;i++)
	{
		draw_point(x1,y1);
		xerr += delta_x;
		yerr += delta_y;
		if(xerr>=distance)
		{
			xerr -= distance;
			x1 += incx;
		}
		if(yerr>=distance)
		{
			yerr -= distance;
			y1 +=incy;
		}
	}
	return;
}

//画圆
//圆心横坐标x0:1~126
//圆心纵坐标y0: 1~62
//半径r:		1~32
void draw_circle(unsigned char x0,unsigned char y0,unsigned char r)
{
	unsigned char x,y;			//
	unsigned int xx,rr,xt,yt,rs;//

	yt = r;
	rr = r*r+1;
	rs = yt*7/10;				//画1/8圆弧, rs=0.707r
	for(xt=0;xt<=rs;xt++)
	{
		xx = xt*xt;
		while((yt*yt)>(rr-xx))yt--;
		x = x0+xt;				//第一象限
		y = y0-yt;
		draw_point(x,y);
		x = x0-xt;				//第二象限
		draw_point(x,y);
		y = y0+yt;				//第三象限
		draw_point(x,y);
		x = x0+xt;				//第四象限
		draw_point(x,y);
		
		x = x0+yt;				//第一象限
		y = y0-xt;
		draw_point(x,y);
		x = x0-yt;				//第二象限
		draw_point(x,y);
		y = y0+xt;				//第三象限
		draw_point(x,y);
		x = x0+yt;				//第四象限
		draw_point(x,y);
	}
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -