使用1602液晶显示的c代码
2012-07-14
明皓
标签: 1602液晶

SMC1602A(16*2)模拟口线接线方式

连接线图:

  -------------------------------------------------

  |LCM-----51   | LCM-----51   | LCM------51      |

  |-------------|--------------|------------------|

  |DB0-----P1.0 | DB4-----P1.4 | RW-------P2.0    |

  |DB1-----P1.1 | DB5-----P1.5 | RS-------P2.1    |

  |DB2-----P1.2 | DB6-----P1.6 | E--------P2.2    |

  |DB3-----P1.3 | DB7-----P1.7 | VLCD接1K电阻到GND|

  -------------------------------------------------

[注:AT89S51使用12M晶振]

=============================================================*/

#include <at89x51.h>
#define LCM_RW P2_0//定义引脚 
#define LCM_RS P2_1
#define LCM_E P2_2
#define LCM_Data P1
#define Busy 0x80//用于检测LCM状态字中的Busy标识 
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[] = {"uctech.icpcn.com"};

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--);
    };
}


可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号