AVR写LCD12864,在写页地址后读状态,一直为忙,那为懂AVR的帮我解决一下呢,用的是atmel studio 6.0

AVR写LCD12864,在写页地址后读状态,一直为忙,那为懂AVR的帮我解决一下呢,用的是atmel studio 6.0,第1张

没能直接找出你程序的明显问题,但有几点可以考虑下:

void LCD_Status()中,仔细对照12864的说明书,看你口线的 *** 作逻辑,是否完全符合说明书。你写开关屏命令正确,但也并不能保证逻辑就是正确的,Y 因为你锁出去的数据是不同的,不仔细看你程序,理论上讲,对后续的程序的影响是不一样的。不同厂家的LCD *** 作,大同小异,但确实各有不同之处。

在AVR中,asm("nop");是可以用NOP();来代替的,后者比前者看起来舒服些。

你没说你的CPU连接LCD的排线的长度,此长度小于5cm时,考虑可以很少;>10cm时,需要考虑电容效应,信号会被延迟,你程序中NOP()的个数可能会不够,因为AVR的机器周期其实是可以小于us级的(看你的晶振速度了),一个NOP可能起不到作用,需要N个。

个人观点供参考,我用LCD时,根本就不去查询LCD是否繁忙,因为现在的LCD接收端口都是硬件锁存的,速度非常快,根本不会出现繁忙拥堵的情况。下面是我使用320240LCD的写命令和数据的函数,没查询,大量使用从来也不出问题:

void LcmWriteADataByte(uchar mydata)     //写数据

{

 pinLcmA00();

 LCM=mydata;

 NOP();

 pinLcmCS0();

 pinLcmWR0();

 NOP();

 pinLcmWR1();

 pinLcmCS1();

}

void LcmWriteAControlByte(uchar mycommand)    //写指令

{

 pinLcmA01();

 LCM=mycommand;

 pinLcmCS0();

 pinLcmWR0();

 NOP();

 pinLcmWR1();

 pinLcmCS1();

 pinLcmA01();

}

总结,不正常工作最可能的两个原因(不是全部原因):A逻辑不完全符合说明书;B延时不够,或某些地点漏做延时了。希望有所帮助。

你的LCM是用什么控制IC的?COB还是COG? 不清楚你驱动IC所以不能帮你看了,只要初始化没问题就行了,我给你发个常用的COB 三星0108的驱动 程序,跟 COG的7565R的程序,你参考下

// MASTER IC: S6B0108 X3 SLAVE IC: S6B0107

// VDD= 5v,Vop=100V 1/64DUTY 1/9BIAS

// PARALLEL 6800-SERIES

// 2003712 by ZHM

#include <mreg52h>

#define Uchar unsigned char

#define Uint unsigned int

unsigned char code Pic[8128];

unsigned char code image[8128];

void ComWrite(Uchar com);

void DatWrite(Uchar dat);

void Initial(void);

void Disp(Uchar dot1,Uchar dot2);

void DispBmp(void);

void DispB(void);

void block(Uchar dot1,Uchar dot2);

void delay(unsigned int d)

{

int d3;

for(;d!=0;d--)

{

for(d3=50;d3!=0;d3--)

{}

}

}

void main(void)

{

Initial();

while(1)

{

DispBmp();

Disp(0x0ff,0x0ff);

delay(3000);

Disp(0x00,0x00);

delay(3000);

Disp(0x55,0x55);

delay(3000);

Disp(0xaa,0xaa);

delay(3000);

Disp(0xff,0x00);

delay(3000);

Disp(0x00,0xff);

delay(3000);

Disp(0xaa,0x55);

delay(3000);

Disp(0x55,0xaa);

delay(3000);

block(0x00,0xff);

delay(3000);

DispB();

}

}

void block(Uchar dot1,Uchar dot2)

{

Uchar cnt,cnt2;

register Uchar cnt1;

CS1=1;CS2=0; //SELECT ALL SEG IC

for(cnt=0;cnt<4;cnt++)

{

ComWrite(0x0b8+cnt+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt2=0;cnt2<4;cnt2++)

{

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot1);}

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot2);}

}

ComWrite(0x0b8+cnt+cnt+1); //Set Page Address 0~7

ComWrite(0x40);

for(cnt2=0;cnt2<4;cnt2++)

{

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot2);}

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot1);}

}

}

CS1=0;CS2=1;

for(cnt=0;cnt<8;cnt++)

{

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt2=0;cnt2<4;cnt2++)

{

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot1);}

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot2);}

}

cnt++;

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt2=0;cnt2<4;cnt2++)

{

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot2);}

for(cnt1=8;cnt1>0;--cnt1){ DatWrite(dot1);}

}

}

delay(10);

}

void DispBmp(void)

{

Uchar cnt;

register Uchar cnt1;

for(cnt=0; cnt<8; cnt++)

{

CS1=1; CS2=0; // CS3=1;

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt1=64; cnt1>0; cnt1--) DatWrite(image[128cnt+64-cnt1]);

CS1=0; CS2=1; // CS3=1;

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt1=128; cnt1>64; cnt1--) DatWrite(image[128cnt+192-cnt1]);

/ CS1=1; CS2=1; // CS3=0;

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt1=0; cnt1<64; cnt1++) DatWrite(bmp++);

/ }

delay(5000);

Disp(0x00,0x00);

}

void DispB(void)

{

Uchar cnt;

register Uchar cnt1;

for(cnt=0; cnt<8; cnt++)

{

CS1=1; CS2=0; // CS3=1;

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt1=64; cnt1>0; cnt1--) DatWrite(Pic[128cnt+64-cnt1]);

CS1=0; CS2=1; // CS3=1;

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt1=128; cnt1>64; cnt1--) DatWrite(Pic[128cnt+192-cnt1]);

/

CS1=1; CS2=1; // CS3=0;

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40);

for(cnt1=0; cnt1<64; cnt1++) DatWrite(bmp++); /

}

delay(10000);

Disp(0x00,0x00);

}

void Disp(Uchar dot1,Uchar dot2)

{

Uchar cnt;

register Uchar cnt1;

CS1=1;CS2=1; //SELECT ALL SEG IC

for(cnt=0;cnt<8;cnt++)

{

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40); //Set Y address

for(cnt1=0;cnt1<32;cnt1++)

{

DatWrite(dot1);

DatWrite(dot2);

}

}

CS1=0;CS2=0;

for(cnt=0;cnt<8;cnt++)

{

ComWrite(0x0b8+cnt); //Set Page Address 0~7

ComWrite(0x40); //Set Y address

for(cnt1=0;cnt1<32;cnt1++)

{

DatWrite(dot1);

DatWrite(dot2);

}

}

delay(10);

}

void Initial()

{

CS1=1; CS2=1;

RES =0;

delay(500);

RES =1;

delay(100);

ComWrite(0x0C0); // start line 00

ComWrite(0x3f); //Display ON

CS1=0; CS2=0; // CS3=1; // CLOSE IC

ComWrite(0x3f); //Display ON

}

void DatWrite(Uchar dat)

{

RS = 1;

RW = 0;

P1=dat;

E = 1;

//P1 = dat;

E = 0;

RW = 1;

}

void ComWrite(Uchar com)

{

RS = 0;

RW = 0;

P1=com;

E = 1;

//P1 = com;

E = 0;

RW =1;

}

unsigned char code Pic[8128]={

/-- 调入了一幅图像:C:\Documents and Settings\liuminglai\桌面\ebmp --/

/-- 宽度x高度=128x64 --/

0xFF,0xFF,0x83,0x83,0x83,0xC3,0xC3,0xC3,0x43,0x43,0x63,0x63,0xE3,0xE3,0xE3,0xE3,

0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0xA3,0x83,0x43,0x43,0x43,0x43,0x43,0x43,0x43,

0x43,0xC3,0xC3,0xC3,0x83,0x83,0x83,0x83,0x83,0x83,0x03,0x03,0x03,0x03,0x03,0x03,

0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,

0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,

0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,

0x03,0x83,0x83,0xC3,0x43,0xC3,0x43,0x63,0xE3,0x63,0x23,0x23,0xF3,0x33,0x93,0x93,

0x5B,0x2B,0xAB,0x9B,0xCB,0xCB,0xEB,0xEB,0x63,0x73,0xF3,0xF3,0xE3,0xC3,0xFF,0xFF,

0xFF,0xFF,0x0D,0x18,0x38,0x28,0x68,0x48,0xC8,0xC8,0xC8,0x88,0x8C,0x8C,0x8C,0x8C,

0x8C,0x8C,0x84,0x84,0x84,0xC4,0xC4,0xC4,0xC4,0xC4,0xC4,0x44,0x44,0x44,0x45,0x45,

0x45,0x45,0x40,0x48,0xF6,0x22,0x27,0xFD,0x2D,0x0B,0x07,0x11,0x5B,0x53,0xF3,0x23,

0x22,0x66,0x66,0x6C,0xCC,0x88,0x18,0x10,0x30,0x20,0x60,0xC0,0xC0,0x80,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x30,0x10,0xF8,0x0C,0x8C,0x3E,0x03,

0xE1,0x07,0x00,0x20,0x84,0xC1,0x70,0x2E,0xD3,0xF8,0x3E,0x1D,0x0E,0x0F,0x06,0x06,

0x07,0x03,0x07,0x07,0x07,0x05,0x01,0x03,0x03,0x06,0x06,0x04,0x01,0x03,0xFF,0xFF,

0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,

0x03,0x03,0x04,0x0C,0x08,0x18,0x30,0x20,0x68,0x68,0x60,0x44,0x44,0x44,0x44,0xC4,

0xC4,0xC4,0x84,0xA4,0xA4,0x25,0x26,0x5A,0x57,0x7D,0x55,0xF5,0xD5,0x85,0xE3,0x9D,

0x11,0x75,0xF5,0x14,0x14,0xFF,0x4B,0x42,0x54,0x50,0xF8,0x50,0x50,0x61,0xA3,0x06,

0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x80,0x80,0x80,0xC0,0x40,0xE0,0xF8,0x3C,0x0E,

0x07,0x03,0x03,0x33,0x91,0x99,0x89,0x0B,0xE3,0xF2,0xFC,0xF8,0xF0,0xE7,0xE8,0xCC,

0xCC,0x8C,0x8F,0xF6,0x39,0x1C,0x0E,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0

/

EY1206E3 IC: ST7565R

Parallel Interface: 6800 systeml

Duty = 1/65; Bias = 1/9; Vdd =30; Vop = 97v

20080811 by Arrow Du

/

#include <reg52h> //Port Pin included

#include <delayc>

#define Uchar unsigned char

#define Uint unsigned int

void DispBmp(Uchar bmp[]);

void DispDat(Uchar dat1, dat2);

void ComWrite(Uchar COM);

void DatWrite(Uchar DAT);

void INITIAL(void);

sbit RES = P3^7;

sbit CS1 = P3^1;

sbit RD1 = P3^5;

sbit WR1 = P3^0;

sbit A0 = P3^6;

Uchar Ratio=0x27;//调节LCD电压参数

Uchar Refer=0x30; //调节LCD电压参数

extern char code zft[]; //显示

void MAIN(void)

{

EA=1;

EX1=1;

PX1=1;

IT1=1;

WR=0;

delay(200);

INITIAL();

delay(200);

while(1)

{

DispBmp(zft);

delay(20000);

DispDat(0x55, 0x55);

DispDat(0xaa, 0xaa);

DispDat(0xff, 0x00);

DispDat(0x00, 0xff);

DispDat(0x00, 0x00);

}

}

void INITIAL()

{

delay(100);

CS1 =0;

RES=0;

delay(50);

RES=1;

delay(50);

ComWrite(0x02e);

delay(50);

ComWrite(02); // 1/9 bias

ComWrite(00); // ADC(segment driver direction select):reverse

ComWrite(0x0c8); // Common Output Mode Select: 1/64duty, COM63->COM0

ComWrite(0x2f); // Power Controller Set

ComWrite(0x2f); // Power Controller Set

delay(50);

ComWrite(0x0f8);

ComWrite(0x00); //Booster Ratio Select

ComWrite(Ratio);

ComWrite(0x81);

ComWrite(Refer);

ComWrite(0f); // Display ON

ComWrite(0x40); // Display Start Line Set: 00

}

void DispBmp(Uchar bmp[])

{

Uchar cnt, cnt1;

for(cnt=0; cnt<8; cnt ++)

{

ComWrite(0xb0 + cnt);

ComWrite(0x10);

ComWrite(0x00);

for(cnt1=0; cnt1<128; cnt1 ++)

{

DatWrite(bmp ++);

// delay(50);

}

}

delay(20000);

}

void DispDat(Uchar dat1, dat2)

{

Uchar cnt,cnt1;

for(cnt=0; cnt<8; cnt++)

{

ComWrite(0xb0 + cnt);

ComWrite(0x10);

ComWrite(0x00);

for(cnt1=0; cnt1<128 ; cnt1++)

{

DatWrite(dat1);

DatWrite(dat2);

}

}

delay(20000);

}

/void ComWrite(Uchar COM)

{

;

A0=0;

delay(1);

P1=COM;

delay(1);

E=0;

delay(1);

E=1;

}

void DatWrite(Uchar DAT)

{

A0=1;

delay(1);

P1=DAT;

delay(1);

E=0;

delay(1);

E=1;

} /

/

void ComWrite(unsigned char com)

{

unsigned char count;

CS1=1;

A0=0;

for (count = 0; count < 8; count++)

{

SCL=0;

SDA=(bit)(com&0x80);

SCL=1;

com=com<<1;

}

delay(10);

}

void DatWrite(unsigned char dat)

{

unsigned char count;

CS1=0;

A0=1;

for (count = 0; count < 8; count++)

{

SCL=0;

SDA=(bit)(dat&0x80);

SCL=1;

dat=dat<<1;

}

delay(10);

}

/

void DatWrite(Uchar dat)//80

{

A0 = 1;

RD1=1;

WR1=0;

P1=dat;

WR1=1;

}

void ComWrite(Uchar com)

{

A0 = 0;

RD1=1;

WR1=0;

P1=com;

WR1=1;

}

LCD12864和LCM12864的区别在于:

1、LCM12864带字库;LCD12864不带字库。

2、LCD12864是液晶显示器,一般是指单独的屏幕;LCM12864是液晶显示模组,它包括相应的驱动电路和控制电路,可以直接与单片机相连。

液晶模块简单点说就是LCD屏+LED背光板+PCB板+铁框。模块主要分为屏和背光灯组件。两部分被组装在一起,但工作的时候是相互独立的(即电路不相关)。液晶显示的原理是背光灯组件发出均匀的面光,光通过液晶屏传到我们的眼睛里。屏的作用就是按像素对这些光进行处理,以显示图像。

这个是最底层的驱动程序有问题。

请参考以下这两个驱动程序

总线接口:

模拟口线接口:

你按程序里面的连线连接好后可以直接运行。

相关对应产品资料,完全和你现在的液晶显示模块产品程序兼容。

如有不清楚之处,请发邮件给我sunmanlcm@163com

#define LCM_RW P2_0 //定义引脚

#define LCM_RS P2_1

#define LCM_E P2_2

#define LCM_Data P1

#define Busy 0x80 //用于检测LCM状态字中的Busy标识

#i nclude <at89x51h>

void WriteDataLCM(unsigned char WDLCM);

void WriteCommandLCM(unsigned char WCLCM,BuysC);

unsigned char ReadDataLCM(void);

unsigned char ReadStatusLCM(void);

void LCMInit(void);

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code DData);

