发 帖  
原厂入驻New
[问答]

12864显示汉字,开始是乱码,然后正常显示

8900
分享
#include<reg52.h>
#define uchar unsigned char       
#define uint  unsigned int
#define DataPort  P3
sbit E=P2^0;
sbit RW=P2^1;
sbit RS=P2^2;
sbit PSB=P2^3;
uchar code a1[]="啊啊啊啊啊啊啊啊";
uchar code a2[]="哈哈哈哈哈哈哈哈";
uchar code a3[]="啦啦啦啦啦啦啦啦";
uchar code a4[]="呃呃呃呃呃呃呃呃";
uchar d[]={0x98,0x90,0x88,0x80};
/**************延时1ms*count*****************/
void delay(int count)
{        int x,y;
for(x=0;x<count;x++)
for(y=0;y<120;y++);
}


/***********忙检测********************/
void Busy()
{
DataPort=0xFF;
RS=0;
RW=1;
while (1)
   {
E =1;
if (P0^7==0) break;
}
E=0;
}
/***********写指令子程序****************/
void Write_Com(uchar command)
{
Busy();        //检测忙标志位
RS=0;
RW=0;                                                          
DataPort=command;        //写入指令
E=1;
delay(1);                                                       
E=0;                                                                                                  
}                                                          
/***********写数据子程序***************/
void Write_Data(uchar Data)
{
Busy();
RS=1;                 
RW=0;
DataPort=Data;
E=1;
delay(1);
E=0;  
}
/***********LCD初始化*******************/
void Init_LCD(void)
{   
PSB=0;
delay(1);
PSB=1;         //将PSB置1,通信方式为8位数据并口
delay(1);
Write_Com(0x30);//30H--基本指令操作
Write_Com(0x34);   
Write_Com(0x0c);//开显示,关光标,不闪烁。
Write_Com(0x01);//清除显示  
Write_Com(0x02);
Write_Com(0x06);//指定在资料写入或读取时,光标的移动方向,DDRAM的地址计数器(AC)加1。
Write_Com(0x04);//显示状态 全关
}
/*****************清屏***********************/
void Clear_Lcd(void)
{
Write_Com(0x01);
Write_Com(0x34);
Write_Com(0x30);
}

/*******************逐行显示***************************************/
void Lcd_pos(uchar X,uchar Y)
{                          
   uchar  pos;
   if (X==1)
     {X=0x80;}
   else if (X==2)
     {X=0x90;}
   else if (X==3)
     {X=0x88;}
   else if (X==4)
     {X=0x98;}
   pos = X+Y ;

   Write_Com(pos);     //显示地址
}

void main()
{
   uchar i;
   delay(100);                 //上电,等待稳定
   Init_LCD();                 //初始化LCD
   while(1)
   {
     Lcd_pos(1,0);             //设置显示位置为第一行
     for(i=0;i<16;i++)
     {
       Write_Data(a1[i]);
       delay(30);
     }

     Lcd_pos(2,0);             //设置显示位置为第二行
     for(i=0;i<16;i++)
     {
       Write_Data(a2[i]);
       delay(30);
     }
     Lcd_pos(3,0);             //设置显示位置为第三行
     for(i=0;i<16;i++)
     {
       Write_Data(a3[i]);
       delay(30);
     }
     Lcd_pos(4,0);             //设置显示位置为第四行
     for(i=0;i<16;i++)
     {
       Write_Data(a4[i]);
       delay(30);
     }
    Clear_Lcd(); //清屏函数,为下次刷新准备
   }
}
0
2014-7-9 16:44:15   评论 分享淘帖 邀请回答
11个回答
问题不清楚,具体现在描述太少了,代码也不全,尽量上传一下完整的工程文件。这样好帮你调试,你懂的。
2014-7-9 19:25:15 评论

举报

我是个新手,麻烦指导一下,谢谢

12864.zip

下载积分: 积分 -1 分

21.61 KB , 下载次数: 43 , 下载积分: 积分 -1 分

2014-7-10 10:59:51 评论

举报

你用的不是仿真吧!这个程序我看了一下,你的应该类似1602的驱动,也就是说在仿真中用的是LM041,只不过仿真中的模型不带中文字库。
你说的开始时乱码,后来好使了,具体是个什么现象呢?不是很清楚。另外你的忙检测有问题,看一下手册你就知了。我qq441747863,如果你自己确实解决不了了,就加我, QQ截图20140710134219.png
2014-7-10 13:47:02 评论

举报



武力戡乱 发表于 2014-7-10 13:47
你用的不是仿真吧!这个程序我看了一下,你的应该类似1602的驱动,也就是说在仿真中用的是LM041,只不过仿 ...



好的非常感谢!
2014-7-10 14:59:44 评论

举报

我也有同样的问题,你的解决了吗?分享一下方案吧!
我用12864B液晶,显示数字时有的地方正常,有的地方显示的是乱码(偶尔乱码)。是单片机的问题还是程序的问题?高手们指点一下!!!不胜感激!!!
#include <c8051f020.h>
#include <LCD.h>

//12864端口定义
#define LCD_DATA P5        //数据口
sbit RS  = P3^0;           //并行的指令/数据选择信号, H数据, L命令
sbit RW  = P3^1;           //并行读写选择信号, H读, L写
sbit E   = P3^2;           //并行使能端, H有效, L无效
sbit PSB = P3^3;           //并/串接口选择, H并,L串
sbit RST = P3^4;           //复位, L有效

