?? lcd12864.c
字號(hào):
/***************************************************************************
12864液晶模塊(ST7920控制器) Keil C51 并行口驅(qū)動(dòng)程序
s_yqzhan@stu.edu.cn
OFourME@163.com 2007-9-29
/**************************************************************************/
#include"LCD12864.h"
// #define NOP
/* 通過(guò)define NOP 決定是否在程序中插入nop指令
** 因?yàn)長(zhǎng)CD可能對(duì)電平保持時(shí)間有一定的要求 */
/*////////////////////////////////////////////////////////////////////////*/
#ifdef NOP
#include<intrins.h>
#endif
/*////////////////////////////////////////////////////////////////////////*/
/* 初始化12864液晶模塊 */
void init_LCD(void)
{
RST = 0;
delay(10);
RST = 1;
#ifdef NOP
_nop_();
#endif
PSB = 1;/*H:8位或4位并口方式,L:串口方式*/
send_i(ext8);
send_i(bas8);
send_i(clr);
send_i(cursor_1);
send_i(texton);
}
/*////////////////////////////////////////////////////////////////////////*/
/* 等待,直到12864液晶模塊處于就緒狀態(tài) */
void chk_busy(void)
{
BF = 1; /*DI=L.RW=H,讀出忙標(biāo)志(BF)及地址記數(shù)器(AC)的狀態(tài)*/
DI = 0; /*BF標(biāo)志提供內(nèi)部工作情況.BF=1表示模塊在進(jìn)行內(nèi)部操作,*/
RW = 1; /*此時(shí)模塊不接受外部指令和數(shù)據(jù).BF=0時(shí),模塊為準(zhǔn)備狀態(tài),*/
E = 1; /*隨時(shí)可接受外部指令和數(shù)據(jù).*/
while(BF);
E = 0;
}
/*////////////////////////////////////////////////////////////////////////*/
/* 向12864液晶模塊傳輸指令 */
void send_i(cmd12864 instrution)
{
chk_busy();
DI = 0;
RW = 0;
DB = instrution;
E = 1;
#ifdef NOP
_nop_();
_nop_();
#endif
E = 0;
}
/*////////////////////////////////////////////////////////////////////////*/
/* 向12864液晶模塊傳輸數(shù)據(jù) */
void send_d(int8u dt)
{
chk_busy();
DI = 1; /* 數(shù)據(jù)(1)/指令(0) */
RW = 0; /* 讀(1)/寫(xiě)(0) */
DB = dt;/* P0口,作為數(shù)據(jù)總線(xiàn) */
E = 1;/* 使能-寫(xiě)(H->L)/讀(H) */
#ifdef NOP
_nop_();
_nop_();
#endif
E = 0;
}
/*////////////////////////////////////////////////////////////////////////*/
/* 從12864液晶模塊讀取數(shù)據(jù) */
int8u read_d()
{
int8u dt;
chk_busy();
DI = 1;
RW = 1;
E = 1;
#ifdef NOP
_nop_();
#endif
dt = DB;
E = 0;
return dt;
}
/*////////////////////////////////////////////////////////////////////////*/
/* 從12864液晶模塊讀取指令、狀態(tài) */
int8u read_i()
{
int8u dt;
chk_busy();
DI = 0;
RW = 1;
E = 1;
#ifdef NOP
_nop_();
#endif
dt = DB;
E = 0;
return dt;
}
/*////////////////////////////////////////////////////////////////////////*/
/* 設(shè)置文本輸出位置;x取值范圍:0~7;y取值范圍:0~3 */
void gotoxy(int8u x, int8u y)
{
switch(y)
{
case 0: send_i(0x80+x);break;
case 1: send_i(0x90+x);break;
case 2: send_i(0x88+x);break;
case 3: send_i(0x98+x);break;
}
}
/*////////////////////////////////////////////////////////////////////////*/
/* 設(shè)置圖形模式輸出位置;x取值范圍(byte):0~7,單位為16位/2個(gè)字節(jié),共128位;
y取值范圍(bit):0~63
*/
void setxy(int8u x, int8u y)
{
send_i(ext8);
if( y & 0xe0 ) /* y>=32 */
{
send_i(gdbas+y-32);
send_i(page1+x);
}
else
{
send_i(gdbas+y);
send_i(page0+x);
}
send_i(bas8);
}
/*////////////////////////////////////////////////////////////////////////*/
/* 屏幕閃爍 */
void flash()
{
send_i(textoff); /* 關(guān)閉顯示 */
delay(250);
send_i(texton); /* 開(kāi)顯示,關(guān)光標(biāo),不閃爍 */
delay(250);
send_i(textoff);
delay(250);
send_i(texton);
delay(250);
send_i(textoff);
delay(250);
send_i(texton);
}
/*////////////////////////////////////////////////////////////////////////*/
/* 清屏 */
void clrddram()
{
send_i(clr);
send_i(ext8);
send_i(bas8);
}
/*////////////////////////////////////////////////////////////////////////*/
/* 連續(xù)向LCD發(fā)送string指向的num個(gè)數(shù)據(jù) */
void LCD_puts(TAB* string, int8u num)
{
while(num--)
{
send_d(*string++);//向12864液晶模塊傳輸數(shù)據(jù)
}
}
/*////////////////////////////////////////////////////////////////////////*/
/* 全屏顯示圖形子程序 */
void pho_disp(BMP12864* tab)
{
int8u i, j, k, lcd_x, lcd_y;
lcd_x = 0x80;
for(i=0 ; i<2; i++)
{
for(j=0, lcd_y=0x80; j<32; j++, lcd_y++)
{
send_i(ext8);
send_i(lcd_y);
send_i(lcd_x);
send_i(bas8);
for(k=16; k; k--)
send_d(*(tab++));
}
lcd_x = 0x88;
}
send_i(grapon);
send_i(bas8);
}
/*////////////////////////////////////////////////////////////////////////*/
/* 顯示點(diǎn)陣子程序,以lcd_data填充圖形顯示空間(GDRAM) */
void lat_disp(int8u lcd_data)
{
int8u i, j, k;
int8u lcd_x, lcd_y;
lcd_x=0x80;
i=2;
do
{ j=32; lcd_y=0x80;
do
{ send_i(ext8);
send_i(lcd_y);
send_i(lcd_x);
send_i(bas8);
k=16;
do
{ send_d(lcd_data);
}while(k--);
lcd_y++;
}while(--j);
lcd_x = 0x88;
}while(--i);
send_i(grapon);
send_i(bas8);
}
/*////////////////////////////////////////////////////////////////////////*/
/* 造字功能,最多自定義4的字,word的范圍為0~3 */
void setcgram(int8u word, BMP1616* map)
{
int i;
send_i(cgbas+16*word);
for(i=0; i<32; i++)
send_d( *map++ );
}
/*////////////////////////////////////////////////////////////////////////*/
void clrgdram()
{
lat_disp(0);
}
/*//////////////////////////////////////////////////////////////////////////
原型:void putpixel(int8u x, int8u y, int8u mode);
功能:在屏幕的指定位置上畫(huà)點(diǎn)
說(shuō)明:(x,y)為屏幕上點(diǎn)的坐標(biāo),mode值含義如下:
mode=0:清除(x,y)處的點(diǎn)
1:在(x,y)處畫(huà)點(diǎn)
2:將(x,y)處的點(diǎn)的狀態(tài)取反
//////////////////////////////////////////////////////////////////////////*/
/* 本程序可能是錯(cuò)誤的,因?yàn)閞ead_d()讀取的GDRAM的內(nèi)容并不完全,
這可能是因?yàn)楸救说?2864液晶模塊故障,或是因?yàn)槠洳o(wú)此功能。
*/
void putpixel(int8u x, int8u y, int8u mode)
{
int8u i;
union
{ int16u D;
struct
{ int8u c1;
int8u c2;
}C;
}t;
int16u code an[] = {
0x7fff, 0xbfff, 0xdfff, 0xefff, 0xf7ff, 0xfbff, 0xfdff, 0xfeff,
0xff7f, 0xffbf, 0xffdf, 0xffef, 0xfff7, 0xfffb, 0xfffd, 0xfffe };
int16u code or[] = {
0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100,
0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001 };
int16u code * const xo = or;
setxy(x/16,y);
read_d();
t.C.c1 = read_d();
t.C.c2 = read_d();
i = x & 0x0f;
switch(mode)
{
case 0: t.D &= an[i]; break;
case 1: t.D |= or[i]; break;
default:t.D ^= xo[i];
}
setxy(x/16,y);
send_d(t.C.c1);
send_d(t.C.c2);
}
/*////////////////////////////////////////////////////////////////////////*/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -