首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

一个奇怪的1602液晶显示有关问题

2012-02-17 
一个奇怪的1602液晶显示问题我写了个1602的程序,完全可以驱动1602显示,但有一个这样的问题,我搞不明白。主

一个奇怪的1602液晶显示问题
我写了个1602的程序,完全可以驱动1602显示,但有一个这样的问题,我搞不明白。
主函数如下:

void main(void)
{
  Initialize();//初始化液晶
  WriteChar(5,1,'Q');//在第液晶第1行第6个位置会显示一个“A”
  Delay(500);//延时500ms 
  WriteChar(5,2,'Q');//如果没有执行上面那条500ms延时的语句,在第液晶第2行第6个位置会显示一个“B”
  //如果执行了上面那条500ms延时的语句,在第液晶第2行第6个位置不会有任何反应
  //我试过,如果改为200ms的延时,是可以正常在第液晶第2行第6个位置会显示一个“B”的
  while(1);
}

先谢谢大家了,这东西困扰我一天了,就是没想明白是什么原因。

[解决办法]
没有看懂你的意思,你说的A和B都是属于正常显示吗?你的程序里明明是Q……
另外,如果1602的显示不正常,大半是初始化的问题,另外还有一个就是延时设置问题
你这里只贴出了main函数,关键的initialize和writechar都没有贴出来,实在是无法分析什么
[解决办法]

