单片机时间控制器c语言程序,STC单片机控制DS1302程序 (C程序)

描述

#include "REG51.H"

#include "INTRINS.H"

typedef unsigned char BYTE;

sbit SCLK = P1^0;                   //DS1302时钟口P1.0

sbit IO = P1^1;                     //DS1302数据口P1.1

sbit RST = P1^2;                    //DS1302片选口P1.2

//秒    分    时    日    月  星期    年

BYTE code init[] = {0x00, 0x00, 0x20, 0x01, 0x01, 0x05, 0x10};

BYTE data now[7];

void DS1302_Initial();

void DS1302_SetTime(BYTE *p);

void DS1302_GetTime(BYTE *p);

void main()

{

DS1302_Initial();               //初始化DS1302

DS1302_SetTime(init);           //设置初始时间

DS1302_GetTime(now);            //读取当前时间

while (1);

}

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

延时X微秒(STC12C5A60S2@12M)

不同的工作环境,需要调整此函数

此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同

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

void Delay()

{

_nop_();

_nop_();

}

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

从DS1302读1字节数据

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

BYTE DS1302_ReadByte()

{

BYTE i;

BYTE dat = 0;

for (i=0; i>= 1;                    //数据右移一位

if (IO) dat |= 0x80;        //读取数据

SCLK = 1;                   //时钟线拉高

Delay();                //延时等待

}

return dat;

}

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

向DS1302写1字节数据

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

void DS1302_WriteByte(BYTE dat)

{

char i;

for (i=0; i>= 1;                  //移出数据

IO = CY;                    //送出到端口

SCLK = 1;                   //时钟线拉高

Delay();                //延时等待

}

}

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

读DS1302某地址的的数据

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

BYTE DS1302_ReadData(BYTE addr)

{

BYTE dat;

RST = 0;

Delay();

SCLK = 0;

Delay();

RST = 1;

Delay();

DS1302_WriteByte(addr);         //写地址

dat = DS1302_ReadByte();        //读数据

SCLK = 1;

RST = 0;

return dat;

}

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

往DS1302的某个地址写入数据

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

void DS1302_WritEDAta(BYTE addr, BYTE dat)

{

RST = 0;

Delay();

SCLK = 0;

Delay();

RST = 1;

Delay();

DS1302_WriteByte(addr);         //写地址

DS1302_WriteByte(dat);          //写数据

SCLK = 1;

RST = 0;

}

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

写入初始时间

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

void DS1302_SetTime(BYTE *p)

{

BYTE addr = 0x80;

BYTE n = 7;

DS1302_WriteData(0x8e, 0x00);   //允许写操作

while (n--)

{

DS1302_WriteData(addr, *p++);

addr += 2;

}

DS1302_WriteData(0x8e, 0x80);   //写保护

}

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

读取当前时间

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

void DS1302_GetTime(BYTE *p)

{

BYTE addr = 0x81;

BYTE n = 7;

while (n--)

{

*p++ = DS1302_ReadData(addr);

addr += 2;

}

}

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

初始化DS1302

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

void DS1302_Initial()

{

RST = 0;

SCLK = 0;

DS1302_WriteData(0x8e, 0x00);   //允许写操作

DS1302_WriteData(0x80, 0x00);   //时钟启动

DS1302_WriteData(0x90, 0xa6);   //一个二极管+4K电阻充电

DS1302_WriteData(0x8e, 0x80);   //写保护

}

打开APP阅读更多精彩内容

点击阅读全文

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/******************************************************************************* * 标题: 试验数码管显示时钟 * * * * 通过本例程了解 DS1302时钟芯片的基本原理和使用 ,理解并掌握DS1302时钟芯片 * * 驱动程序的编写以及实现数字字符在数码管中的显示。 * * ********************************************************************************/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include <intrins.h> sbit SCK=P3^6; //时钟 sbit SDA=P3^4; //数据 sbit RST = P3^5;// DS1302复位 sbit LS138A=P2^2; sbit LS138B=P2^3; sbit LS138C=P2^4; bit ReadRTC_Flag;//定义读DS1302标志 unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00 unsigned char l_tmpdisplay[8]; code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位 code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //共阴数码管 0-9 '-' '熄灭‘表 /******************************************************************/ /* 函数声明 */ /******************************************************************/ void Write_Ds1302_byte(unsigned char temp); void Write_Ds1302( unsigned char address,unsigned char dat ); unsigned char Read_Ds1302 ( unsigned char address ); void Read_RTC(void);//read RTC void Set_RTC(void); //set RTC void InitTIMER0(void);//inital timer0 /******************************************************************/ /* 主函数 */ /******************************************************************/ void main(void) { InitTIMER0(); //初始化定时器0 Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽 while(1) { if(ReadRTC_Flag) { ReadRTC_Flag=0; Read_RTC(); l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开 l_tmpdisplay[1]=l_tmpdate[2]&0x0f; l_tmpdisplay[2]=10; //加入"-" l_tmpdisplay[3]=l_tmpdate[1]/16; l_tmpdisplay[4]=l_tmpdate[1]&0x0f; l_tmpdisplay[5]=10; l_tmpdisplay[6]=l_tmpdate[0]/16; l_tmpdisplay[7]=l_tmpdate[0]&0x0f; } } } /******************************************************************/ /* 定时器0初始化 */ /******************************************************************/ void InitTIMER0(void) { TMOD|=0x01;//定时器设置 16位 TH0=0xef;//初始化值 TL0=0xf0; ET0=1; TR0=1; EA=1; } /******************************************************************/ /* 写一个字节 */ /******************************************************************/ void Write_Ds1302_Byte(unsigned char temp) { unsigned char i; for (i=0;i<8;i++) //循环8次 写入数据 { SCK=0; SDA=temp&0x01; //每次传输低字节 temp>>=1; //右移一位 SCK=1; } } /******************************************************************/ /* 写入DS1302 */ /******************************************************************/ void Write_Ds1302( unsigned char address,unsigned char dat ) { RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); //启动 Write_Ds1302_Byte(address); //发送地址 Write_Ds1302_Byte(dat); //发送数据 RST=0; //恢复 } /******************************************************************/ /* 读出DS1302数据 */ /******************************************************************/ unsigned char Read_Ds1302 ( unsigned char address ) { unsigned char i,temp=0x00; RST=0; _nop_(); _nop_(); SCK=0; _nop_(); _nop_(); RST=1; _nop_(); _nop_(); Write_Ds1302_Byte(address); for (i=0;i<8;i++) //循环8次 读取数据 { if(SDA) temp|=0x80; //每次传输低字节 SCK=0; temp>>=1; //右移一位 _nop_(); _nop_(); _nop_(); SCK=1; } RST=0; _nop_(); //以下为DS1302复位的稳定时间 _nop_(); RST=0; SCK=0; _nop_(); _nop_(); _nop_(); _nop_(); SCK=1; _nop_(); _nop_(); SDA=0; _nop_(); _nop_(); SDA=1; _nop_(); _nop_(); return (temp); //返回 } /******************************************************************/ /* 读时钟数据 */ /******************************************************************/ void Read_RTC(void) //读取 日历 { unsigned char i,*p; p=read_rtc_address; //地址传递 for(i=0;i<7;i++) //分7次读取 秒分时日月周年 { l_tmpdate[i]=Read_Ds1302(*p); p++; } } /******************************************************************/ /* 设定时钟数据 */ /******************************************************************/ void Set_RTC(void) //设定 日历 { unsigned char i,*p,tmp; for(i=0;i<7;i++){ //BCD处理 tmp=l_tmpdate[i]/10; l_tmpdate[i]=l_tmpdate[i]; l_tmpdate[i]=l_tmpdate[i]+tmp*16; } Write_Ds1302(0x8E,0X00); p=write_rtc_address; //传地址 for(i=0;i<7;i++) //7次写入 秒分时日月周年 { Write_Ds1302(*p,l_tmpdate[i]); p++; } Write_Ds1302(0x8E,0x80); } /******************************************************************/ /* 定时器中断函数 */ /******************************************************************/ void tim(void) interrupt 1 using 1 //中断,用于数码管扫描 { static unsigned char i,num; TH0=0xf5; TL0=0xe0; P0=table[l_tmpdisplay[i]]; //查表法得到要显示数字的数码段 switch(i) { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } i++; if(i==8) { i=0; num++; if(10==num) //隔段时间读取1302的数据。时间间隔可以调整 { ReadRTC_Flag=1; //使用标志位判断 num=0; } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值