原创 DS1302的C51程序

2009-12-7 15:41 3215 8 8 分类: 软件与OS

#include<reg52.h>
#include<intrins.h>
/* 实时时钟模块 时钟芯片型号:DS1302 */
#define uchar unsigned char
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;



/*/
/*********************************************************************/
sbit T_CLK = P2^0; /*实时时钟时钟线引脚 */ // T_CLK = P2^0;
sbit T_RST = P2^1; /*实时时钟复位线引脚 */  //T_RST = P2^1;
sbit T_IO  =  P2^2; /*实时时钟数据线引脚 */  //T_IO  =  P2^2;


#define ldata P0


sbit led1=P2^7;
sbit led2=P2^6;
sbit led3=P2^5;
sbit led4=P2^3;
uchar led[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x0,0x90};


/********************************************************************


*
* 名称: v_RTInputByte
* 说明:
* 功能: 往DS1302写入1Byte数据
* 调用:
* 输入: ucDa 写入的数据
* 返回值: 无
***********************************************************************/
void v_RTInputByte(uchar ucDa)
{
uchar i;
ACC = ucDa;
for(i=8; i>0; i--)
{
T_IO = ACC0; /*相当于汇编中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
*
* 名称: uchar uc_RTOutputByte
* 说明:
* 功能: 从DS1302读取1Byte数据
* 调用:
* 输入:
* 返回值: ACC
***********************************************************************/
uchar uc_RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
*
* 名称: v_W1302
* 说明: 先写地址,后写命令/数据
* 功能: 往DS1302写入数据
* 调用: v_RTInputByte()
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值: 无
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); /* 地址,命令 */
v_RTInputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名称: uc_R1302
* 说明: 先写地址,后读命令/数据
* 功能: 读取DS1302某地址的数据
* 调用: v_RTInputByte() , uc_RTOutputByte()
* 输入: ucAddr: DS1302地址
* 返回值: ucDa :读取的数据
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); /* 地址,命令 */
ucDa = uc_RTOutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST =0;
return(ucDa);
}
/********************************************************************
*
* 名称: v_BurstW1302T
* 说明: 先写地址,后写数据(时钟多字节方式)
* 功能: 往DS1302写入时钟数据(多字节方式)
* 调用: v_RTInputByte()
* 输入: pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制
* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void v_BurstW1302T(uchar *pSecDa)
{
uchar i;
v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbe); /* 0xbe:时钟多字节写命令 */
for (i=8;i>0;i--) /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/
{
v_RTInputByte(*pSecDa);/* 写1Byte数据*/
pSecDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名称: v_BurstR1302T
* 说明: 先写地址,后读命令/数据(时钟多字节方式)
* 功能: 读取DS1302时钟数据
* 调用: v_RTInputByte() , uc_RTOutputByte()
* 输入: pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: ucDa :读取的数据
***********************************************************************/
void v_BurstR1302T(uchar *pSecDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbf); /* 0xbf:时钟多字节读命令 */
for (i=8; i>0; i--)
{
*pSecDa = uc_RTOutputByte(); /* 读1Byte数据 */
pSecDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名称: v_BurstW1302R
* 说明: 先写地址,后写数据(寄存器多字节方式)
* 功能: 往DS1302寄存器数写入数据(多字节方式)
* 调用: v_RTInputByte()
* 输入: pReDa: 寄存器数据地址
* 返回值: 无
***********************************************************************/
void v_BurstW1302R(uchar *pReDa)
{
uchar i;
v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xfe); /* 0xbe:时钟多字节写命令 */
for (i=31;i>0;i--) /*31Byte 寄存器数据 */
{
v_RTInputByte(*pReDa); /* 写1Byte数据*/
pReDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名称: uc_BurstR1302R
* 说明: 先写地址,后读命令/数据(寄存器多字节方式)
* 功能: 读取DS1302寄存器数据
* 调用: v_RTInputByte() , uc_RTOutputByte()
* 输入: pReDa: 寄存器数据地址
* 返回值: 无
***********************************************************************/
void v_BurstR1302R(uchar *pReDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xff); /* 0xbf:时钟多字节读命令 */
for (i=31; i>0; i--) /*31Byte 寄存器数据 */
{
*pReDa = uc_RTOutputByte(); /* 读1Byte数据 */
pReDa++;
}
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名称: v_Set1302
* 说明:
* 功能: 设置初始时间
* 调用: v_W1302()
* 输入: pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void v_Set1302(uchar *pSecDa)
{
uchar i;
uchar ucAddr = 0x80;
v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
for(i =7;i>0;i--)
{
v_W1302(ucAddr,*pSecDa); /* 秒 分 时 日 月 星期 年 */


pSecDa++;
ucAddr +=2;
}
v_W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
}
/********************************************************************
*
* 名称: v_Get1302
* 说明:
* 功能: 读取DS1302当前时间
* 调用: uc_R1302()
* 输入: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void v_Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
for (i=0;i<7;i++)
{
ucCurtime = uc_R1302(ucAddr);/*格式为: 秒 分 时 日 月
星期 年 */
ucAddr += 2;
}

void serie_init()
{
 TMOD=0X20;
  TL1=0XFD;
  TH1=0XFD;
  SCON="0XD8";
  PCON="0X00";
 


}
void delay()
{
  unsigned int i;
 for(i=1;i<100;i++)
 {
  _nop_();
    _nop_();
   _nop_();
     _nop_();
    _nop_();
      _nop_();



 }


}
void display(uchar ldata1,uchar ldata2,uchar ldata3,uchar ldata4)
{
    led1=1;
    led2=1;
    led3=1;
    led4=0;
    ldata="ldata1";
    delay();
    led1=1;
    led2=1;
    led3=0;
    led4=1;
    ldata="ldata2";
    delay();
    led1=1;
    led2=0;
    led3=1;
    led4=1;
    ldata="ldata3";
    delay();
    led1=0;
    led2=1;
    led3=1;
    led4=1;
    ldata="ldata4";
    delay();


 


}


uchar bcd2_hex(uchar val)
{
 uchar i;


i = val&0x0f; //按位与,i得到低四位数。
val >>= 4;    //右移四位,将高四位移到低四位的位置,得到高四位码值。
val &= 0x0f;  //防止移位时高位补进1,只保留高四位码值
val *= 10;    //高位码值乘以10
i += val;     //然后与第四位码值相加。
return i;     //将得到的十进制数返回
}
void main()
{  uchar time[]={0x00,0x00,0x02,0x03,0x04,0x05,0x00};
     uchar ntime[]={0,0,0,0,0,0,0} ;
   unsigned int i;
    uchar sec;
 uchar sec1,sec2;
 uchar data1,data2;
 uchar tmp1;


 uchar min;
 uchar min1,min2;
 uchar data3,data4;
 uchar tmp2;


 T_RST = 0;
    T_CLK = 0;
 for(i=2000;i>0;i--);
 
    v_Set1302(time);
 //serie_init();
   TR1=1;
  while(1){
 
    
    v_Get1302(ntime);
     sec="ntime"[0];
  min=ntime[1];
   
      tmp1= bcd2_hex(sec);
 
   sec1=(int)tmp1%10;
      sec2=(int)tmp1/10;


   tmp2=bcd2_hex(min);
   min1=(int)tmp2%10;
   min2=(int)tmp2/10;
  
  
 
    data1=led[sec1];
    data2=led[sec2];
    data3=led[min1];
    data4=led[min2];
    display(data1,data2,data3,data4);



   
    }



}


 


//奇怪。一提交程序,有些地方就给填上了“”符合,不知道怎么回事???
 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条