⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd2403.c

📁 SD2403A时钟芯片在STC单片机下的源程序 此芯片价格便宜
💻 C
字号:
//************************************************************
//实时时钟SD2400读写C51演示程序
//              chendw@whwave.com.cn    2008/01/15
//************************************************************

/******读SD2400实时数据寄存器******/
//读出时间后屏蔽掉无用数据位
//如果调用此程序而所用系统当中又没有时钟或时钟不正常就会出现死机现象
#include <reg52.h>
#include <intrins.h>
//*********变量及IO口定义*********
typedef unsigned char uchar;
typedef unsigned int uint;


#define true  1
#define false 0
//sbit	SDA=P1^2;
//sbit	SCL=P1^0;
sbit	SCL=0xea;
sbit	SDA=P2^4;
sbit    RST =P2^6;
//void rState(void);//写FLASH备用这里暂时不用
//void wState(void);
void ReadDate(void);
void WriteDate(void);
static	bit I2CStart(void);
static	void I2CStop(void);
static	void I2CAck(void);
static	void I2CNoAck(void);
static	bit I2CWaitAck(void); 
static	void I2CSendByte(uchar Data);
static	uchar I2CReceiveByte(void);
static	void WriteTimeOn(void);
static	void WriteTimeOff(void);
void I2CWait(void);
uchar Second=0x22,Minute=0x45,Hour=0x16,Week=0x05,Day=0x3,Month=0x04,Year=0x09,State;

void main(void)
{
  RST=0;
 //// WriteDate();
  while(1){
    ReadDate();
  }

}
/*********I2C延时***********/
void I2CWait(void)
{	
	_nop_();_nop_();_nop_();_nop_();
}

