电子产业一站式赋能平台

PCB联盟网

搜索
查看: 2467|回复: 5
收起左侧

求教DS1302,LCD上时分秒年月日都是问号,怎么破?

[复制链接]

617

主题

968

帖子

5301

积分

四级会员

Rank: 4

积分
5301
发表于 2022-12-15 09:10:58 | 显示全部楼层 |阅读模式
#include<reg52.h>
#include<intrins.h>

#define GPIO_LCD P0

//DS1302写入和读取时分秒的地址命令
unsigned charREAD_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //秒分时日月周年 最低位读写位};
unsigned charWRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//DS1302时钟初始化2013年1月1日星期二12点00分00秒。存储顺序是秒分时日月周年,存储格式是用BCD码
unsigned charTIME[7]={0x01,0x01,0x12,0x02,0x01,0x01,0x13};     //BCD码


sbit RS=P2^6;
sbit RW=P2^5;
sbit E=P2^7;



sbit SCLK=P3^6;
sbit RST=P3^5;
sbit DSIO=P3^4;

void Delay1us(unsigned int);                                         //延时函数声明

void LCDInit();                                                                                  //LCD初始化
void LcdWriteCom(unsigned char com);                     //LCD写入命令
void LcdWriteData(unsigned char dat);                          //LCD写入数据

void Ds1302Write(unsigned charaddr,unsigned char dat);             //1302写入数据
unsigned char Ds1302Read(unsigned charaddr);                                                 //1302读操作
void Ds1302Init(void);                                                                                                   //
void Ds1302ReadTime(void);                                                                                      //

void LcdDisplay(void);

///////////////////////////////////////////////////////////////
void main()
{
   LCDInit();
         Ds1302Init();

   while(1)
         {         
                   Ds1302ReadTime();
                   LcdDisplay();

         }
}


///////////////////////////////////////////////////////////显示函数
void LcdDisplay()
{
         LcdWriteCom(0x80+0x40);
         LcdWriteData('0'+TIME[2]/16);                                   //时
         LcdWriteData('0'+(TIME[2]&0x0f));                                      
         LcdWriteData('-');
         LcdWriteData('0'+TIME[1]/16);                                   //分
         LcdWriteData('0'+(TIME[1]&0x0f));        
         LcdWriteData('-');
         LcdWriteData('0'+TIME[0]/16);                                   //秒
         LcdWriteData('0'+(TIME[0]&0x0f));

         LcdWriteCom(0x80);
         LcdWriteData('2');
         LcdWriteData('0');
         LcdWriteData('0'+TIME[6]/16);                          //年
         LcdWriteData('0'+(TIME[6]&0x0f));
         LcdWriteData('-');
         LcdWriteData('0'+TIME[4]/16);                          //月
         LcdWriteData('0'+(TIME[4]&0x0f));
         LcdWriteData('-');
         LcdWriteData('0'+TIME[3]/16);                          //日
         LcdWriteData('0'+(TIME[3]&0x0f));
         LcdWriteCom(0x8D);
         LcdWriteData('0'+(TIME[5]&0x07));        //星期                          
}



////////////////////////////////////////////////////////////下面是DS1302
void Ds1302Write(unsigned charaddr,unsigned char dat)              //向DS1302写数据
{
  unsigned char n;
  SCLK=0;             //将信号时钟SCLK置低电平
  _nop_();
  RST=1;              //将RST(CE)置高电平
  _nop_();
for(n=0;n<8;n++)           //开始传送8位地址命令
  {
     DSIO=addr&0x01;       //数据从低位开始传送
            addr>>=1;                              //“>>=”是符合运算符,等于addr右移一位再赋值给addr
           SCLK=1;                                    //数据在上升沿时,DS1302读取数据
           _nop_();
           SCLK=0;               //数据在下降沿时,放置数据
          _nop_();

  }
  _nop_();
  for(n=0;n<8;n++)                 //写8位数据
  {
     DSIO=dat&0x01;       //数据从低位开始传送
           dat>>=1;                                  //“>>=”是符合运算符,等于addr右移一位再赋值给addr
           SCLK=1;                                    //数据在上升沿时,DS1302读取数据
     _nop_();
           SCLK=0;               //数据在下降沿时,放置数据
           _nop_();

  }
RST=0;
_nop_();               
}


////////////////////////////////////////////////////////////////////从DS1302读数据
unsigned char Ds1302Read(unsigned charaddr)                     
{
unsigned char n,dat,dat1;
SCLK=0;             //将信号时钟SCLK置低电平
_nop_();
RST=1;              //将RST(CE)置高电平
_nop_();
for(n=0;n<8;n++)           //开始传送8位地址命令
  {
     DSIO=addr&0x01;       //数据从低位开始传送
            addr>>=1;                              //“>>=”是符合运算符,等于addr右移一位再赋值给addr
           SCLK=1;                                    //数据在上升沿时,DS1302读取数据
           _nop_();
           SCLK=0;               //数据在下降沿时,放置数据
           _nop_();

  }
   _nop_();
  for(n=0;n<8;n++)                 //读取8位数据
  {   
     //dat1=DSIO;       //数据从低位开始传送
         //dat=dat>>1;                                      //“>>=”是符合运算符
          // dat|=dat1<<7;
           dat>>=1;
           if(DSIO)
           dat|=0x80;
           SCLK=1;                                    //数据在上升沿时,DS1302读取数据
           _nop_();
           SCLK=0;               //数据在下降沿时,放置数据
           _nop_();

  }
RST=0;
_nop_();                 //下面6行是为了让DS1302复位
SCLK=1;
_nop_();
DSIO=0;
_nop_();
DSIO=1;
_nop_();
return dat;  
}


//////////////////////////////////////////////////DS1302初始化
void Ds1302Init()                        
{
         unsignedchar n;
         Ds1302Write(0x8E,0X00);                  //禁止写保护,就是关闭写保护功能
         for(n=0;n<7;n++)//写入7个字节的时钟信号:分秒时日月周年
         {
                   Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);      
         }
         Ds1302Write(0x8E,0x80);                  //打开写保护功能
}


///////////////////////////////////////////////////////DS1302读出时间
void Ds1302ReadTime()
{
         unsignedchar n;
         for(n=0;n<7;n++)//读取7个字节的时钟信号:分秒时日月周年
         {
                   TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);
         }               
}







///////////////////////////////////////////////下面是LCD的3个子函数和延时函数

void LcdWriteCom(unsigned char com)                     //写入命令
{

       RS=0;                                                                          //选择命令
           RW=0;                                                                            //写
           GPIO_LCD=com;
     Delay1us(1);
           E=1;                                                                                //使能信号
           Delay1us(1);
           E=0;
}
void LcdWriteData(unsigned char dat)              //写入数据
{

           RS=1;
           RW=0;
           GPIO_LCD=dat;
     Delay1us(1);
           E=1;
           Delay1us(1);         
           E=0;
}
void LCDInit()                                                                    //初始化
{  
      LcdWriteCom(0x38);                                                    //设置16*2显示,5*7点阵,8位数据接口
          LcdWriteCom(0x0c);                                                     //开显示,不显示光标,不闪烁
          LcdWriteCom(0x06);                                                    //光标加1,整屏不移动
          LcdWriteCom(0x01);                                                    //所有显示清零

}
void Delay1us(unsigned int a)                     //延时函数
{
         unsignedint b,c;
         for(c=a;c>0;c--)
                   for(b=110;b>0;b--);
}
回复

使用道具 举报

0

主题

829

帖子

622

积分

二级会员

Rank: 2

积分
622
发表于 2022-12-15 09:11:12 | 显示全部楼层
这是例程?
回复 支持 反对

使用道具 举报

0

主题

804

帖子

517

积分

二级会员

Rank: 2

积分
517
发表于 2022-12-15 09:12:01 | 显示全部楼层
与单片机相连的要加上拉电阻
回复 支持 反对

使用道具 举报

35

主题

892

帖子

1091

积分

三级会员

Rank: 3Rank: 3

积分
1091
发表于 2022-12-15 09:12:29 | 显示全部楼层
我也遇到了,你怎么解决的、
回复 支持 反对

使用道具 举报

35

主题

892

帖子

1091

积分

三级会员

Rank: 3Rank: 3

积分
1091
发表于 2022-12-15 09:13:12 | 显示全部楼层
楼主用的是普中的开发版?
回复 支持 反对

使用道具 举报

35

主题

892

帖子

1091

积分

三级会员

Rank: 3Rank: 3

积分
1091
发表于 2022-12-15 09:13:39 | 显示全部楼层
这个问题解决了吗?
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表