功勋会员
WJ
- 积分
- 6304
- 威望
- 1456
- 贡献
- 4674
- 兑换币
- 17
- 注册时间
- 2008-4-6
- 在线时间
- 87 小时
|
1 看硬件管脚是否联错了。
2 测试一下下时序,主要是延时要求。
这个驱动网上很多,改改就成。
// LCD上文本区 64 字节 LCD上图形区 1024 字节
// ┌──────────────┐ ┌──────────────┐
// │ 第一行 │ │ 前半屏 │
// │地址x: 0x80 --- 0x87 │ │ 64 * 128 点阵 = 512 Byte │
// ├──────────────┤ │每 32*128 点阵 为一行,共2行│
// │ 第二行 │ │行0: 首址y=0x80 前半屏首 │
// │地址x 0x90 --- 0x97 │ │行1: 首址y=0x90 址x = 0x80│
// ├──────────────┤ ├──────────────┤
// │ 第三行 │ │ 后半屏 │
// │地址x 0x88 --- 0x8f │ │ 64 * 128 点阵 = 512 Byte │
// ├──────────────┤ │每 32*128 点阵 为一行,共2行│
// │ 第四行 │ │行2: 首址y=0x80 后半屏首 │
// │地址x 0x90 --- 0x9f │ │行3: 首址y=0x90 址x = 0x88│
// └──────────────┘ └──────────────┘
// 文本区4行,每行可显示8个汉字,或16个字符。文本区的
// 座标位,即文本区的地址x值,如上图所示,或数组TextLine[][8]。
// 图形区分为上下两部份,即上半屏和下半屏。每个半屏的点阵 = 64 * 128,即
// 64行,每行16字节128个bit位。y 座标上下半屏相同都是: 0x80 - 0x9f 共32行。
// 每行行首的x 座标上半屏是 0x80,而下半屏是 0x88。
// 行内的16字节是地址是由操作自动+1,末位加到15,再加又回 0。
下面是底层驱动程序:
// ㈠ ************* 端口设置 *************
extern void _nop_ (void);
#define LCD ((unsigned char volatile xdata *) 0xf010) // 液晶显示器首地址
#define RS 0 // 寄存器选择选择口,=0 指令寄存器,=1 数据寄存器
#define RW 1 // 读写操作控制口,=0 写操作,=1 读操作
#define RST 2 // 液晶显示器复位口,低电平有效
#define BK 3 // 液晶显示器背光口
#define COMM 6 // 液晶显示器命令口
#define DATA 6 // 液晶显示器数据口
#define EN 7 // 液晶显示器使能口,高电平有效
#define STATE 8 // 液晶显示器状态口
// ㈡ ************* 底层驱动程序 *************
/****************************************
测试液晶是否忙 LCD_Busy()
****************************************/
void LCD_Busy(void)
{
LCD[DATA]=0xff; // 数据口先送 0xff
LCD[RS]=0; // 指令
LCD[RW]=1; // 读出忙标志(BF)及地址记数器(AC)
LCD[EN]=1; // 使能
while(LCD[STATE] & 0x80); // 最高位为1则忙,再读
LCD[EN]=0;
}
/***************************************
送指令或数据 LCD_cmd()
参数 md 类别(0/1),md=0 命令 md="1" 数据
dt 命令或数据的值
****************************************/
void LCD_cmd(char md,char dt)
{
LCD_Busy(); // 测试液晶是否忙
if(md) LCD[RS]=1; // 判断是数据还是命令
else LCD[RS]=0;
LCD[RW]=0; // 写
LCD[COMM]=dt; // 送数据或命令
LCD[EN]=1; // 使能
_nop_();
//_nop_();
LCD[EN]=0;
}
/****************************************
从液晶读数据 LCD_Read()
读一字节数据,需读2次。第一次读为空操作
****************************************/
char LCD_Read(void)
{ LCD_Busy(); // 测试液晶是否忙
LCD[RS]=1; // 数据
LCD[RW]=1; // 读
LCD[EN]=1; // 使能
_nop_();
return LCD[DATA]; // 读数据
//LCD[EN]=0;
}
/****************************************
液晶背光控制 LCD_Back(md)
md=0xff 点亮背光,md=0 关背光
****************************************/
void LCD_Back(unsigned char md)
{
LCD[BK] = md;
}
// ㈢ ************* 显示基本函数 *************
code const unsigned char TextLine[][8]= // TS7920 128x64 文本显示行列地址
{{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}}; // 第四行
/****************************************
液晶显示器初始化 LCD_init()
****************************************/
void LCD_init(void)
{
LCD[BK]=0;
LCD[RST]=1;
LCD_cmd(0,0x34); // 关闭图形显示 *
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x01); // 清屏,地址指针指向00H
LCD_cmd(0,0x06); // 光标的移动方向
LCD_cmd(0,0x0c); // 开显示,关光标
ClearGraph(); // 清图形区
ClearText(4); // 清文本区
}
/****************************************
清图形区 ClearGraph()
****************************************/
void ClearGraph(void)
{ xdata char i,j,k,x;
x=0x80; // 图型上半区开始位置
for(k=0;k<2;k++)
{ for(j=0;j<32;j++)
{ LCD_cmd(0,0x34); // 扩充指令,关图形显示
LCD_cmd(0,0x80+j); // 确定垂值座标
LCD_cmd(0,x); // 确定水平座标
LCD_cmd(0,0x30); // 基本指令动作
for(i=0;i<16;i++)
LCD_cmd(1,0); // 送数据 0
}
x="0x88"; // 图型下半区开始位置
}
LCD_cmd(0,0x36); // 扩充指令集动作且开图形显示
}
/****************************************
清文本区 ClearText(row)
参数 row 行号(0-4),若 row="4" 清屏
****************************************/
void ClearText(char row)
{ xdata char k,i=0;
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x0c); // 开显示,关光标
if (row>4) return;
if (row==4)
for (k=0;k<4;k++,i=0) // 清四行
{LCD_cmd(0,TextLine[k][0]); // 送出行地址
while (i++<16) LCD_cmd(1,0x20);
}
else
{ LCD_cmd(0,TextLine[row][0]); // 送出行地址
while (i++<16) LCD_cmd(1,0x20);
}
}
/****************************************
显示一屏汉字或字符 DisplayScreen(*p)
参数: *p 待显字符串指针
说明: 数组第2行和第3行显示时将被对调
****************************************/
void DisplayScreen(char *p)
{ xdata char k,i=0;
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x0c); // 开显示,关光标
for (k=0;k<4;k++,i=0) {
LCD_cmd(0,TextLine[k][0]); // 送出行地址
while (*p && i++<16)
LCD_cmd(1,*p++);
if (!(*p)) break;
}
}
/****************************************
显示一行字符串 DisplayRow(row,*p)
参数 row 行号(0-3)
*p 待显字符串指针
****************************************/
void DisplayRow(char row,char *P)
{ char i="0";
if (row>3) return;
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x0c); // 开显示,关光标 *
LCD_cmd(0,TextLine[row][0]); // 送出行地址
while (*P && i++<16)
LCD_cmd(1,*P++);
} |
|