原创 试验板之DS1302驱动-LCD显示

2007-1-3 00:05 5167 7 9 分类: MCU/ 嵌入式



以下是驱动DS1302并用LCD显示的代码。

/*********************************************************
模块名称:DS1302+LCD试验模块
创 建 人:ZHCE  
创建日期:2005年10月18日
功能描述:LCD演示
说    明:此模块在试验板1.0上验证通过,晶振使用11.0592M
*********************************************************/

#include <REGX51.H>

typedef unsigned char uchar;
typedef unsigned int  uint;

//定义LCD引脚
#define LCD_RS   P2_0            //定义RS引脚。寄存器选择脚,1是数据;0是命令
#define LCD_RW   P2_1            //定义引脚    读写操作选择,1读  0写
#define LCD_E    P2_2            //定义使能脚  使能信号
#define LCD_Data P0                  //数据总线


//定义DS1302引脚
#define DS_CLK   P1_0            //定义DS1302 时钟输入端口
#define DS_DAT   P1_1            //定义DS1302 串行数据输入输出端口(双向)
#define DS_RST   P1_2            //定义DS1302 复位/片选端口
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
unsigned char inittime[7]={0x06,0x10,0x12,0x27,0x03,0x07,0x05};

uchar code CG[]={
                 0x08, 0x1f, 0x02, 0x0f, 0x0a, 0xff, 0x02, 0x00, // 年
                 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x09, 0x13, 0x00, // 月
                 0x0f, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x0f, 0x00, // 日
                       
               } ;

void  initlcd(void);
void  delay(uint n);
void  WriteCommand(uchar cmd,busyflag);
void  WriteData(uchar Data);
uchar Readlcdstatus(void);
void  DisplayOneChar(uchar X, uchar Y, uchar s);
void  lcdpos(uchar XPOS,uchar YPOS);
void  DisplayChar(uchar X,uchar Y,uchar *s);
void  lcdfill(uchar s);

uchar DS1302Read(uchar address);
void  DS1302Write(uchar address,uchar number);

main()
{
  uchar sec;
  P1_5=1;                                    //允许LCD的RS RW E输出
  P1_6=0;                                    //关闭继电器输出,防止数据输出时影响继电器
  initlcd();                              //液晶初始化
  DisplayChar(0,0,"DS1302 CLOCK DEMO");
/*  delay(62000);
  DisplayChar(0,1,"QRSTUVWXYZ+-{}");
  delay(62000);
  lcdfill(' ');
 
  WriteCommand(0x40,1);//第二行
  for (j=0;j<24;j++)
  {
     WriteData(CG[j]);
  }      
  WriteCommand(0x80,1);//第二行
  WriteData(0x00);
  WriteData(0x01);
  WriteData(0x02);
  delay(62000);*/

  DS1302Write(0x8E,0x00);//取消写保护
  DS1302Write(0x80,0x00);
  DS1302Write(0x8E,0x80);//写保护
//Set1302(inittime);
//  if (DS1302Read(0x81)==0x80&&DS1302Read(0x83)==0x00) {DS1302Write(0x80,0x00);}    //如果分和秒都为初始状态,则初始化1302,开始走时  
  while(1)
  {
  sec="DS1302Read"(0x85);
  DisplayOneChar(0,1,sec/16+0x30);
  DisplayOneChar(1,1,sec%16+0x30);

  sec="DS1302Read"(0x83);
  DisplayOneChar(3,1,sec/16+0x30);
  DisplayOneChar(4,1,sec%16+0x30);
 
  sec="DS1302Read"(0x81);
  DisplayOneChar(6,1,sec/16+0x30);
  DisplayOneChar(7,1,sec%16+0x30);
 
  }


}


/*********************************************************
//  delay(255);            //当参数为char时时间为0.55881ms  参数
为整形时时间为2.22005ms,基本上相当于4倍
//  delay(100);            //0.22244ms         0.87457ms
//  delay(200);            //0.43945ms
//  delay(1);            //3.26us
*********************************************************/
void delay(uint n)
{
while(--n);
}


/********************************************************
函数名称:液晶模块初始化函数
功能描述:LCD初始化
全局变量:无
参数说明:无
返回说明:无
设 计 人:ZHCE
版    本:1.0
说    明:在实际使用中延时可以短一些,实验中曾经使用38M晶
振,程序依然很好运行。
---------------------------------------------------------
初始化设置命令,0 0 1 DL N F * *  
DL=1 8位数据接口 DL="04位数据接口":
N=1 二行显示     N="0一行显示"
F=1 5*10点阵显示 F="05"*7点阵显示
---------------------------------------------------------
显示开关控制命令:0 0 0 0 1 D C B
D:表示显示开关 D="1开"  D=0关
C:光标显示开关 C="1开"  C=0关
B:表示闪烁开关 B="1开"  B=0关
---------------------------------------------------------
输入方式设置命令:0 0 0 0 0 1 N S
N=1:数据读写后,地址指针自动加1,且光标加1
N=0:数据读写后,地址指针自动减1,且光标减1
S=1:数据读写操作,显示屏左移(N=1)或右移(N=0),以得到光标不
动,而屏幕移动的效果。
S=0:当写一个字符,整屏不动
********************************************************/
void initlcd(void)
{
  /*延时15ms以上*/
  delay(2500);                        //延时15ms
  WriteCommand(0x3c,0);            //初始化设置,8位数据接口模式,两行显示,5*7点阵字符:
  delay(600);                        //延时5ms以上
  WriteCommand(0x3C,0);
  delay(600);                        //延时5ms以上
  WriteCommand(0x3C,0);
  delay(100);
  WriteCommand(0x3c,1);            
  //WriteCommand(0x06,1);            //显示关,光标不显示,不闪烁
  WriteCommand(0x01,1);            //清屏
  WriteCommand(0x06,1);            //屏幕不动,光标加1
  WriteCommand(0x0c,1);            //显示开,光标关
}


/********************************************************
函数名称:液晶模块写指令函数
功能描述:向LCD写入指令
全局变量:无
参数说明:cmd:命令字  busyflag:忙检测,0不检测 1检测
返回说明:无
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
void WriteCommand(uchar cmd, busyflag)
{
  if(busyflag) Readlcdstatus();            //检测忙标志
  LCD_RS=0;LCD_RW=0;LCD_E =1;            //使能LCD命令输送
  delay(1);                                          //短暂延时
  LCD_Data=cmd;                                    //送出命令值
  LCD_E=0;                                          //关闭LCD使能

}


/********************************************************
函数名称:液晶模块写数据函数
功能描述:向LCD写入数据
全局变量:无
参数说明:data:写入的数据
返回说明:无
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
void WriteData(uchar Data)
{
  Readlcdstatus();
  LCD_RS=1;  LCD_RW=0;            //设置为数据输入状态
  LCD_Data=Data;                  //送入数据
  LCD_E =1;                              //使能LCD
  delay(1);                              //短暂延时
  LCD_E=0;                              //关闭LCD使能
}


/********************************************************
函数名称:读LCD忙状态函数
功能描述:读取LCD状态
全局变量:无
参数说明:无
返回说明:返回LCD数据,类型是UCHAR
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
uchar Readlcdstatus(void)
{
  LCD_Data=0XFF;                        //
  LCD_RS=0;  LCD_RW=1;                  //设置LCD为读取数据状态
  LCD_E= 1;                                    //使能LCD
  while((LCD_Data&0x80)==0x80);      //检测忙
  LCD_E=0;                                    //关闭使能
  return(LCD_Data);                        //返回LCD数据
}

/********************************************************
函数名称:按指定位置显示一个字符
功能描述:按指定位置显示一个字符
全局变量:无
参数说明:X行  Y列  S显示字符
返回说明:无
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
void DisplayOneChar(unsigned char X, unsigned char Y, uchar s)
{
   lcdpos(X,Y);                        //根据参数定位
   WriteData(s);                  //写入字符数据
}

/********************************************************
函数名称:定位函数
功能描述:定位函数
全局变量:无
参数说明:X行  Y列
返回说明:无
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
void lcdpos(uchar XPOS,uchar YPOS)
{  XPOS&=0x0f;
   YPOS&=0x03;
   if(YPOS==0x00)
      WriteCommand(XPOS|0x80,1);
   else if(YPOS==0x01)
      WriteCommand((XPOS+0x40)|0x80,1);
}

/********************************************************
函数名称:按指定位置显示一个字符串
功能描述:按指定位置显示一个字符串
全局变量:无
参数说明:X行  Y列  S显示字符串
返回说明:无
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
void DisplayChar(uchar X,uchar Y,uchar *s)
{
   uchar XPOS;  
   for(XPOS=X;XPOS<16;XPOS++)
   {  lcdpos(XPOS,Y);
      WriteData(*s);
      s++;
   }
}

/********************************************************
函数名称:用某一字符全屏填充屏幕
功能描述:用某一字符全屏填充屏幕
全局变量:无
参数说明:S填充字符
返回说明:无
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
void lcdfill(uchar s)
{
   uchar XPOS,YPOS;
   for(YPOS=0;YPOS<2;YPOS++)
      for(XPOS=0;XPOS<16;XPOS++)
      {  lcdpos(XPOS,YPOS);
         WriteData(s);  }
}


/********************************************************
函数名称:DS1302单字节写函数
功能描述:读取某一地址的数据
全局变量:无
参数说明:address为地址变量;number为所送的数据
返回说明:返回指定地址的数据
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
uchar DS1302Read(uchar address)
{
  uchar i;
  DS_CLK=0;                                                //复位各脚
  DS_DAT=0;
  DS_RST=0;
  DS_RST=1;                                                //允许读写数据
  for (i=8;i>0;i--)                                    //地址输入,8位
  {
    DS_CLK=0;                                          //上升沿数据输入
    DS_DAT=address&0x01;                        //送出一位数据
    address>>=1;                                    //右移一位
     DS_CLK=1;                                          //上升沿
  }
 
  for (i=8;i>0;i--)                                    //数据读出
  {
    DS_CLK=0;                                          //下降沿数据读出
     address>>=1;                                    //把数据右移
     if (DS_DAT)      address=address|0x80;      //读取数据
    DS_CLK=1;                                          
     DS_CLK=1;
  }
                                                           //时钟置高位
  DS_CLK=1;                                                //片选无效
  DS_RST=0;
  return(address);
}


/********************************************************
函数名称:DS1302单字节写函数
功能描述:读取某一地址的数据
全局变量:无
参数说明:address为地址变量;number为所送的数据
返回说明:返回指定地址的数据
设 计 人:ZHCE
版    本:1.0
说    明:
********************************************************/
void DS1302Write(uchar address,uchar number)
{
  uchar i;
  DS_CLK=0;
  DS_DAT=0;
  DS_RST=0;
  DS_RST=1;
  /*地址输入*/
  for (i=16;i>0;i--)
  {
     DS_CLK=0;
    if (i>8)
     {
       DS_DAT=address&0x01;
      address="address">>1;
     }
     else
     {
       DS_DAT=number&0x01;
      number>>=1;
     }
    DS_CLK=1;
  }

  DS_CLK=1;
  DS_RST=0;
}

文章评论2条评论)

登录后参与讨论

用户23556 2008-1-8 21:32

资料很好,太感谢了

用户15267 2007-11-6 16:54

我也刚刚用LCD和DS1302做了个电子钟,程序下进去后运行正常,但是将电源拔掉后再上电,LCD就不显示任何东西了,然后再进行仿真也不行。好像死机了一样,要用另外的LCD试验程序下进去,LCD才能运行。这是怎么回事啊?请高手赐教

用户25737 2007-6-29 08:25

不错,就是缺少调节功能和显示年月日。
相关推荐阅读
用户70812 2010-12-16 17:20
准备要学习STM32了
形势所迫,要学习STM32了,初步看了看,不好学呀...
用户70812 2010-06-13 14:56
SQL SERVER 中IP地址的排序方法
最近在编写一个IP管理的web,要用到IP地址的排序问题,存储IP地址的字段为字符型的,当直接排序时,IP地址按字符的方式排序,无法得到正确的IP地址排序,经过查找资料,采用如下语句即可实现IP地址的...
用户70812 2010-05-31 09:06
三极管与数字电路
下面两张图片源自21ic,论坛上richardnee的帖子,作为资料收藏一下...
用户70812 2010-02-19 14:03
英语主语格式变化
主格          形容词性物主代词    宾格   名词性物主代词I                         my                      me            ...
用户70812 2009-12-22 15:27
线性稳压器工作原理及其补偿
网上找到的资料:...
用户70812 2009-12-12 22:51
中断方式数码管显示的演示实例
在一个论坛回答别人的提问的时候的回帖,放在这里,程序很简单,需要的就看看,也欢迎多指教。/*******************************************************...
我要评论
2
7
关闭 站长推荐上一条 /2 下一条