void ReadDate(void)
{
																//系统每0.5S读一次时间
	
	if(I2CStart()){													//判断开始是否正确
		 	
	  I2CSendByte(0x65); 
	  if(I2CWaitAck()){					 						//判断ACK是否正确{
		 Second = I2CReceiveByte()&0x7f;			//秒
		 I2CAck();
		 Minute = I2CReceiveByte()&0x7f;			//分
		 I2CAck();
		 Hour = I2CReceiveByte()&0x3f;			//时
		 I2CAck();
		 Week = I2CReceiveByte()&0x07;			//星期
		 I2CAck();
		 Day = I2CReceiveByte()&0x3f;			//日
		 I2CAck();
		 Month = I2CReceiveByte()&0x1f;			//月
		 I2CAck();
		 Year = I2CReceiveByte();				//年
		 I2CNoAck();											//最后一个数据不应答		
      }
	}
	I2CStop();
		

}
/******写SD2400实时数据寄存器******/
void WriteDate(void)
{		
    WriteTimeOn();
	I2CStart();
	I2CSendByte(0x64);      
	I2CWaitAck();   
    I2CSendByte(0x00);									//设置写起始地址      
	I2CWaitAck();
	I2CSendByte(Second);					// second     
	I2CWaitAck();	
	I2CSendByte(Minute);					//minute      
	I2CWaitAck();	
	I2CSendByte(Hour|0x80);				//hour ,二十四小时制     
	I2CWaitAck();	
	I2CSendByte(Week);						//week      
	I2CWaitAck();	
	I2CSendByte(Day);						//day      
	I2CWaitAck();	
	I2CSendByte(Month);					//month      
	I2CWaitAck();	
	I2CSendByte(Year);						//year      
	I2CWaitAck();	
	I2CStop();
	I2CStart();
	I2CSendByte(0x64);      
	I2CWaitAck();   
    I2CSendByte(0x12);									//设置写起始地址      
	I2CWaitAck();		
    I2CSendByte(0x00);									//清零数字调整寄存器      
	I2CWaitAck();        
	I2CStop();  
	WriteTimeOff();      
}
/********读Flash状态位程序**********/
//如果读取出的数据不正常则要重新启动或者初始化数据
/*void rState(void)
{
	I2CStart();
	I2CSendByte(0x64);
	I2CWaitAck();
	I2CSendByte(0x14);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0x65);
	I2CWaitAck();
	State = I2CReceiveByte();
	I2CNoAck();											//最后一个数据不应答
	I2CStop();
}*/
/********写Flash状态位程序**********/
/*void wState(void)
{
    WriteTimeOn();
	I2CStart();
	I2CSendByte(0x64);      
	I2CWaitAck();   
    I2CSendByte(0x14);					//设置写起始地址      
	I2CWaitAck();
	I2CSendByte(3);					//写入状态位
	I2CWaitAck();	
	I2CStop();
	WriteTimeOff();      
}*/
/********开启SD2400的I2C总线********/
static bit I2CStart(void)
{
	SDA=1;
	SCL=1;
	I2CWait();
	if(!SDA) return false;//SDA线为低电平则总线忙,退出
	SDA=0;
	I2CWait();
	if(SDA)	 return false;//SDA线为高电平则总线出错,退出
	SCL=0;
	I2CWait();
	return true;
}
/********关闭SD2400的I2C总线*******/
static void I2CStop(void)
{
	SDA=0;
	SCL=0;
	I2CWait();
	SCL=1;
	I2CWait();
	SDA=1;
}
/*********发送 ACK*********/
static void I2CAck(void)
{	
	SDA=0;
	SCL=0;
	I2CWait();
	SCL=1;
	I2CWait();
	SCL=0;
}
/*********发送NO ACK*********/
static void I2CNoAck(void)
{	
	SDA=1;
	SCL=0;
	I2CWait();
	SCL=1;
	I2CWait();
	SCL=0;
}
/*********读取ACK信号*********/
static bit I2CWaitAck(void)  //返回为:1=有ACK,0=无ACK
{
	uchar i = 0xff;
	SCL=0;
	SDA=1;
	I2CWait();
	SCL=1;
	I2CWait();
	while(SDA){
	  if((i--) == 0){	
		 SCL = 0;
		 return	false;
	  }
	}
	SCL=0;
	return true;
}
/************MCU向SD2400发送一个字节*************/
static void I2CSendByte(uchar Data) //数据从高位到低位//
{
	uchar i=8;                       
	while(i--){
		SCL=0;
		_nop_();
		SDA	= Data & 0x80;
		Data <<= 1;
		I2CWait();
		SCL=1;
		I2CWait();
	 }
	SCL=0;
}
/*********MCU从SD2400读入一字节*********/
static uchar I2CReceiveByte(void)  //数据从高位到低位//
{
	uchar i=8;
	uchar ddata=0;
	SDA=1;
	while(i--){
		ddata<<=1;          //数据从高位开始读取
		SCL=0;
		I2CWait();
		SCL=1;
		I2CWait();	   //从高位开始 ddata|=SDA;ddata<<=1
		if(SDA){
			ddata|=0x01;
		}
	}
	SCL=0;
	return ddata;
}
/******写SD2400允许程序******/
static void WriteTimeOn(void)
{		
	I2CStart();
	I2CSendByte(0x64);      
	I2CWaitAck();   
    I2CSendByte(0x10);//设置写地址10H      
	I2CWaitAck();	
	I2CSendByte(0x80);//置WRTC1=1      
	I2CWaitAck();
	I2CStop(); 
	I2CStart();
	I2CSendByte(0x64);      
	I2CWaitAck();   
    I2CSendByte(0x0F);//设置写地址0FH      
	I2CWaitAck();	
	I2CSendByte(0x84);//置WRTC2,WRTC3=1      
	I2CWaitAck();
	I2CStop(); 
}
/******写SD2400禁止程序******/
static	void WriteTimeOff(void)
{		
	I2CStart();
	I2CSendByte(0x64);      
	I2CWaitAck();   
    I2CSendByte(0x0F);//设置写地址0FH      
	I2CWaitAck();	
	I2CSendByte(0x0) ;//置WRTC2,WRTC3=0      
	I2CWaitAck();
	I2CSendByte(0x0) ;//置WRTC1=0(10H地址地址自动加1)      
	I2CWaitAck();
	I2CStop(); 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -