📄 lcd.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 + -