void Delay5Ms(void);

void Delay400Ms(void);

unsigned char code uctech[] = {"uctech"};

unsigned char code net[] = {"uctechicpcncom"};

void main(void)

{

Delay400Ms(); //启动等待,等LCM讲入工作状态

LCMInit(); //LCM初始化

Delay5Ms(); //延时片刻(可不要)

DisplayListChar(0, 5, uctech);

DisplayListChar(0, 0, net);

ReadDataLCM();//测试用句无意义

while(1);

}

//写数据

void WriteDataLCM(unsigned char WDLCM)

{

ReadStatusLCM(); //检测忙

LCM_Data = WDLCM;

LCM_RS = 1;

LCM_RW = 0;

LCM_E = 0; //若晶振速度太高可以在这后加小的延时

LCM_E = 0; //延时

LCM_E = 1;

}

//写指令

void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测

{

if (BuysC) ReadStatusLCM(); //根据需要检测忙

LCM_Data = WCLCM;

LCM_RS = 0;

LCM_RW = 0;

LCM_E = 0;

LCM_E = 0;

LCM_E = 1;

}

//读数据

unsigned char ReadDataLCM(void)

{

LCM_RS = 1;

LCM_RW = 1;

LCM_E = 0;

LCM_E = 0;

LCM_E = 1;

return(LCM_Data);

}

