微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机+ds1302出现乱码,求助?

51单片机+ds1302出现乱码,求助?

时间:10-02 整理:3721RD 点击:
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define qw P1
uchar code tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x84,0x0E};// 显示段码值
uchar home[]={12,20,0}; //时分秒
uchar write_add[]={0x84,0x82,0x80};//时 分 秒 写寄存器地址
uchar read_add[]={0x85,0x83,0x81}; //时 分 秒 读寄存器地址
uchar disp[6];
uchar wei[]={0,1,2,3,4,5,6,7,};
uchar flng=0;//初始化标志位
sbit  SCLK = P1^6;              //实时时钟时钟线引脚
sbit  SDA  = P1^7;              //实时时钟数据线引脚
sbit  RST = P1^5;              //实时时钟复位线引脚
void  delayus(uchar a)            //延迟
{
    uchar i,j;
     for(i=0;i<a;i++)
      for(j=0;j<110;j++);
}
/************************************************
*名称: DS1302WriteByte
*说明: 无
*功能: 写入8bit数据
*调用: delayus()
*输入: dat:要写入的数据
*输出: 无
*************************************************/
void DS1302WriteByte(uchar dat)
{
uchar i;
SCLK=0;//初始时钟线置为0
delayus(2);
for(i=0;i<8;i++)//开始传输8个字节的数据
{
SDA=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
delayus(2);
SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输
delayus(2);
SCLK=0;//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
}
void write_1302(uchar add,uchar dat)//向1302芯片写函数,指定写入地址,数据
{
RST=0;     delayus(2);     
SCLK=0;    delayus(2);  
RST=1;     delayus(2);
DS1302WriteByte(add);     //传地址
DS1302WriteByte(dat);           //传数据
RST=0;     delayus(2);     
     SDA=1;
     SCLK=1;
}
/************************************************
*名称: DS1302ReadByte()
*说明: 无
*功能: 读取8bit的数据
*调用: delayus()
*输入: 无
*输出: dat:读取的数据
*************************************************/
uchar DS1302ReadByte()
{
uchar i,dat;
delayus(2);                                   
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据左移一位                       
if(SDA==1)//当数据线为高时,证明该位数据为1
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
SCLK=1;//拉高时钟线
delayus(2);
SCLK=0;//制造下降沿
delayus(2);
}
return dat;//返回读取出的数据
}
/************************************************
*名称: uchar DS1302Read()
*说明: 先写地址,后读数据
*功能: 从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;//返回得到的时间/日期
}
void ds1302_init() //1302芯片初始化子函数(,12:20:00,)
{
   uchar i,j;
   for(i=0;i<3;i++)
   {
     j=home[i]/10;
     home[i]=home[i]%10;
     home[i]=home[i]+j*16 ;
   
   }
   write_1302(0x8e,0x00); //允许写,禁止写保护
   for(i=0;i<3;i++)
    {
    write_1302(write_add[i],home[i]);
    delayus(2);
     }
    write_1302(0x8e,0x80); //打开写保护
    flng=1;
}
void read()     //读时钟
{
  uchar i;
  for(i=0;i<3;i++)
   {
     home[i]= DS1302Read(read_add[i]);
     delayus(2);
   }
     disp[0]=home[0]/16;
     disp[1]=home[0]%16;
     disp[2]=home[1]/16;
     disp[3]=home[1]%16;
     disp[4]=home[2]/16;
     disp[5]=home[2]%16;
}
void display()
{    uchar i;      
     for(i=0;i<7;i++)
      {
        P2=tab[disp[i]];
        delayus(2);
        qw=wei[i];
      }
        
}
main()
{
  if(!flng)
    {
     ds1302_init();
    }
   while(1)
   {
   read();
   display() ;
   }
}


你看看你Proteus中用的数码管与你的数码管显示的代码是否一致?
共阴 or 共阳;

Proteus中用的是共阳啊,是不是程序出问题了?

图像不全不清,难以判断,数码管的段位审定如何?建议输入标准程序仿真,如全写入0~8,在判断,即先硬件在软件。

是的!你可以你简单地写个Demo 程序,排除硬件问题!
之后再看软件!因为贴图,模糊,看不清!
其实你用Proteus仿真,目前IO也没有那么紧张,位选端可以直接占用
整个P1口!没有必要用串----并IC!

谢谢各位,已经搞定了

时钟—ds1302+数码管显示
http://bbs.elecfans.com/forum.ph ... &fromuid=748670

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

网站地图

Top