ds1302 数码管显示 C51

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit SCL = P3^6;   //定义时钟信号接口
sbit IO   = P3^4;   //定义数据信号接口
sbit RST = P3^5;   //定义复位信号接口
sbit ACC0 = ACC^0;   //ACC寄存器的最低位
sbit ACC7 = ACC^7;   //ACC寄存器的最高位

uchar ds1,ds2,time;
uchar curttime[7];

//数码管显示字符表
uchar code table[] = {
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
//初始化时间表
uchar code InitTime[] = {0x01,0x20,0x02,0x16,0x10,0x06,0x10,
};
//段选表
uchar code tabwcon[] ={0x07,0x06,0x05,0x04,
0x03,0x02,0x01,0x00};

//读取时间的地址表
uchar code read_time_address[7]={
0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};

//写入时间的地址表
code uchar write_rtc_address[7]={
0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};

//数码管显示延时函数
void delay(uint z)
{
uint x,y;
   for(x=z;x>0;x--)
    {
     for(y=190;y>0;y--);
      {
      }
    }
}
//发送一个字节
void SendByte(uchar date)
{
uchar i;
ACC = date;          //将date变量存入ACC中
for (i = 8; i >0; i--)
      {
   IO = ACC0;
   SCL = 1;     //时钟信号线拉高发送一位数据
   SCL = 0;    //发送完一位数据后 拉低时钟线
   ACC = ACC>>1;   //将ACC的D1位移到D0位准备发送
   }
}

//接收一个字节
uchar AccByte(void)
{
uchar i;
for (i = 8; i >0; i--)
      {
   ACC = ACC>>1;   //向右一位准备接受总线上的数据
   ACC7 = IO;    //从总线上接收数据并存到ACC7中
   SCL = 1;    //从总线上接收到一位数据
   SCL = 0;    //接收完一位数据后 拉低时钟线
   }
return (ACC);        //返回接收到的数据 ACC
}

//写一个字节 注意与读一个字节的区别
void WriteByte(uchar add, uchar date)
{
RST = 0; SCL = 0; RST = 1;   //初始化 开启丛机内部定时器电路
SendByte(add);        //发送将写入数据的地址
SendByte(date);           //向预定地址写入数据            //拉高时钟线 为下一次读取的初始化
SCL = 1; RST = 0;         //屏蔽任何输入输出   释放总线
}

//读一个字节 注意与发一个字节的区别
uchar ReadByte(uchar add)
{
uchar date;
RST = 0;    SCL = 0; RST = 1;   //初始化 开启丛机内部定时器电路
SendByte(add);        //发送将读数据的地址
date = AccByte();          //将接收到的数据赋予rdate         //拉高时钟线 为下一次读取的初始化
SCL = 1;    RST = 0;         //屏蔽任何输入输出
return (date);        //返回读到的数据
}

//时钟寄存器多字节写
/*void BurstW1302T(uchar *p) //P寄存器地址指针
{
uint i;
WriteByte(0X8e,0x00);      //写保护控制命令 WP = 0(开启写命令) 写操作
RST = 0;    SCL = 0; RST = 1;   //初始化
SendByte(0xbe);           //时钟多字节写命令(时钟突发访问)
// 向地址逐一发送数据
for (i = 0; i < 8; i++)
   {
   SendByte(*p);
   p++;
   }
SCL = 1;          //拉高时钟线 为下一次读取的初始化
RST = 0;         //主机释放总线
}

//时钟寄存器多字节读 读数据的时候不用写保护控制命令
void BurstR1302T(uchar *p)
{
uint i;
RST = 0;    SCL = 0; RST = 1;    //初始化
SendByte(0xbf);         //时钟多字节读命令(时钟突发访问)
for (i = 0; i < 8; i++)       
   {
   *p = AccByte();        //接收数据并将其存到P指针所指向的地址
   p++;
   }
SCL = 1; RST = 0;       //同上
}

//RAM寄存器多字节写(道理同时钟数据多字节读写一样)
void BurstW1302R(uchar *p)
{
uint i;
WriteByte(0X8e,0x00);
RST = 0;    SCL = 0; RST = 1;
SendByte(0xfe); //寄存器突发访问(写)
for (i = 0; i < 32; i++)
   {
   SendByte(*p);
   p++;
   }
SCL = 1; RST = 0;
}

//RAM寄存器多字节读 (道理同时钟数据多字节读写一样)
void BurstR1302R(uchar *p)
{
uint i;
RST = 0;    SCL = 0; RST = 1;
SendByte(0xff); //寄存器突发访问(读)
for (i = 0; i < 32; i++)
   {
   *p = AccByte();
   p++;
   }
SCL = 1; RST = 0;
} */

//设置初始化时间   注意区分于多字节写的不同
void TimeSet(uchar *p)
{
uchar i;

uchar add = 0x80;         //写入数据的初始地址
WriteByte(0x8e,0x00);   //写保护控制 WP=0,允许写入数据
for (i = 0; i < 7; i++)
   {
   WriteByte(add,*p);
   p++;
   add += 2;
   }
WriteByte(0x8e,0x80);     //写保护控制 WP=1,禁止写入数据
}

//读取时间 并将其存到数组中
void GetTime(uchar curttime[])
{
    uchar i;                    
    uchar add = 0x81;                 //读取数据的初始地址
    for (i = 0; i < 8; i++)
   {
   curttime[i] = ReadByte(add); //在此地址读数据并存入数组中
   add += 2;
   }
}

//每隔5秒轮流显示时间和日期
void display()
{
uchar i,j;
//显示时间
if (time <= 100)
   {
   for (i = 0; i < 4; i++)
    {
    if(j == 8) { j = 0; }
    ds1 = curttime[i]&0x0f;
    ds2 = (curttime[i]&0xf0)>>4;
    P2 = tabwcon[j];
    P0 = table[ds1];
    j++;
    delay(1);
  
    P2 = tabwcon[j];
    P0 = table[ds2];
    j++;
    delay(1);
    }
   }
   //显示日期
else if(time>=100 && time<=200)
   {
    for (i = 4; i < 7; i++)
     {
     if(j == 6) { j = 0; }
     ds1 = curttime[i]&0x0f;
     ds2 = (curttime[i]&0xf0)>>4;
     P2 = tabwcon[j];
     P0 = table[ds1];
     j++;
     delay(1);
   
     P2 = tabwcon[j];
     P0 = table[ds2];
     j++;
     delay(1);
     }
   }
else time = 0; //清零

}
void init()
{
TMOD = 0x01; //设置定时器0工作方式
TH0 = (65536-50000)/265;
TL0 = (65536-50000)%265;
IE = 0x82;
TR0 = 1;
}
void main()
{
init();
TimeSet(InitTime);

while(1)
{
   GetTime(curttime);
   display();
}
}

void timer() interrupt 1
{
TH0 = (65536-50000)/265;
TL0 = (65536-50000)%265;
time++;
}


你可能感兴趣的:(ds1302 数码管显示 C51)