void delayms(unsigned int time)    //延时 time * 1ms
{
    unsigned int i,j;
    for(i = 0; i < time; i++)
        for(j = 0; j < 300; j++);
}

bit checkBusy()            //检测LCD是否处于忙状态, 若忙返回1, 空闲返回0
{
    bit busy;
    RS = 0;
    RW = 1;
    E = 1;
    delayms(1);
    busy = (bit)(LCD_DATA&0x80);
    E = 0;
    return busy;
}

void wait()                 //等待LCD到空闲
{
    while(checkBusy());
}

void writeCmd(unsigned char cmd)    //写命令
{
    wait();
    RS = 0;
    RW = 0;
    E = 0;
    delayms(1);
    LCD_DATA = cmd;
    delayms(1);
    E = 1;
    delayms(1);
    E = 0;
}

void writeData(unsigned char dat)   //写数据
{
    wait();
    RS = 1;
    RW = 0;
    E = 0;
    delayms(1);
    LCD_DATA = dat;
    delayms(1);
    E = 1;
    delayms(1);
    E = 0;
}

void LCD_Init()            //初始化LCD屏
{
    RST = 0;
    delayms(100);
    RST = 1;
    PSB = 1;               //并口方式
    writeCmd(0x30);        //基本指令, 扩充指令为34H
    delayms(10);
    writeCmd(0x0c);        //显示开, 关光标
    delayms(10);
    writeCmd(0x01);        //清屏
    delayms(10);
}

void setPosition(unsigned char x, unsigned char y)
{
    unsigned char p;
    switch(x%4)
    {
        case 0: p = 0x80; break;   //第一行开始地址
        case 1: p = 0x90; break;   //第二行
        case 2: p = 0x88; break;   //第三行
        case 3: p = 0x98; break;   //第四行
    }
    p += y;
    writeCmd(p);
}

void writeString(unsigned char * str)
{
    unsigned char i = 0;
    while(str[i] != '\0')
    {
        writeData(str[i++]);
    }
}



start:        Di();
                writeCmd(0x01);          // 清屏
            writeCmd(0x0c);          // 取消光标闪烁
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------

                                  
Zeroing:        
                writeCmd(0x0c);          // 取消光标闪烁
                                setPosition(0,0),writeString(Zeroing);         //显示正在回零--------------偶尔乱码文字
               
                Move_to_Zero();
                while( Limit_down == 1 )
                    {
                                              
                }
                Motor2_Off();                   // 撞到零点限位,电机停止
                                Pressure_last = 33;
                delay(60000);
                            
                                direction2 = 1;                 //确定计数方向                       
                                Motor2_On();
                     
                                //delay(60000);
                                               
                       

                                writeCmd(0x01);          // 清屏
                    writeCmd(0x0c);          // 取消光标闪烁
                               
                                setPosition(0,0),writeString(Adjusting);------------------偶尔乱码文字
2014-12-24 15:48:27 评论

举报

一样的,这个都是那个1602的内核,只是和1602偏移地址不同
        case 0: p = 0x80; break;   //第一行开始地址
        case 1: p = 0x90; break;   //第二行
        case 2: p = 0x88; break;   //第三行
        case 3: p = 0x98; break;   //第四行
你可以参考1602的程序改
2014-12-24 18:41:27 评论

举报

我用的是12864的液晶屏,就是在不停的刷新显示数据时,文字部分乱码,数字部分卡。是清屏问题还是时序问题。我是新手,还请多指点一下!
// 回零并调整压力-----------------------------------------------------------------------------------------------------------------------
start:        Di();
                writeCmd(0x01);          // 清屏
            writeCmd(0x0c);          // 取消光标闪烁
//-----------------------------------------------------------------
//-----------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------

                                  
Zeroing:        
                writeCmd(0x0c);          // 取消光标闪烁
                                setPosition(0,0),writeString(Zeroing);         //显示正在回零
               
                Move_to_Zero();
                while( Limit_down == 1 )
                    {
                                              
                }
                Motor2_Off();                   // 撞到零点限位,电机停止
                                Pressure_last = 33;
                delay(60000);
                            
                                direction2 = 1;                 //确定计数方向                       
                                Motor2_On();
                     
                                //delay(60000);
                                               
                       

                                writeCmd(0x01);          // 清屏
                    writeCmd(0x0c);          // 取消光标闪烁
                               
                                setPosition(0,0),writeString(Adjusting);
               
                               
                P_counting();  // 检测码盘

                Motor2_Off();                                  // 调压电机运行到设置高度后停止
                        Pressure_last = Pressure_set;  


备注:writeString(Zeroing)------应该显示“正在回零”-------但此时却显示乱码;  
         writeString(Adjusting-----应该显示“正在调压”-------但此时却显示乱码;  

我的静态显示时就没有问题,就writeString(Zeroing)、writeString(Adjusting)显示时总是刷屏(显示的是直流电机调节的情况),会出现乱码
2014-12-25 15:19:15 评论

举报

程序不完整啊,看不到时序啊。你参考1602的代码,只要仿真没有警告,就一定可以完美运行!
去论坛找找吧,里面很多的例子,找个没有警告的。
2014-12-26 15:34:51 评论

举报

另外你这个12864就是1602的一个扩展!
2014-12-26 15:35:22 评论

举报

一般都是延时的问题,读写操作时最好加多点延时
2016-3-14 13:51:45 评论

举报

撰写答案

你正在撰写答案

如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
我要提问
快速回复 返回顶部 返回列表