1602驱动不了求助

2019-07-15 20:33发布


//sbit RSPIN   = P2^2;                    //RS对应单片机引脚
//sbit RWPIN   = P2^1;                    //RW对应单片机引脚
//sbit EPIN    = P2^0;                    //E对应单片机引脚
//-------------------------------------------------------------------------------

/*****************************************
** 1602A液晶屏驱动程序
** 晶 振  频 率:11.0592M
*****************************************/
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int

sbit LCM_E=P2^0;//定义接口
sbit LCM_RW=P2^1;
sbit LCM_RS=P2^2;

#define LCM_Data P0//数据接口

void LCM_WriteData(uchar WDLCM);
void LCM_WriteCommand(uchar WCLCM,BuysC);
uchar LCM_ReadData(void);
uchar LCM_ReadStatus(void);
void LCM_Init(void);
void DisplayOneChar(uchar X, uchar Y, uchar DData);
void DisplayListChar(uchar X, uchar Y, uchar code *DData);
void Delay5Ms(void);
void Delay400Ms(void);

uchar code uctech[] = {"1602A"};
uchar code net[] = {"www.52c51.com"};

void main(void)
{
Delay400Ms();//启动等待,等LCM讲入工作状态
LCM_Init();//LCM初始化
Delay5Ms();//延时片刻(可不要)

DisplayListChar(6, 1, uctech);
DisplayListChar(0, 0, net);
//LCM_ReadData();//测试用句无意义
//LCM_Data=255;
while(1);
}

/****************************1602A写数据函数**************************/
/*函数原型:void LCM_WriteData(uchar WDLCM)
/*函数功能:1602A写数据
/*输入参数:要写入的数据
/*输出参数:无
/*调用模块:
/**********************************************************************/

void LCM_WriteData(uchar WDLCM)
{
LCM_ReadStatus();//检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 1;//若晶振速度太高可以在这后加小的延时
Delay5Ms();
LCM_E = 0;
}

/****************************1602A写指令函数**************************/
/*函数原型:void LCM_WriteCommand(uchar WCLCM,BuysC)
/*函数功能:1602A写指令
/*输入参数:要写入的指令
/*输出参数:无
/*调用模块:
/**********************************************************************/

void LCM_WriteCommand(uchar WCLCM,BuysC)//BuysC为0时忽略忙检测
{
if (BuysC) LCM_ReadStatus();//根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 1;
Delay5Ms();
LCM_E = 0;
}

/****************************1602A读数据函数**************************/
/*函数原型:uchar LCM_ReadData(void)
/*函数功能:1602A读数据
/*输入参数:无
/*输出参数:1602A返回的数据
/*调用模块:
/**********************************************************************/

uchar LCM_ReadData(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 1;
Delay5Ms();
LCM_E = 0;
return(LCM_Data);
}

/****************************1602A读状态函数**************************/
/*函数原型:uchar LCM_ReadData(void)
/*函数功能:1602A读状态
/*输入参数:无
/*输出参数:1602A返回的状态
/*调用模块:
/**********************************************************************/

uchar LCM_ReadStatus(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 1;
Delay5Ms();
LCM_E = 0;
while (LCM_Data & 0x80);//检测忙信号
return(LCM_Data);
}

/****************************1602A初始化函数**************************/
/*函数原型:void LCM_Init(void)
/*函数功能:1602A初始化
/*输入参数:无
/*输出参数:无
/*调用模块:
/**********************************************************************/

void LCM_Init(void)
{
LCM_Data = 0;
LCM_WriteCommand(0x38,0);//三次显示模式设置,不检测忙信号
Delay5Ms();
LCM_WriteCommand(0x38,0);
Delay5Ms();
LCM_WriteCommand(0x38,0);
Delay5Ms();

LCM_WriteCommand(0x38,1);//显示模式设置,开始要求每次检测忙信号
LCM_WriteCommand(0x08,1);//关闭显示
LCM_WriteCommand(0x01,1);//显示清屏
LCM_WriteCommand(0x06,1);// 显示光标移动设置
LCM_WriteCommand(0x0C,1);// 显示开及光标设置
}

/******************1602A按指定位置显示一个字符函数**********************/
/*函数原型:void DisplayOneChar(uchar X, uchar Y, uchar DData)
/*函数功能:1602A按指定位置显示一个字符
/*输入参数:X坐标 Y坐标 要显示的字符
/*输出参数:无
/*调用模块:
/**********************************************************************/

void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
Y &= 0x1;
X &= 0xF;//限制X不能大于15,Y不能大于1
if (Y) X |= 0x40;//当要显示第二行时地址码+0x40;
X |= 0x80;// 算出指令码
LCM_WriteCommand(X, 0);//这里不检测忙信号,发送地址码
LCM_WriteData(DData);
}

/*******************1602A按指定位置显示一串字符函数*********************/
/*函数原型:void DisplayListChar(uchar X, uchar Y, uchar code *DData)
/*函数功能:1602A按指定位置显示一个字符
/*输入参数:X坐标 Y坐标 要显示字符串的首地址
/*输出参数:无
/*调用模块:
/**********************************************************************/

void DisplayListChar(uchar X, uchar Y, uchar code *DData)
{
uchar 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)
/*函数功能:5ms延时
/*输入参数:无
/*输出参数:无
/*调用模块:
/**********************************************************************/

void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}

/********************400ms延时延时函数************************/
/*函数原型:void Delay400Ms(void)
/*函数功能:400ms延时延时
/*输入参数:无
/*输出参数:无
/*调用模块:
/**********************************************************************/

void Delay400Ms(void)
{
uchar TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
1504415944
1楼-- · 2019-07-15 21:01
/**
*
*   main.c
*
*   Mcu         : STC12C5608AD
*   Freq        : 12M
*   Compiler    : Keil C51 v9.03
*   Version     : 1.0
*   Created on  : 2011-08-08
*   Author      : etuMCU.taobao.com
*       
*        Note        : 这个例子我们演示如何用字符液晶LCD1602
*               : 1602液晶可以用来显示数字或者字母,是常用的显示器件
*
*                                : 硬件连接:
*                 1. 1602的RS、R/W、E引脚分别接到单片机的P1.3、P1.4、P1.5端口
*                 2. 1602的数据端口接到单片机的P2端口

*
**/


#include "STC12C5620AD.H"   // 加载STC12C56系列头文件,头文件要放在工程文件夹内
#include <intrins.h>        // 加载头文件,此头文件内含_nop_()函数


sbit Buzzer = P3^4;         // 定义I/O P3.4为Buzzer,增加程序可读性
sbit LED_9        = P3^5;

sbit SDI    = P1^5;
sbit SS     = P1^4;
sbit SCLK   = P1^7;

/* 定义LCD1602驱动端口,详情请查阅原理图 */

#define LCD_DATA        P2                //单片机写1602的数据端口

sbit LCD_RS   = P1^3;
sbit LCD_RW          = P1^4;
sbit LCD_EN          = P1^5;
sbit LCD_BUSY = P2^7;

//----------------------------------------------------------------------------------------
// 函数名        : _delay_us
// 功  能        : 一个粗略的微秒级延时函数
// 输入值        : i,要延时的时间,单位是us
// 输出值        : 无
// 返回值        : 无
// 版  本        : 1.0
// 作  者        : 一优电子
// 日  期   : 2011-08-08
//----------------------------------------------------------------------------------------
void _delay_us(unsigned int i)
{
        while(i--)              
        {
                _nop_();  
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
        }
}
//----------------------------------------------------------------------------------------
// 函数名        : _delay_ms
// 功  能        : 一个粗略的毫秒级延时函数
// 输入值        : i,要延时的时间,单位是毫秒
// 输出值        : 无
// 返回值        : 无
// 版  本        : 1.0
// 作  者        : 一优电子
// 日  期   : 2011-08-08
//----------------------------------------------------------------------------------------
void _delay_ms(unsigned int i)
{
        while(i--)
        {
                _delay_us(1000);
        }
}

void LCD1602_status(void)
{
        unsigned int timeout_loop = 1;                                // 超时变量

        LCD_BUSY = 1;                           // 向P2.7端口写“1”,为读液晶状态做准备
       
       
        LCD_RS = 0;                                        // RS = 0;
        LCD_RW = 1;                                        // RW = 1
        LCD_EN = 0;                                         // EN = 0;

        _delay_us(5);
        LCD_EN = 1;                                         // EN = 1;
        _delay_us(5);


        while ((LCD_BUSY == 1) && (timeout_loop != 0))        //判断LCD1602是否忙,加入一个简单的超时判断
        {                                                                                                //当timeout_loop == 0时,无论是否读到LCD1602
                timeout_loop++;                                                                //状态均退出该循环,防止系统死锁在此处。
        }

        LCD_EN = 0;                                         //EN = 0;
}

//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_write_byte
// 功  能        : 向1602写入数据
// 输入值        : dat,Busy
// 输出值        : 无
// 返回值        : 无
// 说  明        : dat:要写入的数据,Busy=1,需要检查LCD忙,Busy=0不需要
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_write_byte(unsigned char dat, unsigned char Busy)
{
       
        if (Busy)
        {
                LCD1602_status();
                Busy = 0;
        }
               
        LCD_RS = 1;                //RS = 1;
        LCD_RW = 0;                //RW = 0;
        LCD_EN = 1;                //EN = 1;

        LCD_DATA = dat;
        _delay_us(5);
        LCD_EN = 0;                //EN = 0;
}
//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_write_CMD
// 功  能        : 向1602写入命令
// 输入值        : command,Busy
// 输出值        : 无
// 返回值        : 无
// 说  明        : command:要写入的命令,Busy=1,需要检查LCD忙,Busy=0不需要
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_write_CMD(unsigned char command, unsigned char Busy)
{

        if (Busy)
        {
                LCD1602_status();
                Busy = 0;
        }

       
       
        LCD_RS = 0;                //RS = 0;
        LCD_RW = 0;                //RW = 0;
        LCD_EN = 1;                //EN = 1;       
       
        LCD_DATA = command;
    _delay_us(5);
        LCD_EN = 0;                //EN = 0;
}

//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_clean
// 功  能        : 清屏
// 输入值        : 无
// 输出值        : 无
// 返回值        : 无
// 说  明        : 无
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_Clean(void)
{
        LCD1602_write_CMD(0x01, 1);                               
}

//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_write_char
// 功  能        : 向指定位置写入一个字符
// 输入值        : x, y, data
// 输出值        : 无
// 返回值        : 无
// 说  明        : x:第x列;y:第y行;dat:要写入的字符
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_write_char(unsigned char x, unsigned char y, unsigned char dat)
{
        x &= 0x0F;                                                                //每行最多显示16个字符
        y &= 0x01;                                                                //最多只能显示两行。

        x += 0x80;
        if (y)
        {
                x += 0x40;
        }

        LCD1602_write_CMD(x, 1);
        LCD1602_write_byte(dat, 1);

}

//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_write_str
// 功  能        : 向指定位置写入一个字符串
// 输入值        : x, y, data
// 输出值        : 无
// 返回值        : 无
// 说  明        : x:第x列;y:第y行;sdata:要写入的字符串
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_write_str(unsigned char x,unsigned char y,char *sdata)
{
        x &= 0x0F;
        y &= 0x01;

        x |= 0x80;
        if (y)
        {
                x |= 0x40;
        }

        LCD1602_write_CMD(x, 1);

        while (*sdata != '')
        {
                LCD1602_write_byte(*sdata++, 1);
        }
}

//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_write_number
// 功  能        : 向指定位置写入一个10进制数字
// 输入值        : x, y, data
// 输出值        : 无
// 返回值        : 无
// 说  明        : x:第x列;y:第y行;number:要写入的数字
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_write_number(unsigned char x, unsigned char y, unsigned char number)
{
        x &= 0x0F;
        y &= 0x01;

        x |= 0x80;
        if (y)
        {
                x |= 0x40;
        }

        LCD1602_write_CMD(x, 1);
        LCD1602_write_byte(number+48, 1);
}
//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_write_hexnum
// 功  能        : 向指定位置写入一个16进制数字
// 输入值        : x, y, hex
// 输出值        : 无
// 返回值        : 无
// 说  明        : x:第x列;y:第y行;hex:要写入的数字
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_write_hexnum(unsigned char x, unsigned char y, unsigned char hex)
{
        unsigned char a[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        unsigned char tem;
        x &= 0x0F;
        y &= 0x01;

        x |= 0x80;
        if (y)
        {
                x |= 0x40;
        }
        LCD1602_write_CMD(x, 1);

        tem = hex>>4;
        LCD1602_write_byte(a[tem],1);
        LCD1602_write_CMD(x+1, 1);
        tem = hex&0x0f;
        LCD1602_write_byte(a[tem],1);
}       

//-------------------------------------------------------------------------------------
// 函数名        : LCD1602_init
// 功  能        : LCD1602初始化函数
// 输入值        : 无
// 输出值        : 无
// 返回值        : 无
// 版  本        : 1.0
// 作  者        : 一优电子/etuMcu.taobo.com
// 日  期   : 2011-03-27
//-------------------------------------------------------------------------------------
void LCD1602_init(void)
{
        _delay_ms(15);
        LCD1602_write_CMD(0x38, 0);
        _delay_ms(5);
        LCD1602_write_CMD(0x38, 0);
        _delay_ms(5);
        LCD1602_write_CMD(0x38, 0);
        _delay_ms(5);
        LCD1602_write_CMD(0x38, 1);                                //设置16x2显示,5x7点阵,8bit数据接口
        LCD1602_write_CMD(0x08, 1);                                //关显示
        LCD1602_write_CMD(0x01, 1);                                //清屏
        LCD1602_write_CMD(0x06, 1);                                //写入新的数据后,光标右移,显示屏不移动
        LCD1602_write_CMD(0x0C, 1);                                //显示功能开,无光标,
        LCD1602_write_CMD(0x01, 1);                                //清屏
}

//----------------------------------------------------------------------------------------
// 函数名        : main
// 功  能        : 主函数
// 输入值        : 无
// 输出值        : 无
// 返回值        : 无
// 版  本        : 1.0
// 作  者        : 一优电子
// 日  期   : 2011-08-08
//----------------------------------------------------------------------------------------
void main(void)
{
        Buzzer = 0;                 // 噤声蜂鸣器
        LED_9  = 0;                                    // 关闭D9
               
        LCD1602_init();

        LCD1602_write_str(1, 0, "etuMCU.taobao");
        LCD1602_write_str(1, 1, ".com");
                              
        while(1)
        {
                ;
        }
}

这个是STC12C5608AD 开发板源码,你看看有帮助没有,参考一下吧
张大猛
2楼-- · 2019-07-16 02:40
 精彩回答 2  元偷偷看……
martin1800
3楼-- · 2019-07-16 05:58
网上下载个程序对比一下,这么长的程序估计没人帮你看,靠自己吧兄弟

一周热门 更多>