微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 1602驱动不了求助

1602驱动不了求助

时间:10-02 整理:3721RD 点击:

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

/**
*
*   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 != '\0')
        {
                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 开发板源码,你看看有帮助没有,参考一下吧

66666666666666666666666666666

你这个程序写的太复杂啦#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P3^4;
sbit rs=P3^5;
sbit rw=P3^6;       
sbit dula=P2^6;
sbit wela=P2^7;
uchar table1[]="I LOVE FREEDOM!";
uchar table2[]=" HOPE!";
void delay(uint x)
{
        uint a,b;
        for(a=x;a>0;a--)
                for(b=10;b>0;b--);
}
void delay1(uint x)
{
        uint a,b;
        for(a=x;a>0;a--)
                for(b=100;b>0;b--);
}
void write_com(uchar com)
{
        P0=com;
        rs=0;
        lcden=0;
        delay(10);
        lcden=1;
        delay(10);
        lcden=0;
       
}
void write_date(uchar date)
{
        P0=date;
        rs=1;
        lcden=0;
        delay(10);
        lcden=1;
        delay(10);
        lcden=0;
       
}
void init()
{
        rw=0;
        dula=0;
        wela=0;
        write_com(0x38);   //显示模式设置:16×2显示,5×7点阵,8位数据接口
        delay(20);
        write_com(0x0f);   //显示模式设置
        delay(20);
        write_com(0x06);   //显示模式设置:光标右移,字符不移
        delay(20);
        write_com(0x01);   //清屏幕指令,将以前的显示内容清除
        delay(20);       
}
void main()
{
        uchar a;
        init();
        write_com(0x80+17);         //将第一个字符写在向右偏移17个字符处,为后面的由右向左划入做准备。
        delay(20);
        for(a=0;a<14;a++)
        {
        write_date(table1[a]);
        delay(20);               
        }
        write_com(0xc0+17);
        delay(50);
        for(a=0;a<14;a++)
        {
        write_date(table2[a]);
        delay(40);               
        }
        for(a=0;a<16;a++)
        {
                write_com(0x18); //左移
                delay1(200);
        }
        while(1);
}
这个还行  简单

网上下载个程序对比一下,这么长的程序估计没人帮你看,靠自己吧兄弟

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top