//读状态

unsigned char ReadStatusLCM(void)

{

LCM_Data = 0xFF;

LCM_RS = 0;

LCM_RW = 1;

LCM_E = 0;

LCM_E = 0;

LCM_E = 1;

while (LCM_Data & Busy); //检测忙信号

return(LCM_Data);

}

void LCMInit(void) //LCM初始化

{

LCM_Data = 0;

WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号

Delay5Ms();

WriteCommandLCM(0x38,0);

Delay5Ms();

WriteCommandLCM(0x38,0);

Delay5Ms();

WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号

WriteCommandLCM(0x08,1); //关闭显示

WriteCommandLCM(0x01,1); //显示清屏

WriteCommandLCM(0x06,1); // 显示光标移动设置

WriteCommandLCM(0x0C,1); // 显示开及光标设置

}

//按指定位置显示一个字符

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)

{

Y &= 0x1;

X &= 0xF; //限制X不能大于15,Y不能大于1

if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;

X |= 0x80; // 算出指令码

WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码

WriteDataLCM(DData);

}

//按指定位置显示一串字符

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code DData)

{

unsigned char ListLength;

ListLength = 0;

Y &= 0x1;

X &= 0xF; //限制X不能大于15,Y不能大于1

while (DData[ListLength]>0x20) //若到达字串尾则退出

{

if (X <= 0xF) //X坐标应小于0xF

{

DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符

ListLength++;

X++;

}

}

}

//5ms延时

void Delay5Ms(void)

{

unsigned int TempCyc = 5552;

while(TempCyc--);

}

//400ms延时

void Delay400Ms(void)

