DS1302时钟LCD1602显示,proteus7和8的仿真都有
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- //调用1602显示驱动,在此文件内已包含51头文件和定义数据类型
- #include "LCD1602.h"
- /*====================================
- IO接口定义
- ====================================*/
- sbit TSCLK = P1^1; //时钟
- sbit TIO = P1^0; //数据
- sbit TRST = P1^2; //使能
- #define MAIN_Fosc 11059200UL //宏定义主时钟HZ
- #define DS1302_W_ADDR 0x80 //写时钟日历寄存器起始地址
- #define DS1302_R_ADDR 0x81 //读时钟日历寄存器起始地址
- //时钟日历暂存数组,秒、分、时、日、月、周、年
- uchar TimeData[7]={0, 0, 0, 0, 0, 0, 0};
- /*=================================================
- *函数名称:Delay_Ms
- *函数功能:12T 51单片机自适应主时钟毫秒级延时函数
- *说明:需定义MAIN_Fosc(晶振主频单位HZ)
- *输入:ms:要延时的毫秒
- =================================================*/
- void Delay_Ms(INT16U ms)
- {
- INT16U i;
- do{
- i = MAIN_Fosc / 96000;
- while(--i); //96T per loop
- }while(--ms);
- }
- /*=================================================
- *函数名称:DS1302_W_Byte
- *函数功能:DS1302写一字节数据
- *输入:dat:要写入的数据
- =================================================*/
- void DS1302_W_Byte(uchar dat)
- {
- uchar i;
- for(i = 0; i < 8; i++) //每次写1bit,写8次
- {
- TSCLK = 0; //拉低时钟总线
- TIO = dat & 0x01; //从一字节最低位开始写
- TSCLK = 1; //拉高时钟总线,DS1302把数据读走
- dat >>= 1; //数据右移一位
- }
- }
- /*=================================================
- *函数名称:DS1302_R_Byte
- *函数功能:DS1302读一字节
- *输出:dat:读取的数据
- =================================================*/
- uchar DS1302_R_Byte()
- {
- uchar i, dat;
- for(i = 0; i < 8; i++) //每次写1bit,写8次
- {
- TSCLK = 0; //拉低时钟总线,DS1302把数据放到数据总线上
- dat >>= 1; //数据右移一位,数据从最低位开始读
- if(TIO) dat |= 0x80;//读取数据
- TSCLK = 1; //拉高时钟总线
- }
- return dat; //返回读取的数据
- }
- /*=================================================
- *函数名称:DS1302_W_DAT
- *函数功能:写DS1302数据一次写2个字节
- *说明:先写命令后写数据
- *调用:DS1302_W_Byte()
- *输入:cmd:需要写的命令 ,dat:需要些的数据
- =================================================*/
- void DS1302_W_DAT(uchar cmd, uchar dat)
- {
- TRST = 0; //拉低使能端
- TSCLK = 0; //拉低数据总线
- TRST = 1; //拉高使能端,开始写数据
- DS1302_W_Byte(cmd); //写命令
- DS1302_W_Byte(dat); //写数据
- }
- /*=================================================
- *函数名称:DS1302_R_DAT
- *函数功能:读DS1302数据
- *说明:先写入命令字节后读出对应数据
- *调用: DS1302_W_Byte();DS1302_R_Byte();
- *输入: cmd:需要写的命令
- *输出: dat:读出的数据
- =================================================*/
- uchar DS1302_R_DAT(uchar cmd)
- {
- uchar dat;
- TRST = 0; //拉低使能端
- TSCLK = 0; //拉低数据总线
- TRST = 1; //拉高使能端,开始写数据
- DS1302_W_Byte(cmd); //写命令
- dat = DS1302_R_Byte(); //读出数据
- return dat; //返回读出数据
- }
- /*=================================================
- *函数名称:DS1302_Clear_WP
- *函数功能:清除DS1302写保护
- *说明:先写入命令0x8e(写控制寄存器)接着向该寄存器写0
- *调用:DS1302_W_DAT()
- =================================================*/
- void DS1302_Clear_WP()
- {
- DS1302_W_DAT(0x8e,0x00); //把控制寄存器WP位置0
- }
- /*=================================================
- *函数名称:DS1302_Clear_WP
- *函数功能:设置DS1302写保护
- *说明:先写入命令0x8e(写控制寄存器)接着向该寄存器写0x80
- *调用:DS1302_W_DAT()
- =================================================*/
- void DS1302_Set_WP()
- {
- DS1302_W_DAT(0x8e,0x80); //把控制寄存器WP位置1
- TRST = 0; //拉低使能端
- TSCLK = 0; //拉低数据总线
- }
- /*=================================================
- *函数名称:Read_DS1302_Time
- *函数功能:读取DS1302时钟数据
- *说明: 读取DS1302时钟数据 返回数据存入时钟日历暂存
- 数组TimeData(数据格式BCD码)
- *调用:DS1302_Clear_WP();DS1302_R_DAT();DS1302_Set_WP();
- *输入: addr:需要读取时钟日历寄存器的起始地址
- =================================================*/
- void Read_DS1302_Time(uchar addr)
- {
- uchar i;
- DS1302_Clear_WP(); //清楚些保护
- for(i = 0; i < 7; i++) //从DS1302读取7个字节的时钟日历数据
- {
- TimeData[i] = DS1302_R_DAT(addr);//先写入要读取数据的寄存器起始地址,再读出数据存入TimeData数组
- addr += 2; //时钟日历寄存器地址+2转向下一个寄存器
- }
- DS1302_Set_WP(); //开起写保护
- }
- /*=================================================
- *函数名称:main
- *函数功能:主函数 1602液晶显示DS1302数据
- Date:年-月-日-星期
- Time:时:分:秒
- =================================================*/
- void main()
- {
- InitLcd1602(); //1602初始化
- LcdShowStr(0,0,"Date:"); //1602显示字符串
- LcdShowStr(0,1,"Time:"); //1602显示字符串
- while(1)
- {
- Read_DS1302_Time(DS1302_R_ADDR); //先写入时钟日历寄存器起始地址再读出时钟日历写入到TimeData数组中
- DisplayOneStr (5,0,TimeData[6]); //年
- DisplayOneChar (7,0,'-'); //-
- DisplayOneStr (8,0,TimeData[4]); //月
- DisplayOneChar (10,0,'-'); //-
- DisplayOneStr (11,0,TimeData[3]);//日
- DisplayOneStr (5,1,TimeData[2]); //时
- DisplayOneChar (7,1,':'); //:
- DisplayOneStr (8,1,TimeData[1]); //分
- DisplayOneChar (10,1,':'); //:
- DisplayOneStr (11,1,TimeData[0]);//秒
- Delay_Ms(1000); //延时1秒
- }
- }
复制代码
Keil代码与Proteus仿真下载:
DS1302时钟LCD1602不带星期.zip
(95.21 KB, 下载次数: 58)
|