proteus仿真ds1302的显示问题

2019-07-15 15:58发布

我用proteus仿真的ds1302,用数码管显示,本身应该每60秒一清零,但是却变成了99秒一清零,分钟也不对,不只是哪里的问题,请大侠们帮小弟看看,在这里先谢过了。
#include <AT89X52.H>
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
uchar code duanma[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0~9段码,共阴极
sbit S1=P3^0;         //小时调整按键
sbit S2=P3^1;         //分钟调整按键
sbit S3=P3^2;         //秒钟调整按键
uchar hour;      //小时计数变量
uchar minute;         //分钟计数变量
uchar second;         //秒钟计数变量
uchar isr_time;  //50中断次数计数器
/************************************
  初始化子函数
  入口参数:无
  出口参数:无
************************************/
void init(void)
{
        //hour=12;                //初始化时的时间是12点整
        //minute=0;
        //second=0;
        P3=0xff;
        P2=0x00;
        //TMOD=0x01;           //使用定时器0的模式1
        //TH0=0x3c;           //定时50ms
        //TL0=0xb0;
        //ET0=1;
        //TR0=1;
        //EA=1;
}
/************************************
  5ms*x定时子函数
  入口参数:无
  出口参数:无
************************************/
void delay_5ms(uchar m)
{
        uchar i,j,l;
        for(j=m;j>0;j--)
                {
                        for(i=10;i>0;i--)
                        {
                                for(l=247;l>0;l--)
                                ;
                        }
                                
                }
}
/************************************
  1ms*x定时子函数
  入口参数:无
  出口参数:无
************************************/
void delay_1ms(uchar m)
{
        uchar i,j,l;
        for(j=m;j>0;j--)
                {
                        for(i=2;i>0;i--)
                        {
                                for(l=247;l>0;l--)
                                ;
                        }
                                
                }
}
/************************************
  显示小时子函数
  入口参数:h
  出口参数:无
************************************/
void display_xiaoshi(uchar h)
{
                P2=0x00;                        //显示小时的十位
                P0=duanma[h/10];
                delay_1ms(1);

                P2=0x01;                        //显示小时的个位
                P0=duanma[h%10];
                delay_1ms(1);

                P2=0x02;                        //显示-
                P0=0x40;
                delay_1ms(1);

                P2=0x0f;            //关闭所有数码管
}
/************************************
  显示分钟子函数
  入口参数:m
  出口参数:无
************************************/
void display_fenzhong(uchar m)
{
                P2=0x03;                        //显示分钟的十位
                P0=duanma[m/10];
                delay_1ms(1);

                P2=0x04;                        //显示个的个位
                P0=duanma[m%10];
                delay_1ms(1);

                P2=0x05;                        //显示-
                P0=0x40;
                delay_1ms(1);

                P2=0x0f;            //关闭所有数码管
}
/************************************
  显示秒钟子函数
  入口参数:s
  出口参数:无
************************************/
void display_miaozhong(uchar s)
{
                P2=0x06;                        //显示秒钟的十位
                P0=duanma[s/10];
                delay_1ms(1);

                P2=0x07;                        //显示秒的个位
                P0=duanma[s%10];
                delay_1ms(1);

                P2=0x0f;            //关闭所有数码管
}


void main(void)
{
        init();
        while(1)
        {
                second=DS1302Read( 0x81 );
                minute=DS1302Read( 0x83 );
                hour=DS1302Read( 0x85 );
                second &= 0x7f;
                minute &= 0x7f;
                hour &=0x1f ;
                display_xiaoshi( hour );
                display_fenzhong(minute );
                display_miaozhong(second );
        }

}

RTX截图未命名.png
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
in2004
1楼-- · 2019-07-15 17:19
你这程序不透明,对ds1302操作的部分你都打包在头文件里了,谁知道问题出在哪呢?ds1302的时序对了才有可能读到数据,'才谈得上显示时间。
lyzsml
2楼-- · 2019-07-15 18:02
谢谢in2004,我把对ds1302的操作部分给传上来,这个是从网上下载的。
#include <at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit RST=P1^0;
sbit SCLK=P1^1;
sbit SDA=P1^2;

/************************************************
*名称:DS1302WriteByte
*说明:无
*功能:写入8bit数据
*调用:delayus()
*输入:dat:要写入的数据
*输出:无
*************************************************/
void DS1302WriteByte(uchar dat)
{
        uchar i;
        SCLK=0;//初始时钟线置为0
        //delay_us(2);
        for(i=0;i<8;i++)//开始传输8个字节的数据
        {
                SDA=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
                //delay_us(2);
                SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输
                //delay_us(2);
                SCLK=0;//时钟线拉低,为下一个上升沿做准备
                dat>>=1;//数据右移一位,准备传输下一位数据
        }
}
/************************************************
*名称:DS1302ReadByteDS1302ReadByte()()
*说明:无
*功能:读取8bit的数据
*调用:delayus()
*输入:无
*输出:dat:读取的数据
*************************************************/
uchar DS1302ReadByte()
{
        uchar i,dat;
        //delay_us(2);
        for(i=0;i<8;i++)
        {
                dat>>=1;//要返回的数据左移一位
                if(SDA==1)//当数据线为高时,证明该位数据为1
                        dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
                SCLK=1;//拉高时钟线
                //delay_us(2);
                SCLK=0;//制造下降沿
                //delay_us(2);
        }
        return dat;//返回读取出的数据
}
/************************************************
*名称:ucharDS1302Read()
*说明:先写地址,后读数据
*功能:从cmd相应地址中读取一个字节的数据
*调用:DS1302WriteByte(),DS1302ReadByte()
*输入:cmd:要写入的控制字节
*输出:dat:读取的数据
*************************************************/
uchar DS1302Read(uchar cmd)
{
        uchar dat;
        RST=0;//初始CE线置为0
        SCLK=0;//初始时钟线置为0
        RST=1;//初始CE置为1,传输开始
        DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址
        dat=DS1302ReadByte();//读取要得到的时间/日期
        SCLK=1;//时钟线拉高
        RST=0;//读取结束,CE置为0,结束数据的传输
        return dat;//返回得到的时间/日期
}
/************************************************
*名称:DS1302Write
*说明:先写地址,后写数据
*功能:向cmd相应地址中写一个字节的数据
*调用:DS1302WriteByte()
*输入:cmd:要写入的控制字,dat:要写入的数据
*输出:无
*************************************************/
void DS1302Write(uchar cmd,uchar dat)
{
        RST=0;//初始CE线置为0
        SCLK=0;//初始时钟线置为0
        RST=1;//初始CE置为1,传输开始
        DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
        DS1302WriteByte(dat);//写入要修改的时间/日期
        SCLK=1;//时钟线拉高
        RST=0;//读取结束,CE置为0,结束数据的传输
}
哇咔咔32
3楼-- · 2019-07-15 20:31
 精彩回答 2  元偷偷看……
lyzsml
4楼-- · 2019-07-15 22:15
我后来调整程序发现是ds1302操作时出的问题,但是就不知道怎么才能正常。
lyzsml
5楼-- · 2019-07-16 00:19
原来程序也没问题,而是读取的数没有进行转换,所以才出现错误。

一周热门 更多>