英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流
标题:
一个picc编的192x64液晶显示问题
[打印本页]
作者:
winnie
时间:
2009-4-25 15:04
标题:
一个picc编的192x64液晶显示问题
我用的是pic16f877,液晶模块是LM19264D-4 (三星s6b0108),192x64的。可是当我用icd2调试时,
发现该程序总是跳不出wtcom()里面这个循环:
do{
RA2=0;
RA2=1;
}while(PORTD&0x80); //判断最高位状态,如果是1,则反复送E时续,直到LCD空闲
也就是说液晶一直忙? 按理说不应该啊,找了好久,没有发现原因,恳请大虾给予指点,感激不尽。
整个程序是这样的:
#include<pic.h>
#define Uchar unsigned char
//***********操作命令和参数定义***************
#define DISPON 0x3f //*显示on*/
#define DISPOFF 0x3e //*显示off*/
#define DISPFIRST 0xc0 //*显示起始行定义*/
#define SETX 0xb8 //*X定位设定指令(页)*/
#define SETY 0x40 //*Y定位设定指令(列)*/
#define Lcdbusy 0x80 //*LCM忙判断位*/
//**************显示分区边界位置*****************/
#define MODL 0x00 //*左区*/
#define MODM 0x40 //*左区和中区分界*/
#define MODR 0x80 //*中区和右区分界*/
#define LCMLIMIT 0xC0 //*显示区的右边界*/
//****************全局变量定义*******************/
Uchar col,row,cbyte; //*列x,行(页)y,输出数据 */
//*****************函数列表**********************/
void INITIAL(void); //*系统各口的输入输出状态初始化子程序*/
void Lcminit(void); //*液晶模块初始化 */
void Delay(Uchar); //*延时,入口数为Ms */
void lcdbusyL(void); //*busy判断、等待(左区) */
void lcdbusyM(void); //*busy判断、等待(中区) */
void lcdbusyR(void); //*busy判断、等待(右区) */
void Putcdot(Uchar); //*全角(汉字)输出 */
void Wrdata(Uchar); //*数据输出给LCM */
void Lcmcls(void); //*LCM全屏幕清零(填充0) */
void wtcom(void); //*公用busy等待 */
void Locatexy(void); //*光标定位 */
void WrcmdL(Uchar); //*左区命令输出 */
void WrcmdM(Uchar); //*中区命令输出 */
void WrcmdR(Uchar); //*右区命令输出 */
//******************数组列表*********************/
Uchar Hzk[]; //*自用汉字点阵码表 */
//********************************************************/
//* 系统各口的输入输出状态初始化子程序 */
//********************************************************/
void INITIAL(void)
{
ADCON1=0x87; //设置PORTA口和PORTE口为数字I/O口
PORTA=0;
PORTE=0;
PORTD=0; //先清零A、E、D口,避免干扰
TRISA0=0;
TRISA1=0;
TRISA2=0;
TRISA4=0;
TRISA5=0;
TRISE=0x00; //设置液晶的控制脚为输出
TRISD=0xff; //D口输入
RA5=1; // RST=1,使normal running
RE2=1; //LCD_BLA=1,点亮背景灯
}
//液晶屏初始化
void Lcminit(void)
{
cbyte = DISPOFF; //*关闭显示屏(注:DISPOFF=0x3e) */
WrcmdL(cbyte); //*命令输出到左区控制口*/
WrcmdM(cbyte);
WrcmdR(cbyte);
cbyte = DISPON; //*打开显示屏(注:DISPOFF=0x3f) */
WrcmdL(cbyte); //*命令输出到左区控制口*/
WrcmdM(cbyte);
WrcmdR(cbyte);
cbyte = DISPFIRST; //*定义显示起始行为零(注:DISPFIRST=0xc0) */
WrcmdL(cbyte); //*命令输出到左区控制口*/
WrcmdM(cbyte);
WrcmdR(cbyte);
Lcmcls();
col=0; //*清屏 */
row=0;
Locatexy();
}
//********************************/
//* 延时子程序 */
//********************************/
void Delay(Uchar MS)
{
Uchar us,usn;
while(MS!=0)
{ usn = 4;
while(usn!=0)
{
us=0xf0;
while (us!=0){us--;};
usn--;
}
MS--;
}
}
//********************************/
//* 命令输出到左区控制口 */
//********************************/
void WrcmdL(Uchar X)
{
lcdbusyL(); //*确定分区,返回时保留分区状态不变*/
TRISD=0x00; //D口为输出
RA0= 0; //* LCD_RS=0,为命令操作*/
RA1 = 0; //*LCD_WR=0,为写输出 */
RA2 = 1;
PORTD = X; //*数据输出到数据口 */
asm("nop") ;
RA2 = 0; //*E:1->0,写入到LCM*/
TRISD=0xff; //写完数据,立即把IO口设定成高阻,提高可靠性。
}
//********************************/
//* 命令输出到中区控制口 */
//********************************/
void WrcmdM(Uchar X)
{
lcdbusyM(); //*确定分区,返回时保留分区状态不变*/
TRISD=0x00; //D口为输出
RA0= 0; //* LCD_RS=0,为命令操作*/
RA1 = 0; //*LCD_WR=0,为写输出 */
RA2 = 1;
PORTD = X; //*数据输出到数据口 */
asm("nop");
RA2 = 0; //*E:1->0,写入到LCM*/
TRISD=0xff; //写完数据,立即把IO口设定成高阻,提高可靠性。
}
//********************************/
//* 命令输出到右区控制口 */
//********************************/
void WrcmdR(Uchar X)
{
lcdbusyR(); //*确定分区,返回时保留分区状态不变 */
TRISD=0x00; //D口为输出
RA0= 0; //* LCD_RS=0,为命令操作*/
RA1 = 0; //*LCD_WR=0,为写输出 */
RA2 = 1;
PORTD = X; //*数据输出到数据口 */
asm("nop") ;
RA2 = 0; //*E:1->0,写入到LCM*/
TRISD=0xff; //写完数据,立即把IO口设定成高阻,提高可靠性。
}
//********************************************************/
//* 分区操作允许等待,返回时保留分区选择状态 */
//********************************************************/
void lcdbusyL(void)
{
RA4 = 0; //*CLR CS1 */
RE0 = 1; //*SETB CS2 */
RE1 = 1; //*SETB CS3 */
wtcom(); //* waiting for enable */
}
void lcdbusyM(void)
{
RA4= 1; //*SETB CS1 */
RE0= 0; //*CLR CS2 */
RE1= 1; //*SETB CS3 */
wtcom(); //* waiting for enable */
}
void lcdbusyR(void)
{
RA4= 1; //*SETB CS1 */
RE0 = 1; //*SETB CS2 */
RE1 = 0; //*CLR CS3 */
wtcom(); //* waiting for enable */
}
//*公用busy等待 */
void wtcom(void)
{
TRISD=0xff; //D口输入
RA0 = 0; //*RS=0/
RA1= 1; //*WR=1*/
do{
RA2=0;
RA2=1;
}while(PORTD&0x80); //判断最高位状态,如果是1,则反复送E时续,直到LCD空闲
RA2= 0; //及时拉低E,使DB口处于高阻状态,提高可靠性
}
//****************************************/
//* 清屏,全屏幕清零 */
//****************************************/
void Lcmcls( void )
{
for(row=0;row<8;row++)
for(col=0;col<LCMLIMIT;col++) Wrdata(0);
}
//****************************************/
//* 数据写输出 */
//****************************************/
void Wrdata(Uchar X)
{
Locatexy(); //*坐标定位,返回时保留分区状态不变*/
wtcom();
TRISD=0x00;
RA0 = 1; //*数据输出*/
RA1= 0; //*写输出 */
RA2= 1;
PORTD = X; //*数据输出到数据口 */
asm("nop") ;
RA2 = 0;
}
//********************************************************/
//*根据设定的坐标数据,定位LCM上的下一个操作单元位置 */
//********************************************************/
void Locatexy(void)
{
unsigned char x,y;
switch (col&0xc0) //* col.and.0xC0 */
{ //*条件分支执行 */
case 0: {lcdbusyL();break;} //*左区 */
case 0x40: {lcdbusyM();break;} //*中区 */
case 0x80: {lcdbusyR();break;} //*右区 */
}
x = (col&0x3F|SETX); //* col.and.0x3f.or.setx */
y = (row&0x07|SETY); //* row.and.0x07.or.sety */
wtcom(); //* waiting for enable */
TRISD=0x00;
RA0= 0; //*CLR DI */
RA1= 0; //*CLR RW */
RA2= 1;
PORTD= y; //*MOV P0,Y */
asm("nop");
RA2= 0;
wtcom(); //* waiting for enable */
TRISD=0x00;
RA0= 0; //*CLR DI */
RA1 = 0; //*CLR RW */
RA2 = 1;
PORTD = x; //*MOV P0,X */
asm("nop") ;
RA2= 0;
}
//****************************************/
//* 全角字符点阵码(汉字)数据输出 */
//****************************************/
void Putcdot(Uchar Order)
{
Uchar i,bakerx,bakery; //*共定义3个局部变量 */
int x; //*偏移量,字符量少的可以定义为UCHAR */
bakerx = col; //*暂存x,y坐标,已备下半个字符使用 */
bakery = row;
x=Order * 0x20; //*每个字符32字节 */
//*上半个字符输出,16列 */
for(i=0;i<16;i++)
{
Wrdata(Hzk[x]); //*写输出一字节 */
x++;
col++;
if (col==LCMLIMIT){ col=0;row++;} //*下一列,如果列越界换行*/
if (row>6) row=0; //*如果行越界,返回首行 */
} //*上半个字符输出结束 */
//*下半个字符输出,16列 */
col = bakerx;
row = bakery+1;
for(i=0;i<16;i++) //*下半部分*/
{
Wrdata(Hzk[x]);
x++;
col++;
if (col==LCMLIMIT){col=0;row++;row++;} //*下一列,如果列越界换行*/
if (row>7) row=1; //*如果行越界,返回首行 */
} //*下半个字符输出结束 */
row = bakery;
} //*整个字符输出结束 */
//********************************/
//* 定义中文字库 */
//********************************/
Uchar Hzk[]={
//*-- 文字: 启 --*/
0x00,0x00,0x00,0x00,0x1F,0x12,0x12,0x92,
0x52,0x24,0x24,0x3C,0x00,0x00,0x00,0x00,
0x02,0x04,0x18,0xE0,0x00,0x7E,0x44,0x44,
0x44,0x88,0x88,0xF8,0x00,0x00,0x00,0x00,
//*-- 文字: 动 --*/
0x00,0x02,0x02,0x13,0x14,0x24,0x24,0x00,
0x04,0x05,0xFE,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0x70,0x90,0x20,0xA2,0x64,0x18,
0x60,0x88,0x04,0x18,0xE0,0x00,0x00,0x00,
};
//********************************/
//* 主程序 */
//********************************/
void main()
{
INITIAL();
col=0;
row=0;
Delay(240); //*延时大约40Ms,等待外设准备好*/
Lcminit(); //*液晶模块初始化包括全屏幕清屏*/
Putcdot(1); //*第一个汉字输出*/
// while(1)
{
;
}
}
欢迎光临 英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 (http://enroobbs.com/)
Powered by Discuz! X3.2