📄 lcdinit.c
字号:
#include "ExtDef.h"
#include "function.h"
#include "data.h"
#include "zimo.h"
uchar xdata PP _at_ 0x8001;
uchar g=0;
static uint CharHome = 0x0000;
//lcd_init(uchar txtstpd1, uchar txtstpd2, uchar txtwid, uchar grhstpd1, uchar grhstpd2, uchar grhwid, uchar cur, uchar mod, uchar sw){
// write_cmd2(txtstpd1,txtstpd2,TXT_STP); /*文本区首地址*/
// lcd_init(0x00,0x00,0x14,0x50,0x01,0x14,0x00,MOD_OR,0x0f);
// from the above three sentence,we can see that txtstpd1=0x00,txtstpd2=0x00,so initial address CharHome = 0x0000.
static uint GraphHome = 0x0150; // write_cmd2(grhstpd1,grhstpd2,GRH_STP); /*图形区首地址*/
// same as the CharHome, we can see that grhstpd1=0x50,grhstpd2=0x01,so initial address GraphHome = 0x0150.
#define HanZhi_Totals 20 //共有20个汉字
void delay(int c){
int i, j;
for(i = 0; i < c; i++)
for(j = 0; j < 1000; j++);
}
/*读状态*/
uchar read_state()
{
uchar temp;
cd = 1;
temp = PP;
return(temp);
}
/*STA0指令读写状态,STA1数据读写状态 判断函数*/
void lcd_enable(){
uchar i;
for(i = 10; i > 0; i--)
if((read_state() & 0x03) == 0x03)
break;
if(i==0)
error0=1;/*若i==0,说明错误*/
}
/*STA2数据自动读状态 判断函数*/
void atrd_enable(){
uchar i;
for(i = 10; i > 0; i--)
if((read_state() & 0x04) == 0x04)
break;
if(i==0)
error1=1;/*若i==0,说明错误*/
}
/*STA3数据自动写状态 判断函数*/
void atwr_enable(){
uchar i;
for(i = 10; i > 0; i--)
if((read_state() & 0x08) == 0x08)
break;
if(i==0)
error2=1;/*若i==0,说明错误*/
}
/*写无参数函数*/
void write_cmd0(uchar cmd){
lcd_enable();
cd=1;
PP=cmd;
}
/*写单参数函数*/
void write_cmd1(uchar data1, uchar cmd){
lcd_enable();
cd=0;
PP=data1;
lcd_enable();
cd=1;
PP=cmd;
}
/*写双参数函数*/
void write_cmd2(uchar data1, uchar data2, uchar cmd){
lcd_enable();
cd=0;
PP=data1;
lcd_enable();
cd=0;
PP=data2;
lcd_enable();
cd=1;
PP=cmd;
}
/*写数据函数*/
void write_data(uchar data0){
lcd_enable();
cd=1;
PP=data0;
}
/*读数据函数*/
uchar read_data(){
char temp;
lcd_enable();
cd = 0;
temp = PP;
return(temp); /*若返回0,可能错误*/
}
/*自动写开始*/
void auto_write(){
write_cmd0(AUT_WR);
}
/*自动读开始*/
void auto_read(){
write_cmd0(AUT_RD);
}
/*自动写结束*/
void atwr_stop(){
write_cmd0(AUT_WO);
}
/*自动读结束*/
void atrd_stop(){
write_cmd0(AUT_RO);
}
/*数据一次写函数*/
void write_one(uchar data1, char way){
write_cmd1(data1,way);
}
/*数据一次读函数*/
uchar read_one(char way){
uchar temp;
write_cmd0(way);
temp = read_data();
return(temp);
}
/*设置显示地址指针,以位为单位 */
void set_adr(uchar D1, uchar D2){
write_cmd2(D1,D2,ADR_POS);
}
/*设置光标指针 x,y从0开始*/
void set_cur(char x, char y){
write_cmd2(x,y,CUR_POS);
}
/*设置当前显示位置函数x,y 从CharHome开始表示单位为字符 */
void set_Char_xy(uchar x, uchar y){
int temp;
temp = y * LCD_CHAR + x + CharHome;
set_adr(temp&0xff,temp/0xff);
}
/*设置当前显示位置函数x,y 从GraphHome开始表示单位为图形 */
void Set_Graph_xy(uchar x, uchar y){
int temp;
temp = y * LCD_CHAR + x + GraphHome;
set_adr(temp&0xff,temp/0xff);
}
/*设置光标形状 , 形状代码从 0~7*/
void Set_Cursor_Type(uchar Type)
{
write_cmd0(CUR_SHP|Type);
}
/*当前位置清0 */
void Clr_Cur_Pos()
{
write_one(0x00,NOC_WR); // 光标不移动
}
/*液晶初始化函数(文本区首地址D1,文本区首地址D2, 文本区宽度, 图形区首地址D1, 图形区首地址D2, 图形区宽度, 光标形状, 显示方式, 显示开关)*/
void lcd_init(uchar txtstpd1, uchar txtstpd2, uchar txtwid, uchar grhstpd1, uchar grhstpd2, uchar grhwid, uchar cur, uchar mod, uchar sw){
write_cmd2(txtstpd1,txtstpd2,TXT_STP); /*文本区首地址*/
write_cmd2(txtwid,0x00,TXT_WID); /*文本区宽度*/
write_cmd2(grhstpd1,grhstpd2,GRH_STP); /*图形区首地址*/
write_cmd2(grhwid,0x00,GRH_WID); /*图形区宽度*/
write_cmd2(0x03,0x00,CGR_POS); /*CGRAM首地址*/
write_cmd0(CUR_SHP | cur); /*光标形状*/
write_cmd0(mod); /*显示方式*/
write_cmd0(DIS_SW | sw); /*显示开关*/
}
/*清屏 320 = (160/8) * (128/8) = 20 * 16 = 320*/
void cls(void){
int i;
set_Char_xy(0,0);
for(i = 0; i < 320; i++)
write_one(0x00,INC_WR);
}
/*将自定义汉字码填充到CGROM */
void wirte_cgrom(void){
int i,j;
write_cmd2(0x03,0x00,CGR_POS); /*CGRAM首地址*/
set_adr(0x00,0x1c); // CGRAM offset addr is 00001 , the lower 5 bits of 0x01,which is defined in sentence: write_cmd2(0x01,0x00,CGR_POS);
//then the user-defined CGRAM's first address is :
// 0000 0000 0000 0000
// +0000 1 // the CGRAM offset addr (00001)
// + 100 0000 0 // user-defined code begin from addr 0x80;
// + 000
// = 0000 1100 0000 0000 // the result is just 0x0c00 in: set_adr(0x00,0x0c);
/*自定义字符写入CGROM*/
for(i = 0; i < HanZhi_Totals; i++) // 一个汉字占用32个字节
for(j=0;j<32;j++)
write_one(GB_16[i].Msk[j],INC_WR);
}
char find_chinese(uchar *hz) //在自定义汉字库在查找所要显示的汉字的位置
{
uchar i=0;
while(GB_16[i].Index[0]<0x80)
{
if(*hz==GB_16[i].Index[0])
if(*(hz+1)==GB_16[i].Index[1])
return i;
i++;
if(i>20)break; // 20 totals
}
return -1; // Error !
}
//**************************************************************************
//= 函数原型: void Point(uchar x,uchar y, bit Mode)
//= 功 能: 在指定坐标位置显示一个点
//= 参 数: 坐标,显示点或清除点
//= 返 回 值:
//= 函数性质:私有函数
//= Mode 1:显示 0:清除该点
//**************************************************************************
void Point(uchar x,uchar y, bit Mode)
{
uint Address;
uchar dat;
Address=(uint)y*LCD_CHAR + (x>>3) + GraphHome; //地址转化
dat=BIT_OP+7-x%8; //产生位操作命令画点的数据
if(Mode) dat=dat|0x08;
set_adr(Address&0xff,Address/0xff);
write_cmd0(dat); // 利用位操作命令画点
}
void Char_Wr(uchar x,uchar y, uchar ch,bit Invert)
{
uchar temp;
temp = y * LCD_CHAR + x + CharHome; // x moves one pixel when add one ;
// up-left corner is (0,0) , horizontal is x, vertical is y.
// y moves eight pixel(one char) when add one.
set_adr(temp&0xff,temp/0xff);
if(ch<0x80) // Ascii character.
write_one(ch-0x20,INC_WR); // ASCII :0x30->'0', T6963 internal code :0x10->'0',so 0x30-0x10=0x20;
else
write_one(ch,INC_WR);
}
//******************************************************************************
//= 函数原型: void hanzhi(uchar x,uchar y, uchar m,uchar n)
//= 功 能: 连续写入一个或多个汉字
//= 参 数: 坐标,要显示的第一个汉字的位置,连续显示汉字的个数。
//= 返 回 值:
//= 函数性质:私有函数
//当n=1一次性写入一个字符,否则一次性写入多个字符
//*****************************************************************************
void hanzhi(uchar x,uchar y, uchar m, bit Invert)
{
uchar CGRam;
CGRam=0x80+4*m; //第m个字符
// find the corresponding address in CGROM. Because 0x00~0x7F is the address of T6963's internal Ascii code.
// so user-defined code is begin from 0x80,
Char_Wr(x,y,CGRam,1);
Char_Wr(x,y+1,CGRam+1,1);
Char_Wr(x+1,y,CGRam+2,1);
Char_Wr(x+1,y+1,CGRam+3,1);
}
//*****************************************************************************
//= 函数原型: void char_wr(uchar x,uchar y, uchar *p,uchar dataa,uchar n)
//= 功 能: 连续写入一个或多个字符
//= 参 数: 坐标,要显示的字符数组,显示的单个字符,要显示的字符个数
//= 返 回 值:
//= 函数性质:私有函数
//当n=0一次性写入一个字符,否则一次性写入多个字符
//*****************************************************************************
void Str_Write(uchar x,uchar y, uchar *str,bit Invert)
{
uchar hz[2],index;
uchar *p=str;
uchar xx,yy;
xx=x;yy=y;
while(*p!='\0')
{
if(*p>=0x80) //汉字
{
hz[0]=*p;
hz[1]=*(p+1);
index=find_chinese(hz); // fine the index
hanzhi(x,y,index,1);
p=p+2; // 占用两个字节 ,每个字节代表半个汉字的编码索引 。
x+=2;
if(x==20)
{
x=0; //写满一行,从第二行开始
y+=2;
}
}
else //英文或数字等的ascII码
{
Char_Wr(x,y,*p,1);
p+=1;
x++;
if(x==20)
{
x=0; //写满一行,从第二行开始
y+=1;
}
}
}
}
//******************************************************************************
//= 函数原型: void Show_num(uchar x1,uchar y1,uchar num)
//= 功 能: 在设定的位置显示一个数字
//= 参 数: (x1,y1)为位置,num为数字
//= 返 回 值:
//= 函数性质:公有函数
//= 注 意:以字节为单位
//*****************************************************************************
void Show_num(uchar x1,uchar y1,uchar num)
{
uchar number[10]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
set_Char_xy(x1,y1);
write_cmd1(number[num],INC_WR); //一次写入数据
}
void Init_LCD()
{
lcd_init(0x00,0x00,0x14,0x50,0x01,0x14,0x00,MOD_XOR,0x0f); ///(0x00,0x00,0x14,0x50,0x01,0x14,0x00,MOD_XOR,0x0c)
cls();
wirte_cgrom();
cls();
Str_Write(2,4,"广 东 工 业 大 学",1);
Str_Write(2,6," 嵌入式实验平台 ",1);
Str_Write(2,8," ",1);
Str_Write(2,9," 王日明 ",1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -