以下是驱动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; } |
用户23556 2008-1-8 21:32
资料很好,太感谢了
用户15267 2007-11-6 16:54
我也刚刚用LCD和DS1302做了个电子钟,程序下进去后运行正常,但是将电源拔掉后再上电,LCD就不显示任何东西了,然后再进行仿真也不行。好像死机了一样,要用另外的LCD试验程序下进去,LCD才能运行。这是怎么回事啊?请高手赐教
用户25737 2007-6-29 08:25