{

unsigned char TempCycA = 5;

unsigned int TempCycB;

while(TempCycA--)

{

TempCycB=7269;

while(TempCycB--);

};

下面是我机子上调试过的一个程序,希望那个对你有所帮助。。

祝你好运~~~~~~

//

/ /

/名称: LCD12864显示程序 /

/功能: 显示英文,数字,符号,。 /

/难度等级: 高 /

//

#include <reg52h>

#include <stringh>

#define uchar unsigned char

/引脚定义/

sbit lck = P3^5;//锁存信号

/常用命令及参数定义/

#define DISPON 0x3f

#define DISPOFF 0x3e

#define DISPFIRST 0xc0

#define SETX 0x40

#define SETY 0xb8

#define LCDBUZY 0x80

#define L 0x00

#define R 0x40

#define LIMIT 0x80

/全局变量/

uchar cbyte;

uchar data statu;

bit xy;

/函数/

void WrL(uchar x);

void WrR(uchar x);

void Lcmcls(void);

void delay1s(void);

void Lcminit (void);

void Putpicture(uchar flag);

void delay(unsigned int time);

void VtoH8x16change(uchar hzbuf);

void Puthalf(uchar strch,uchar row,uchar col);

void Wrdata(uchar x,uchar row,uchar col);

void Locatexy(uchar row,uchar col);

void vWrite8x16Character(uchar ch,uchar row,uchar col,bit flag);

void vWrite8x16String(uchar str,uchar col, uchar row, bit flag);

extern uchar code picture1[];

extern uchar code picture2[];

extern uchar code char_Table[95][16];

/主程序/

void main(void)

{

Lcminit();

while(1){

Putpicture(0);

delay1s();

Lcmcls();

Putpicture(1);

delay1s();

Lcmcls();

vWrite8x16String("abcdefghijklmn" ,0, 8,0);

vWrite8x16String("ABCDEFGHIJKLMN", 2, 8,0);

vWrite8x16String("12345678901234", 4, 8,0);

vWrite8x16String("+-/!@#$%^&()", 6, 8,0);

delay1s();

Lcmcls();

}

}

/微秒级延时/

void delay(unsigned int time)

{ unsigned int i;

for(i=0;i<time;i++);

}

/约5S延时/

void delay1s(void)

{

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

delay(50000);

}

//初始化LCD/

void Lcminit (void)

{

cbyte=DISPOFF;

WrL(cbyte);

WrR(cbyte);

cbyte=DISPON;

WrL(cbyte);

WrR(cbyte);

cbyte=DISPFIRST;

WrL(cbyte);

WrR(cbyte);

Lcmcls();

Locatexy(0,0);

}

/LCD清屏/

void Lcmcls(void)

{ uchar i,j;

for(i=0;i<8;i++){

delay(6);

for(j=0;j<LIMIT;j++){

delay(6);

Wrdata(0x0,i,j);

}

}

}

/写左区/

void WrL(uchar x)

{

P0=0xFF;//P0口送FF,准备读

lck = 0;

P1 = 0x2a;//ELCD=1�/W=1(读),CSB=1,CSA=0

lck = 1;

while(P0 & LCDBUZY);//最高位为1,表示忙,则循环

lck = 0;

P1 = 0x00;//ELCD=0,R/W=0(读),CSB=0,CSA=0

lck = 1;

P0 = x; //数据送到P0口

lck = 0;

P1 = 0x22;//ELCD=1,RW = 0(写),CSB=1,CSA=0

lck = 1;

lck = 0;

P1 = 0x00;//ELCD=0,RW = 0(写),CSB=0,CSA=0

lck = 1;

}

/写右区/

void WrR(uchar data x)

{

P0=0xFF;//P0口送FF,准备读

lck = 0;

P1 = 0x29;//ELCD=1,R/W=1(读),CSB=0,CSA=1

lck = 1;

while(P0 & LCDBUZY);//最高位为1,表示忙,则循环

lck = 0;

P1 = 0x00;//ELCD=0,R/W=0(读),CSB=0,CSA=1

lck = 1;

P0=x; //数据送到P0口

lck = 0;

P1 = 0x21;//ELCD=1,RW = 0(写),CSB=0,CSA=1

lck = 1;

lck = 0;

P1 = 0x00;//ELCD=0,RW = 0(写),CSB=0,CSA=0

lck = 1;

}

/定位/

void Locatexy(uchar row,uchar col)

{

uchar x, y, right;

switch(col&0xc0)

{

case 0:{

P0=0xFF;//P0口送FF,准备读

lck = 0;

P1 = 0x29;//ELCD=1,R/W=1(读),CSB=0,CSA=1

lck = 1;

while(P0 & LCDBUZY);//最高位为1,表示忙,则循环

lck = 0;

P1 = 0x00;

lck = 1;

right = 1;break;}//置右半屏标志

case 0x40:{

P0=0xFF;//P0口送FF,准备读

lck = 0;

P1 = 0x2a;//ELCD=1,R/W=1(读),CSB=1,CSA=0

lck = 1;

while(P0 & LCDBUZY);//最高位为1,表示忙,则循环

lck = 0;

P1 = 0x00;//ELCD=0,R/W=0(读)�CSB=0,CSA=0

lck = 1;

right = 0;break;}//置左半屏标志

}

x=col&0x3f|SETX;//把列数据变成行命令

y=row&0x07|SETY;//把行数据变成行命令

//

lck = 0;

if(right)

P1 = 0x29;

else

P1 = 0x2a;

lck = 1;

while(P0 & LCDBUZY);//最高位为1,表示忙,则循环

lck = 0;

P1 = 0x00;

lck = 1;

/以上为判断忙标志/

//

P0 = y;

lck = 0;

if(right)

P1 = 0x21;

else

P1 = 0x22;

lck = 1;

lck = 0;

P1 = 0x00;

lck = 1;

/以上为送行命令/

P0=0xFF;

lck = 0;

if(right)

P1 = 0x29;

else

P1 = 0x2a;

lck = 1;

while(P0 & LCDBUZY);//最高位为1,表示忙,则循环

lck = 0;

P1 = 0x00;

lck = 1;

/以上为判断忙标志/

P0 = x;

lck = 0;

if(right)

P1 = 0x21;

else

P1 = 0x22;

lck = 1;

lck = 0;

P1 = 0x00;

lck = 1;

/以上为送列命令/

if(right)

statu = 1;

else

statu = 0;//置左又半区标志

}

/数据写输出/

void Wrdata(uchar x,uchar row,uchar col)

{

Locatexy(row,col);//定位显示位置

lck = 0;

if(statu)

P1 = 0x05;//ELCD=0�R/W=0(写),D/I= 1 ,CSB=0,CSA=1

else

P1 = 0x06;//ELCD=0,R/W=0(写),D/I= 1 ,CSB=1,CSA=0

lck = 1;

P0 = x;

lck = 0;

if(statu)

P1 = 0x25;//ELCD=1,R/W=0(写),D/I= 1 ,CSB=0,CSA=1

else

P1 = 0x26;//ELCD=1,R/W=0(写),D/I= 1 ,CSB=1,CSA=0

lck = 1;

lck = 0;

P1 = 0x00;

lck = 1;

}

/图形输出/

void Putpicture(uchar flag)

{

unsigned char i,j,row, col ;

unsigned int x;

row = 0; col=0;

for(j=0;j<128;j++){

x=j0x08;

for(i=0;i<8;i++)

{ if(flag)

cbyte=picture1[x++];

else

cbyte=picture2[x++];

Wrdata(cbyte,row,col);

row++;

}

row=0;

col++;

}

}

/半角数据点阵输出/

void Puthalf(uchar strch,uchar row,uchar col)

{

uchar i,bakerx;

bakerx = row;

for(i=0;i<16;i++)//上半字输出

{

cbyte=strch[i];

Wrdata(cbyte,bakerx,col);

cbyte=strch[i+1];

Wrdata(cbyte,bakerx+1,col);

col++;

i++;

}

}

/汉字输出/

/void Puthz(uchar str,uchar row,uchar col)

{

uchar i,bakerx;

bakerx=row;

for(i=0;i<32;i++)

{

cbyte=str[i];

Wrdata(cbyte,row,col); //上半字节输出

i++;

row=bakerx+1;

cbyte=str[i];

Wrdata(cbyte,row,col); //下半字节输出

row=bakerx;

col=col+1;

}

}

/

/字符型点阵行--》列转换/

void VtoH8x16change(uchar hzbuf)

{ uchar i,j,k, cash[16];

uchar newbyte, savebit[8];

for(k=0;k<16;k++){

newbyte = 0;

for(i=0;i<8;i++){

savebit[i]=hzbuf[i] & 0x80;

}

for(j=0;j<8;j++){

savebit[j] = savebit[j] >> (7-j);

newbyte = newbyte | savebit[j];

}

cash[k] = newbyte;

newbyte = 0;

for(i=8;i<16;i++){

savebit[i-8]=hzbuf[i] & 0x80;

}

for(j=0;j<8;j++){

savebit[j] = savebit[j] >> (7-j);

newbyte = newbyte |savebit[j];

}

cash[k+1] = newbyte;

for(j=0;j<16;j++){

hzbuf[j] = hzbuf[j] <<1;

}

k++;

}

for(i=0;i<16;i++)

hzbuf[i] = cash[i];

}

/显示英文和符号字符/

void vWrite8x16Character(uchar ch,uchar row,uchar col,bit flag)

{

uchar ucXArray[16],i;

if(flag){ // 反白显示英文

for(i = 0; i < 16; i++)

ucXArray[i] = ~ch[i];

}else{

for(i = 0; i < 16; i++)

ucXArray[i] = ch[i];

}

VtoH8x16change(ucXArray);

Puthalf(ucXArray,row,col);

}

/显示英文字符串/

void vWrite8x16String(uchar str,uchar row, uchar col, bit flag)

{

unsigned char i, j,thiscol;

j = strlen(str);

for(i = 0; i < j; i++)

{ thiscol = (i % 16) 8 + col;//计算列地址

if(str[i] < 0xa1)//当前显示内容为英文字符

vWrite8x16Character(&char_Table[str[i]-0x20][0],row,thiscol,flag);

}

}

以上就是关于AVR写LCD12864,在写页地址后读状态,一直为忙,那为懂AVR的帮我解决一下呢,用的是atmel studio 6.0全部的内容,包括:AVR写LCD12864,在写页地址后读状态,一直为忙,那为懂AVR的帮我解决一下呢,用的是atmel studio 6.0、关于verilog的12864程序、LCD12864和LCM12864的区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/10130371.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存