微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > ds1302时钟用1602显示为什么控制时间的加减不管用?

ds1302时钟用1602显示为什么控制时间的加减不管用?

时间:10-02 整理:3721RD 点击:
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
uchar shi,fen,miao,snum;
sbit dula=P2^6;//定义锁存使能端口 段锁存
sbit wela=P2^7;//                 位锁存
sbit RS=P2^1;
sbit RW=P1^5;
sbit E=P1^6;
sbit s1=P3^2;
sbit s2=P3^3;
bit ReadTimeFlag;//定义读时间标志
//unsigned char code DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 显示段码值0~9
//unsigned char code WeiMa[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//分别对应相应的数码管点亮,即位码
uchar TempData[8]; //存储显示值的全局变量
void keyscan();
void init_timer0()
{
TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;

}
void delayus(uint t)
{
while(t--);
}
void delayms(uint t)
{
while(t--)
{
  delayus(245);
  delayus(245);
}
}
void wri_com(uchar com)
{
RS=0;
RW=0;
E=0;
delayms(5);
E=1;
delayms(5);
P0=com;
E=0;
}
void wri_data(uchar date)
{
RS=1;
RW=0;
E=0;
delayms(5);
E=1;
delayms(5);
P0=date;
E=0;
}
void wri_sfm(uchar add,uchar date)
{
uint shi,ge;
shi=date/10;
ge=date%10;
wri_com(0x80+0x40+add);
wri_data(0x30+shi);
wri_data(0x30+ge);
}
void wri_nyr(uchar add,uchar date)
{
uint shi,ge;
shi=date/10;
ge=date%10;
wri_com(0x80+add);
wri_data(0x30+shi);
wri_data(0x30+ge);
}
void init_led()
{
RS=0;
RW=0;
dula=0;
wela=0;
E=0;
snum=0;
wri_com(0x01);//清屏
wri_com(0x06);//输入方式设置 ac增一,画面不动
wri_com(0x0c);//显示开关控制  开闪
wri_com(0x38);//功能设置,两行  5*7
wri_com(0x80);
wri_com(0x80+0x40+5);
wri_data(':');
delayms(5);
wri_com(0x80+0x40+8);
wri_data(':');
  delayms(5);
wri_com(0x80+4);
wri_data(':');
  delayms(5);
wri_com(0x80+7);
wri_data(':');
delayms(5);
wri_com(0x80);
wri_data('2');
wri_com(0x81);
wri_data('0');
// wri_com(0x80+12);
// wri_data()
}
/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main ()
{
init_timer0();
init_led();
Ds1302_Init();
//Ds1302_Write_Time();
while (1)         //主循环
  {
keyscan();
if(ReadTimeFlag==1)
{
   ReadTimeFlag=0;
   Ds1302_Read_Time();
wri_sfm(3,time_buf1[4]);//时
wri_sfm(6,time_buf1[5]);//分
wri_sfm(9,time_buf1[6]);//秒
wri_nyr(2,time_buf1[1]);//年
wri_nyr(5,time_buf1[2]);//月
wri_nyr(8,time_buf1[3]);//日
}
}
}
void timer0() interrupt 1
{
uint num;
TH0=(65536-200)/256;    //重新赋值 2ms
TL0=(65536-200)%256;
num++;
if(num==50)        //大致100ms
   {
    num=0;
    ReadTimeFlag=1; //读标志位置1
}
}
void keyscan()
{
s1=1;
s2=1;
  Ds1302_Write_Byte(ds1302_control_add,0x00);
if(!s1)
{
  delayms(2);
  if(s1==0)
  { TR0=0;
   snum++;
   while(!s1);
  /* if(snum==1)
   {
   // TR0=0;
    wri_com(0x80+0x40+9);//秒
    wri_com(0x0f);
   }*/
   if(snum==2)
   {
    wri_com(0x80+0x40+6);//分
    wri_com(0x0f);
   }
   if(snum==3)
   {
    wri_com(0x80+0x40+3);//时
    wri_com(0x0f);
   }
   if(snum==4)
   {
    wri_com(0x80+8);//日
    wri_com(0x0f);
   }
   if(snum==5)
   {
    wri_com(0x80+5);//月
    wri_com(0x0f);
   }
   if(snum==6)
   {
    wri_com(0x80+2);//年
    wri_com(0x0f);
   }
   if(snum==7)
   {
    snum=0;
    wri_com(0x0c);
    TR0=1;
   }
  }
}
if(!snum)
{
  if(snum==1)
  {
   if(s2==0)
   {
    delayms(5);
    if(s2==0);
   while(!s2);
   
     time_buf1[6]++;
     if(time_buf1[6]==60);
     time_buf1[6]=0;
     Ds1302_Write_Time();
   
   }
  }
  if(snum==2)
  {
   if(!s2)
   {
    delayms(5);
    if(s2==0);
  while(!s2);
    time_buf1[5]++;

    if(time_buf1[5]==60);
    time_buf1[5]=0;
    Ds1302_Write_Time();
   
   }
  }
  if(snum==3)
  {
   if(!s2)
   {
    delayms(5);
    if(s2==0);
  while(!s2);
     time_buf1[4]++;
  
     if(time_buf1[4]==24);
     time_buf1[4]=0;
     Ds1302_Write_Time();
   
   }
  }
  if(snum==4)
  {
   if(!s2)
   {
    delayms(5);
    if(s2==0);
   while(!s2);
     time_buf1[3]++;

     if(time_buf1[3]==30);
     time_buf1[3]=0;
     Ds1302_Write_Time();
   
   }
  }
  if(snum==5)
  {
   if(!s2)
   {
    delayms(5);
    if(s2==0);
  while(!s2);
     time_buf1[2]++;
   
     if(time_buf1[2]==12);
     time_buf1[2]=0;
     Ds1302_Write_Time();
   
   }
  }
  if(snum==1)
  {
   if(!s2)
   {
    delayms(5);
    if(s2==0);
   while(s2);
     time_buf1[1]++;
     if(time_buf1[1]==20);
     time_buf1[1]=0;
     Ds1302_Write_Time();
   
   }
  }
}
}

