📄 lcd12864_driver.c
字号:
#include <c8051f020.h>
#include <math.h>
#include "delay.h"
#include "LCD12864_Driver.h"
#define uchar unsigned char
#define uint unsigned int
//初始化-----------------------------
void Lcd_Ini(void)
{
RST=1;
Delay(100,100);
RST=0; //复位
Delay(100,100);
RST=1;
Delay(100,100);
WR=1;RD=1;CD=1;
// Clr_Char_Area() ;
//Clr_Graph_Area();
Send_cmd1(0x80); //设置显示方式: CGROM方式 文本与图形或显示
Send_cmd3(0x00,0x00,0x21); //光标位置
Send_cmd1(0xa7); //设置光标形状 cursor size 8x8
Send_cmd3(0x00,0x00,0x40); //文本区首地址设置
Send_cmd3(0x10,0x00,0x41); //字符宽度:16*16,可设置
Send_cmd3(0x00,0x04,0x42); //图形区首址设置
Send_cmd3(0x10,0x00,0x43); //宽度
Send_cmd1(0x94); //设置显示开关:启用文本显示 禁止图形显示
// Send_cmd1(0x98); //设置显示开关:禁止文本显示启用图形显示 /****显示汉字和动画时选用****/
Send_cmd1(0x80); //设置显示开关:启用文本显示 启用图形显示
//Send_cmd1(0x90); //设置显示开关:禁止文本显示 禁止图形显示
}
void ShowChar(unsigned char lin,unsigned char column, uchar str[])
{
unsigned int i; //定义字符显示个数变量
unsigned int StartAddr; //起始地址变量
uchar temp;
StartAddr=lin*16+column; //定位起始行
Send_cmd3((unsigned char)StartAddr,0x00, 0x24); //set address
Send_cmd1(0xb0);//自动写方式
for(i=0;str[i]!=0;i++)
{
temp = str[i] - 0x20;
Send_data(temp); //写字符
}
Send_cmd1(0xb2);//退出自动写
}
void ShowHZ(unsigned char lin,unsigned char column,uchar HZTable[],uchar HZ_num )
{ unsigned char i,j; //i为汉字点阵字节数变量,j为显示汉字个数变量
unsigned int StartAddr; //定义起始地址变量
unsigned int Abos_Addr;
unsigned char tcolumn; //每个汉字显示的开始列地址
// StartAddr = 0x0400; // Send_cmd3(0x00,0x04,0x40); 与文本区首地址设置保持一致
for(j=0;j<HZ_num;j++)
{ tcolumn=column+j*2;
StartAddr=lin*16 + tcolumn; //定位起始行
for(i=0;i<32;i++) //一个汉字共32字节,一次显示两字节,共显示16次
{ Abos_Addr=StartAddr + 0x0400;
Send_cmd3((unsigned char)(Abos_Addr),(unsigned char)(Abos_Addr>>8), 0x24);
Send_cmd2( HZTable[j*32+i], 0xc0); //左半部 地址加一
Send_cmd2( HZTable[j*32+i+1], 0xc4); //右半部 字模地址加一
i++;
StartAddr=StartAddr + 16; //下一字节先地址
}
}
}
void ShowPicture(unsigned char Startline,unsigned char Startcolumn,unsigned char LineWidth,unsigned char ColumnWidth,unsigned char code * address,unsigned int StartAddr)
{ unsigned char i,j; //i为列宽变量,j为行宽变量
unsigned int StartAddr0;//定义起始地址变量
// StartAddr = 0x0400; // Send_cmd3(0x00,0x04,0x40); 与文本区首地址设置保持一致
StartAddr0=StartAddr + Startline*16 + Startcolumn; //定位起始位置
for(i=0;i<ColumnWidth;i++) //汉字为16*16点阵,ColumnWidth为16,以像数计算
{ Send_cmd3( (unsigned char)(StartAddr0), (unsigned char)(StartAddr0>>8),0x24); //set address
for(j=0;j<LineWidth;j++) //LineWidth为2,以字节计算
{ //Send_cmd2( *(address+i*LineWidth+ j ), 0xc0); //写数据,地址增一
Send_cmd2( *(address+i*LineWidth+ j ), 0xc0); //写数据,地址增一
}
StartAddr0=StartAddr0 + 16; //图片下一个字节的地址
}
}
//清理字符区-----------------------------------
void Clr_Char_Area(void)
{
uint i;
Send_cmd3(0x00,0x00,0x24);
Send_cmd1(0xb0); //自动写设置
for (i=0;i<128;i++)
{
// Autowr_check();
Send_data(0x00);
}
Send_cmd1(0xb3); //自动读/写结束
Send_cmd3(0x00,0x00,0x24);
}
//=========================================
//清理图形区
void Clr_Graph_Area(void)
{
uint i;
Send_cmd3(0x00,0x04,0x24); //地址指针位置
Send_cmd1(0xb0); //自动读设置
for (i=0;i<1024;i++)
{
// Autowr_check();
Send_data(0x00);
}
Send_cmd1(0xb3); //自动读/写结束
Send_cmd3(0x00,0x04,0x24);
}
void Locat_Dot(uchar x_loc, uchar y_loc)
{
uint StartAddr;//定义起始地址变量 volatile
uchar dot_data,ori_data, move;
uchar Line,Column;
y_loc = 63 - y_loc ;
Column = x_loc/8;
Line = y_loc;
StartAddr = 0x0400; // Send_cmd3(0x00,0x04,0x40); 与文本区首地址设置保持一致
StartAddr =StartAddr + Line*16 + Column;
Send_cmd3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8),0x24);
Send_cmd1(0xc5); // 数据读,地址不变
Delay(5,4); // 本来读端口数据时,要把端口配为漏极,且向端口写“1”Data_Port=0XFF; 但在函数Send_cmd(0xc5);里面已经包括了该句
CD=0;CE=0;RD=0;WR=1;
ori_data=Data_Port;
Delay(10,5);
CD=1;RD=1;CE=1;
move = x_loc%8; dot_data = 0x80>>move;
dot_data = dot_data | ori_data;
Send_cmd2(dot_data, 0xc4); // 地址不变
}
void Line(uchar x1,uchar y1,uchar x2,uchar y2)
{ char i;
//y1 = 64 - y1 ;
//y2 = 64 - y2 ;
char x,y;
float y_add;
x=x2-x1;
y=y2-y1;
if(x==0)
{
if(y>0)
{
for(i=0;i<y;i++)
{
Locat_Dot(x1,y1+i);
}
}
else if(y==0)
Locat_Dot(x1,y1);
else
{
for(i=y;i<0;i++)
{
Locat_Dot(x1,y1+i);
}
}
}
else
y_add = y*1.000/x;
if(x>0)
{
if(y_add <=1&&y_add>=-1)
{
for(i=0;i<x;i++)
{
y=y1+y_add*i;
Locat_Dot(x1+i,y);
}
}
else
{
if(y>0)
{
for(i=0;i<y;i++)
{
x=x1+i/y_add;
Locat_Dot(x,y1+i);
}
}
else if(y==0)
{
for(i=0;i<x;i++)
{
Locat_Dot(x1+i,y1);
}
}
else
{
for(i=y;i<0;i++)
{
x=x1+i/y_add;
Locat_Dot(x,y1+i);
}
}
}
}
else if(x<0)
{
if(y_add <=1&&y_add>=-1)
{
for(i=x;i<0;i++)
{
y=y1+y_add*i;
Locat_Dot(x1+i,y);
}
}
else
{
if(y>0)
{
for(i=0;i<y;i++)
{
x=x1+i/y_add;
Locat_Dot(x,y1+i);
}
}
else if(y==0)
{
for(i=x;i<0;i++)
{
Locat_Dot(x1+i,y1);
}
}
else
{
for(i=y;i<0;i++)
{
x=x1+i/y_add;
Locat_Dot(x,y1+i);
}
}
}
}
}
void Circle(uchar x1,uchar y1,uchar R)
{
uchar x,y;
uint a,b;
// y1 = 64 - y1 ;
for(x=x1-R;x<=x1+R;x++)
{
for(y=0;y<=64;y++)
{ a=(abs(x-x1))*(abs(x-x1));
b=(abs(y-y1))*(abs(y-y1));
if( ((a+b)<=R*R) && ((a+b)>=(R-1)*(R-1))){
Locat_Dot(x,y); }
}
}
}
//读状态==================================
uchar Read_state()
{
uchar sta;
Data_Port=0xff;
CD=1;CE=0;RD=0;WR=1;
sta=Data_Port;
Delay(10,5);
RD=1;CE=1;RD=1;CD=1;
return(sta);
}
//发指令-----------------------------------
//2字节数据--------------------------
//
void Send_cmd2(uchar d1,uchar c)
{
Send_data(d1);
Send_cmd1(c);
}
//3字节数据--------------------------
//设置光标指针,CGRAM偏置地址,地址指针,
//显示区域设置
void Send_cmd3(uchar d1,uchar d2,uchar c)
{
Send_data(d1);
Send_data(d2);
Send_cmd1(c);
}
//发数据--------------------
void Send_data(uchar d)
{
uchar s1,D1;
D1=d;
do
{s1=Read_state();}
while((s1)&0x03!=0x03);//R_sta check;
Data_Port=D1;
CD=0; CE=0; WR=0;
Delay(10,5);
CE=1; WR=1;RD=1;CD=1;
Data_Port=0XFF;
}
void Send_cmd1(uchar c)
{
uchar s0,c1;
c1=c;
do
{s0=Read_state();}
while(((s0)&0x03)!=0x03);//r_cmd check;
Data_Port=c1;
CD=1; CE=0; WR=0;RD=1;
Delay(10,5);
CE=1;RD=1; WR=1;CD=1;
Data_Port=0XFF;
}
/*
void PORT_Init ()
{
XBR2=0X40;
P1MDOUT=0XFF;
P2MDOUT=0XFF;
P74OUT=0X00; //读端口数据时,要把端口配为漏极,且向端口写“1”Data_Port=0XFF;
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -