如何改进这个DS1302时钟程序?

时间:2021-02-21 16:32:41
这个程序我写好了,是24小时制的,但我想知道把它改成12小时制的。
现附上原程序如下:
#include<reg52.h>      
#define uchar unsigned char   
uchar digit[10]={"0123456789"};  
sbit SCLK=P1^0;   
sbit DATA=P1^1;  
sbit RST=P1^2;    
void delayms(uchar n)
{
 uchar x,y;
 for(x=n;x>0;x--)
  for(y=110;y>0;y--);
}

void Write1302(uchar dat)
{
  uchar i; 
  SCLK=0;            
  delayms(2);       
  for(i=0;i<8;i++)      
    {
     DATA=dat&0x01;    
 delayms(2);       
 SCLK=1;           
 delayms(2);      
 SCLK=0;           
 dat>>=1;          
  }

 }
void WriteSet1302(uchar Cmd,uchar dat)
 {   
        RST=0;          
        SCLK=0;          
    RST=1;           
    delayms(2);     
    Write1302(Cmd);  
    Write1302(dat);  
    SCLK=1;          
    RST=0;           
 }
 
uchar Read1302(void)
 {
    uchar i,dat;
delayms(2);      
for(i=0;i<8;i++)   
 {  dat>>=1;
 if(DATA==1)   
 dat|=0x80;    
 SCLK=1;      
 delayms(2);  
 SCLK=0;       
 delayms(2);  
  }  
  return dat;        
}  
 
uchar  ReadSet1302(uchar Cmd)
 {
  uchar dat;
  RST=0;                 
  SCLK=0;                
  RST=1;                 
  Write1302(Cmd);       
  dat=Read1302();       
  SCLK=1;              
  RST=0;               
  return dat;          
}
void Init_DS1302(void)
{
  uchar flag;
   
    flag= ReadSet1302(0x81);
//if(flag&0x80)
 //{     
    WriteSet1302(0x8E,0x00);                  
    WriteSet1302(0x80,((52/10)<<4|(52%10)));   
WriteSet1302(0x82,((59/10)<<4|(59%10)));   
WriteSet1302(0x84,((12/10)<<4|(12%10))); 
WriteSet1302(0x86,((25/10)<<4|(25%10))); 
WriteSet1302(0x88,((8/10)<<4|(8%10))); 
WriteSet1302(0x8c,((10/10)<<4|(10%10)));  
WriteSet1302(0x90,0xa5);                
WriteSet1302(0x8E,0x80);    
    //}

  }
sbit RS=P2^0;         
sbit RW=P2^1;         
sbit E=P2^2;          
sbit BF=P0^7;        
bit BusyTest(void)
  {
        bit result;
    RS=0;       
     RW=1;
     E=1;        
     delayms(5);    
     result=BF;  
    E=0;         
    return result;
  }
void WriteInstruction (uchar dictate)
{   
     while(BusyTest()==1);   
 RS=0;                 
 RW=0;   
 E=0;                   
     delayms(5);                
 P0=dictate;            
 delayms(5);                
 E=1;                   
 delayms(5);                
  E=0;                  
 }

 void WriteAddress(uchar x)
 {
     WriteInstruction(x|0x80); 
 }

 void WriteData(uchar y)
 {
    while(BusyTest()==1);  
  RS=1;           
  RW=0;
  E=0;            
      P0=y;           
  delayms(5);       
  E=1;          
  delayms(5);        
  E=0;            
 }
void LcdInitiate(void)
{
    delayms(15);               
    WriteInstruction(0x38);     
delayms(5);               
    WriteInstruction(0x38);
delayms(5);               
WriteInstruction(0x38);     
delayms(5);                
WriteInstruction(0x0c);     
delayms(5);               
WriteInstruction(0x06);     
delayms(5);                 
WriteInstruction(0x01);     
delayms(5);              

 } 
void DisplaySecond(uchar x)
{
 unsigned char i,j;     
i=x/10;
j=x%10;     
WriteAddress(0x49);    
WriteData(digit[i]);    
WriteData(digit[j]);    
delayms(50);              
 } 
void DisplayMinute(unsigned char x)
{
 unsigned char i,j;     
i=x/10;
j=x%10;     
WriteAddress(0x46);    
WriteData(digit[i]);    
WriteData(digit[j]);    
delayms(50);              
 } 
void DisplayHour(uchar x)
{
 unsigned char i,j;    
i=x/10;
j=x%10;     
WriteAddress(0x43);    
WriteData(digit[i]);    
WriteData(digit[j]);   
delayms(50);              
 }
void DisplayDay(uchar x)
{
  unsigned char i,j;     
i=x/10;
j=x%10;     
WriteAddress(0x0c);    
WriteData(digit[i]);    
WriteData(digit[j]);    
delayms(50);              
 } 
void DisplayMonth(uchar x)
{
 uchar i,j;    
i=x/10;
j=x%10;    
WriteAddress(0x09);    
WriteData(digit[i]);    
WriteData(digit[j]);    
delayms(50);             
 } 
void DisplayYear(uchar x)
{
 uchar i,j;     
i=x/10;
j=x%10;   
WriteAddress(0x06);    
WriteData(digit[i]);    
WriteData(digit[j]);    
delayms(50);            
 }
 
void main(void)
{
  uchar second,minute,hour,day,month,year;      
  uchar ReadValue;   
  LcdInitiate();             //Òº¾§³õʼ»¯
  WriteAddress(0x01);  //×¼±¸Ð´ÈëDate
  WriteData('D');      
  WriteData('a');      
  WriteData('t');      
  WriteData('e');      
  WriteData(':');      
  WriteAddress(0x08);  
  WriteData('-');      
  WriteAddress(0x0b);  
  WriteData('-');      
  WriteAddress(0x45);  
  WriteData(':');      
  WriteAddress(0x48);  
  WriteData(':');      
  Init_DS1302();       
  while(1)
    {
  ReadValue = ReadSet1302(0x81);   
     second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  DisplaySecond(second);          
  ReadValue = ReadSet1302(0x83);  
     minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
  DisplayMinute(minute);        
     ReadValue = ReadSet1302(0x85);  
     hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
  DisplayHour(hour);              
     ReadValue = ReadSet1302(0x87);  
     day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
  DisplayDay(day);                
  ReadValue = ReadSet1302(0x89);  
     month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
  DisplayMonth(month);            
  ReadValue = ReadSet1302(0x8d);  
     year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); 
  DisplayYear(year);              
 }
}

6 个解决方案

#1


呵呵,我以前就写了始终的程序,不过是关于12887的,那个时候 我是把24小时制的转换成12小时是用的方法是 当你要设置成12小时制时,把大于12小时的时钟数减去12,再在液晶上显示就可以了,很简单的,楼主可以试一下。

#2


void DisplayHour(uchar x)
{
 unsigned char i,j;
//加下面一句,就变成了十二,但是没有am和pm显示
x=x%12;   
i=x/10;
j=x%10;   
WriteAddress(0x43);   
WriteData(digit[i]);   
WriteData(digit[j]);   
delayms(50);   
 }

#3


但是出现了一个问题:
那就是在上午11:59:59后,也到了00:00:00
这个怎么解决?

#4


引用 3 楼 haoqianxiao 的回复:
但是出现了一个问题:
那就是在上午11:59:59后,也到了00:00:00
这个怎么解决?


if啊

if(hour==0x00)hour=12;//  =.=

#5


怎么添加if?
添加在哪?

#6


可以设置1302的第2个寄存器(小时的),
bit 7   6    5    4    3   2   1   0
bit7=0 24小时 =1 12小时
bit6无用
bit5 12小时时是AM/PM   24小时时与bit4共同组成小时的高位(0,1,2)
bit4时间的个位,
bit3--0 时间的个位(0-9)。


也可以自己换算:
时间为0点时为AM12:0
小于12的(1---11)为AM
12:00为下午12点
大于12的为PM(13-23)要减12

#1


呵呵,我以前就写了始终的程序,不过是关于12887的,那个时候 我是把24小时制的转换成12小时是用的方法是 当你要设置成12小时制时,把大于12小时的时钟数减去12,再在液晶上显示就可以了,很简单的,楼主可以试一下。

#2


void DisplayHour(uchar x)
{
 unsigned char i,j;
//加下面一句,就变成了十二,但是没有am和pm显示
x=x%12;   
i=x/10;
j=x%10;   
WriteAddress(0x43);   
WriteData(digit[i]);   
WriteData(digit[j]);   
delayms(50);   
 }

#3


但是出现了一个问题:
那就是在上午11:59:59后,也到了00:00:00
这个怎么解决?

#4


引用 3 楼 haoqianxiao 的回复:
但是出现了一个问题:
那就是在上午11:59:59后,也到了00:00:00
这个怎么解决?


if啊

if(hour==0x00)hour=12;//  =.=

#5


怎么添加if?
添加在哪?

#6


可以设置1302的第2个寄存器(小时的),
bit 7   6    5    4    3   2   1   0
bit7=0 24小时 =1 12小时
bit6无用
bit5 12小时时是AM/PM   24小时时与bit4共同组成小时的高位(0,1,2)
bit4时间的个位,
bit3--0 时间的个位(0-9)。


也可以自己换算:
时间为0点时为AM12:0
小于12的(1---11)为AM
12:00为下午12点
大于12的为PM(13-23)要减12