#include "ds1302.h"
unsigned char time_buf1[8] ={20,10,6,5,12,0,0,6};//空年月日时分秒周
unsigned char time_buf[8] ;                         //空年月日时分秒周
/*------------------------------------------------
           向DS1302写入一字节数据
------------------------------------------------*/
void Ds1302_Write_Byte(unsigned char addr, unsigned char d)
{
        unsigned char i;
        RST_SET;       
       
        //写入目标地址:addr
        addr = addr & 0xFE;     //最低位置零
        for (i = 0; i < 8; i ++)
            {
                if (addr & 0x01)
                    {
                        IO_SET;
                        }
                else
                    {
                        IO_CLR;
                        }
                SCK_SET;
                SCK_CLR;
                addr = addr >> 1;
                }
       
        //写入数据:d
        for (i = 0; i < 8; i ++)
           {
                if (d & 0x01)
                    {
                        IO_SET;
                        }
                else
                    {
                        IO_CLR;
                        }
                SCK_SET;
                SCK_CLR;
                d = d >> 1;
                }
        RST_CLR;                                        //停止DS1302总线
}
/*------------------------------------------------
           从DS1302读出一字节数据
------------------------------------------------*/
unsigned char Ds1302_Read_Byte(unsigned char addr)
{
        unsigned char i;
        unsigned char temp;
        RST_SET;       
        //写入目标地址:addr
        addr = addr | 0x01;//最低位置高
        for (i = 0; i < 8; i ++)
            {
             
                if (addr & 0x01)
                   {
                        IO_SET;
                        }
                else
                    {
                        IO_CLR;
                        }
                SCK_SET;
                SCK_CLR;
                addr = addr >> 1;
                }
       
        //输出数据:temp
        for (i = 0; i < 8; i ++)
            {
                temp = temp >> 1;
                if (IO_R)
                   {
                        temp |= 0x80;
                        }
                else
                   {
                        temp &= 0x7F;
                        }
                SCK_SET;
                SCK_CLR;
                }
       
        RST_CLR;        //停止DS1302总线
        _nop_();                //以下为DS1302复位的稳定时间
        RST=0;
        SCK=0;
        _nop_();
        SCK=1;
        _nop_();
        SDA=0;
        _nop_();
        SDA=1;
        _nop_();
        return temp;
}
/*------------------------------------------------
           向DS1302写入时钟数据
------------------------------------------------*/
void Ds1302_Write_Time(void)
{
     
    unsigned char i,tmp;
        for(i=0;i<8;i++)
            {                  //BCD处理  由10进制转换成16进制
                tmp=time_buf1[i]/10;
                time_buf[i]=time_buf1[i]%10;
                time_buf[i]=time_buf[i]+tmp*16;
            }
        Ds1302_Write_Byte(ds1302_control_add,0x00);                        //关闭写保护
        Ds1302_Write_Byte(ds1302_sec_add,0x80);                                //暂停
//        Ds1302_Write_Byte(ds1302_charger_add,0xa9);                        //涓流充电
        Ds1302_Write_Byte(ds1302_year_add,time_buf[1]);                //年
        Ds1302_Write_Byte(ds1302_month_add,time_buf[2]);        //月
        Ds1302_Write_Byte(ds1302_date_add,time_buf[3]);                //日
        Ds1302_Write_Byte(ds1302_day_add,time_buf[7]);                //周
        Ds1302_Write_Byte(ds1302_hr_add,time_buf[4]);                //时
        Ds1302_Write_Byte(ds1302_min_add,time_buf[5]);                //分
        Ds1302_Write_Byte(ds1302_sec_add,time_buf[6]);                //秒
        Ds1302_Write_Byte(ds1302_day_add,time_buf[7]);                //周
        Ds1302_Write_Byte(ds1302_control_add,0x80);                        //打开写保护
}
/*------------------------------------------------
           从DS1302读出时钟数据
------------------------------------------------*/
void Ds1302_Read_Time(void)  
{
               unsigned char i,tmp;
        time_buf[1]=Ds1302_Read_Byte(ds1302_year_add);                //年
        time_buf[2]=Ds1302_Read_Byte(ds1302_month_add);                //月
        time_buf[3]=Ds1302_Read_Byte(ds1302_date_add);                //日
        time_buf[4]=Ds1302_Read_Byte(ds1302_hr_add);                //时
        time_buf[5]=Ds1302_Read_Byte(ds1302_min_add);                //分
        time_buf[6]=(Ds1302_Read_Byte(ds1302_sec_add))&0x7F;//秒
        time_buf[7]=Ds1302_Read_Byte(ds1302_day_add);                //周

        for(i=0;i<8;i++)
           {           //BCD处理  16进制转换成10进制
                tmp=time_buf[i]/16;
                time_buf1[i]=time_buf[i]%16;
                time_buf1[i]=time_buf1[i]+tmp*10;
           }
}
/*------------------------------------------------
                DS1302初始化
------------------------------------------------*/
void Ds1302_Init(void)
{
       
        RST_CLR;                        //RST脚置低
        SCK_CLR;                        //SCK脚置低
    Ds1302_Write_Byte(ds1302_sec_add,0x00);                                 
}
#ifndef __DS1302_H__
#define __DS1302_H__
#include <reg52.h>
#include<intrins.h>
sbit SCK=P3^4;               
sbit SDA=P3^6;               
sbit RST=P3^5;
//复位脚
#define RST_CLR        RST=0//电平置低
#define RST_SET        RST=1//电平置高

//双向数据
#define IO_CLR        SDA=0//电平置低
#define IO_SET        SDA=1//电平置高
#define IO_R        SDA  //电平读取

//时钟信号
#define SCK_CLR        SCK=0//时钟信号
#define SCK_SET        SCK=1//电平置高

#define ds1302_sec_add                        0x80                //秒数据地址
#define ds1302_min_add                        0x82                //分数据地址
#define ds1302_hr_add                        0x84                //时数据地址
#define ds1302_date_add                        0x86                //日数据地址
#define ds1302_month_add                0x88                //月数据地址
#define ds1302_day_add                        0x8a                //星期数据地址
#define ds1302_year_add                        0x8c                //年数据地址
#define ds1302_control_add                0x8e                //控制数据地址
#define ds1302_charger_add                0x90                                          
#define ds1302_clkburst_add                0xbe
extern unsigned char time_buf1[8];//空年月日时分秒周
extern unsigned char time_buf[8] ;//空年月日时分秒周
/*------------------------------------------------
           向DS1302写入一字节数据
------------------------------------------------*/
void Ds1302_Write_Byte(unsigned char addr, unsigned char d);
/*------------------------------------------------
           从DS1302读出一字节数据
------------------------------------------------*/
unsigned char Ds1302_Read_Byte(unsigned char addr) ;
/*------------------------------------------------
           向DS1302写入时钟数据
------------------------------------------------*/
void Ds1302_Write_Time(void) ;
/*------------------------------------------------
           从DS1302读出时钟数据
------------------------------------------------*/
void Ds1302_Read_Time(void)  ;
/*------------------------------------------------
                DS1302初始化
------------------------------------------------*/
void Ds1302_Init(void);
#endif

时间是可以写入的,在控制时间的加减的时候,还是需要把你所希望的数值直接写进1302的寄存器中

写得也太长了吧,很难找的

单独测试一下按键响应这块程序

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

网站地图

Top