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

#defineLCD_Star_Line0xc0//起始行,共64行#defineLCD_Page0xB8//起始页,共8页#defineLCD_Vertical0x40... #define LCD_Star_Line 0xc0 //起始行,共64行
#define LCD_Page 0xB8 //起始页,共8页
#define LCD_Vertical 0x40 //起始例地址,共64例,共分为两块区域
#define LCD_ON 0x3f //液晶屏开
#define LCD_OFF 0x3E //液晶屏关
//定义接口寄存器
#define LCD_Data_Write PORTC //输出数据
#define LCD_Data_Flow DDRC //设置C口引脚方向,输出为写,输入为读
#define LCD_Data_Read PINC //读取状态口地址
#define LCD_Ctrl_Port PORTD
#define LCD_Ctrl_Flow DDRD

void LCD_Status()
{
INTU8 check;
Check_Busy:
LCD_Data_Flow=0x00;//设置为输入
LCD_Data_Write=0xff;//设置上拉电阻
LCD_Ctrl_Flow=0xff;//设置D口为输出
RW_1();
asm("nop");
RS_0();
asm("nop");
E_1();
asm("nop");
check=LCD_Data_Read;
E_0();
while(check&0x80) goto Check_Busy;
}
void LCD_Initialize()
{
Rest_1();
LCD_Write_Command(LCD_OFF);
LCD_Write_Command(LCD_ON);
}
void LCD_Write_Command(INTU8 m_com)
{
LCD_Status();//读取LCD液晶屏的状态
LCD_Data_Flow=0xff;//C口设置为输出
LCD_Data_Write=0xff;
LCD_Ctrl_Flow=0xff;//D口设置为输出
RW_0();
asm("nop");
RS_0();
asm("nop");
LCD_Data_Write=m_com;
_delay_us(20);
E_1();
asm("nop");
E_0();
}
void LCD_Write_Data(INTU8 m_data)
{
LCD_Status();
LCD_Data_Flow=0xff;//设置端口C为输出
LCD_Data_Write=0xff;//设置输出高电平

RW_0();
asm("nop");
RS_1();
asm("nop");
if(!Data_Display) LCD_Data_Write=m_data;
else LCD_Data_Write=~m_data;
_delay_us(20);
E_1();
asm("nop");
E_0();
}
void LCD_Clear()
{
INTU8 j,k;
CS1_1();
CS2_1();
LCD_Write_Command(LCD_Page+0);//写了这句后,读液晶状态一直为忙
LCD_Write_Command(LCD_Vertical+0);
for(j=0;j<8;j++)
{
LCD_Write_Command(LCD_Page+j);
for(k=0;k<64;k++)
{
LCD_Write_Command(LCD_Vertical+k);
LCD_Write_Data(0x00);
}
}

}
写开关屏命令后,读状态都是正常的,就是在写page和例时检测液晶屏状态,就一直是忙,程序检查了几遍都没发现问题,实在没法了,
展开
 我来答
倩术绝七0u
2014-06-10 · TA获得超过600个赞
知道答主
回答量:87
采纳率:0%
帮助的人:82.3万
展开全部

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

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

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

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

  4. 个人观点供参考,我用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();
    }

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

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式