C/C++ code
//==============================================//// Filename:   C8051f320_SMC1602A_Display.c     ////                                              //// Prozessor:  C8051f320                        //// Compiler:   Keil C51 7.06                    ////                                              //// Author:     Paul.Jia                         //// QQ:         79974439                         //// Copyright:  MKL PSC TSD                      ////==============================================////================================================//1. SYSCLK is unlimited here//2. Display by SMC1602A////Use 3 ports for control//Use 8 ports for data communications//And initialize them right in the Main ////Need ms delay function from the Main//    extern void delay_ms(unsigned short ms);////Need initialize before use the diaplay function//    void LCMInit(void);////Export these 2 function//    void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);//    void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);//================================================//----------------------------// Include Files//----------------------------#include <c8051f320.h>#include <intrins.h>//----------------------------// Global Constants//----------------------------// Define control ports and data ports// P0.5 - digital    push-pull    (1602)RS// P0.6 - digital    push-pull    (1602)RW// P0.7 - digital    push-pull    (1602)E // P1.x - digital    push-pull    (1602)DATA// Have to initalize these ports in the Main//sbit RS1602 = P0 ^ 5;                             // Register select signal portsbit RW1602 = P0 ^ 6;                             // Data read/write portsbit E1602  = P0 ^ 7;                             // Enable signal port#define DATA1602 P1                               // Data port// Define macro definition basic the selected ports//#define W_D_IN   P1MDOUT &= 0x00                  // Change Data port to open-drain#define W_D_OUT  P1MDOUT |= 0xFF                  // Change Data port to push-pull// Define device busy flag//#define Busy     0x80//----------------------------// Function Prototypes//----------------------------// Write data to SMC1602A//void WriteDataLCM(unsigned char WDLCM);// Write command to SMC1602A//void WriteCommandLCM(unsigned char WCLCM, unsigned char BusyC);// Read data from SMC1602A//unsigned char ReadDataLCM(void);// Read command from SMC602A//unsigned char ReadStatusLCM(void);// Initalize SMC1602A//void LCMInit(void);// Display a char at the specified position//void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);// Display a string at the specified position//void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);// Call a extern ms delay function//extern void delay_ms(unsigned short ms);//----------------------------// Subroutines//----------------------------//-----------------Write Data---------------------void WriteDataLCM(unsigned char WDLCM)//------------------------------------------------{    ReadStatusLCM();                              // Detect Busy     W_D_OUT;                                      // Change Data port to push-pull    DATA1602 = WDLCM;                             // Write data    RS1602 = 1;                                   // LCM_RS = 1;    RW1602 = 0;                                   // LCM_RW = 0;    E1602 = 0;                                    // LCM_E = 0; If SYSCLK is high, add a small delay into here    delay_ms(4);    E1602 = 1;                                    // LCM_E = 1;}//----------------Write Command-------------------void WriteCommandLCM(unsigned char WCLCM, unsigned char BusyC)//------------------------------------------------{    if(BusyC)                                     // Decide if detect Busy from parameter    {        ReadStatusLCM();                          // Detect Busy     }    W_D_OUT;                                      // Change Data port to push-pull    DATA1602 = WCLCM;                             // Write command    RS1602 = 0;                                   // LCM_RS = 0;    RW1602 = 0;                                   // LCM_RW = 0;    E1602 = 0;                                    // LCM_E = 0; If SYSCLK is high, add a small delay into here    delay_ms(4);    E1602 = 1;                                    // LCM_E = 1;}/*//------------------Read Data---------------------unsigned char ReadDataLCM(void)//------------------------------------------------{    RS1602 = 1;                                   // LCM_RS = 1;    RW1602 = 1;                                   // LCM_RW = 1;    E1602 = 0;                                    // LCM_E = 0; If SYSCLK is high, add a small delay into here    delay_ms(4);    E1602 = 1;                                    // LCM_E = 1;    W_D_IN;                                       // Change Data port to open-drain    return DATA1602;                              // Return data}*///-----------------Read Command-------------------unsigned char ReadStatusLCM(void)//------------------------------------------------{    W_D_IN;                                       // Change Data port to open-drain    RS1602 = 0;                                   // LCM_RS = 0;    RW1602 = 1;                                   // LCM_RW = 1;    E1602 = 0;                                    // LCM_E = 0; If SYSCLK is high, add a small delay into here    delay_ms(4);    E1602 = 1;                                    // LCM_E = 1;    while(DATA1602 & Busy);                       // Detect Busy     return DATA1602;                              // Return data}//------------------Initalize---------------------void LCMInit(void)//------------------------------------------------{    DATA1602 = 0;      WriteCommandLCM(0x38, 0);                     // Set display mode 3 times, no detect Busy    delay_ms(5);    WriteCommandLCM(0x38, 0);    delay_ms(5);    WriteCommandLCM(0x38, 0);    delay_ms(5);    // Keep above code    WriteCommandLCM(0x38, 1);                     // Set display mode(8 bits, 2 rows, 5x7), begin detect Busy everytime    WriteCommandLCM(0x08, 1);                     // Close display    WriteCommandLCM(0x01, 1);                     // Clear screen    WriteCommandLCM(0x06, 1);                     // Show the position of cursor move    WriteCommandLCM(0x0C, 1);                     // Show boot-strap cursor setting    WriteCommandLCM(0x80, 1);                     // The first position is row 1 line 1}//----------------Display one char----------------void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)//------------------------------------------------{    Y &= 0x1;    X &= 0xF;                                     // Revise X<=15 Y<=1    if(Y)                                         // Add 0x40 to address for display row 2    {        X |= 0x40;    }    X |= 0x80;                                    // Count the address    WriteCommandLCM(X, 0);                        // Send the address to SMC1602A    WriteDataLCM(DData);                          // Write the char to SMC1602A}//----------------Display list char---------------void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)//------------------------------------------------{    unsigned char ListLength = 0;    Y &= 0x1;    X &= 0xF;                                     // Revise X<=15 Y<=1    while(DData[ListLength] >= 0x20)              // If the string end, quit    {        if(X <= 0xF)        {            DisplayOneChar(X, Y, DData[ListLength]); // Display one char            ListLength++;            X++;        }    }} 


[解决办法]
不知道你用的是什么型号的1602,SMC1602A的要求是在初始化时,应有三次设置模式的操作就是我给的程序里的
WriteCommandLCM(0x38, 0); // Set display mode 3 times, no detect Busy
delay_ms(5);
WriteCommandLCM(0x38, 0);
delay_ms(5);
WriteCommandLCM(0x38, 0);
delay_ms(5);
这是Datasheet里明确要求的,你也可以注意一下你使用的1602,它的资料是怎么说的

另外你的write1602缺少读写检测,就是确保STA7=0的操作,这个也是按照SMC1602A的要求要有的,你可能需要看一下你的1602的相关要求

最后,在write1602里
P0 = Convert(a);
E = 1;
_nop_();
E = 0;
根据1602的要求,在写数据时E为高的时间应大于150ns,所以这里最好不要用_nop_();
[解决办法]
这样吧,你可以试一下,
在 WriteChar(5,1,'A');//在第液晶第1行第6个位置会显示一个“A”
之前增加一个 Delay(500);//延时500ms
来判断这个不正常的状况,是否有“WriteChar(5,1,'A'); ”
的影响因素

热点排行