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

📄 rtc.c

📁 此代码包含IIC操作代码、以及怎样通过IIC读写时钟芯片的源码。
💻 C
字号:
/******************************************************************
** 文件名:	 RTC.c

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

#ifndef MASTER_FILE
#include <include.h>
#endif
#include "bian.h"

/*---------------------------------------------------
调用方式:void I2CStart(void) ﹫2003/06/06
函数说明:私有函数,I2C专用
----------------------------------------------------*/
void I2CStart(void)
{	//启动条件是SCL =1时,SDA出现一个下降沿              
	  
	SCLKL;
	SDAH;
	SCLKH;
	
	SomeNOP();  
	SomeNOP();          
	
	SDAL;
	
	SomeNOP();  //START
	SomeNOP();
	
	SCLKL;
}
/*--------------------------------------------------
调用方式:void I2CStop(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用
---------------------------------------------------*/
void I2CStop(void)
{	//停止条件:SCL = 1时,SDA出现上升沿
	SCLKL;
	
	SDAL; 
	
	SomeNOP();  
	SomeNOP();  
	SCLKH;
	
	SomeNOP();  
	SomeNOP();
	
	SDAH;	
}

/**------------------------------------------------------------------
调用方式:void SendAck(void) ﹫2003/06/06
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,应答信号。
-----------------------------------------------------------------------*/
void SendAck(void)
{
	SDAL;       //SDA=0; 
	
	SomeNOP();
	
	SCLKH;  //SCL=1;
	
	SomeNOP();
	SomeNOP();
	
	 SCLKL; //SCL=0;
}

/**--------------------------------------------------------------------------------
调用方式:void SendAck(void) ﹫2003/06/06
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,非应答信号。
**----------------------------------------------------------------------------*/
void SendNotAck(void)
{
	SDAH;   //SDA=1;
	
	SomeNOP();
	
	SCLKH;  //SCL=1;
	
	SomeNOP();
	SomeNOP(); 
	    
	SCLKL;  //SCL=0;
} 
//----------------------------------wait ack begin
uchar WaitAck(void)
{
	uchar errtime;

	errtime = 255;//因故障接收方无ACK,超时值为255。
	
	SDAH;       //SDA=1;
	
	SomeNOP();
	
	SCLKH;  //SCL=1;
	
	while (SDA)
	{
	    errtime--; 
	    if (!errtime)
	    {
	        I2CStop();          
	        return 0;
	    }
	}
	SCLKL;  //SCL=0;

	return TRUE;
}
//----------------------------------wait ack end
/**--------------------------------------------------------------------------------
调用方式:void I2CSendByte(uchar ch) ﹫2003/06/06
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
void I2CSendByte(uchar ch)
{
    uchar i = 8;    

    while (i--)
    {
        SCLKL;  //SCL=0;

        SomeNOP();

        if (ch & 0X80)
        {
            SDAH;
        }   //  SDA |= 0X20;
        else
        {
            SDAL;
        }   //SDA &= 0Xdf; //SDA=(bit)(ch&0x80);

        ch <<= 1; 

        SomeNOP();
            
        SCLKH;//SCL=1;

        SomeNOP();      //难点之一                  
        SomeNOP();
    }   
    
    SCLKL;//SCL=0; 
}

/*******************************************************************
                    向有子地址器件发送多字节数据函数
函数原型: bit  SET_RTC(uchar *s,uchar no);
功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
          地址0X64,子地址FH,0H,1H...EH,发送内容是s指向的内容,发送no个字节。
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar SET_RTC(uchar* s, uchar no)
{    
	uchar  i;

	if(SwitchRTC ==  NEW_RTC)
	{
		s[0] = s[1];
		s[1] = s[2];
		s[2] = s[3];

		//星期(0X01-0X07)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
		if((s[4]>0) && (s[4]<8))	//(1-7)星期 2004.11.04
			s[3] = s[4];		
		else
			s[3] = 1;//s[4];

		s[4] = s[5];
		s[5] = s[6];
		s[6] = s[7];
	
	    if(s[0] > 0X59) 
	       return 0;
	    if(s[1] > 0X59) 
	       return 0;
	    if(s[2] > 0X23) 
	       return 0;
	   // if(s[3] > 0X06) 
	   //    return 0; 
	    if( (s[4] > 0X31) || (s[4]==0) )
	       return 0; 
	    if( (s[5] > 0X12) || (s[5]==0) )
	       return 0;
	    if(s[6] > 0X49) 
	       return 0;
	    //--------------
	    I2CStart();               /*启动总线*/
	 
	//    I2CSendByte(0X64);            /*发送器件地址*/
	    I2CSendByte(0Xd0);            /*发送器件地址*/
	           
	    if(WaitAck() == 0)
	       return 0;  
	  //--------------------------
	   	I2CSendByte(0x00);            /*发送器件子地址*/
	    
	    if(WaitAck() == 0)
	       return 0;  
	  //-----------------
	     
	   	for(i = 0;i < no;i++)
	    	{
	          I2CSendByte(*s);               /*发送数据*/          
	          
	          if(WaitAck() == 0)
	              return 0;  
	          
	           s++;
	        }
	 
	     I2CStop();                 /*结束总线*/  
	     return TRUE;
	}
	else
	{
		s[0] = 0x20;
	    //--------------
	    if(s[1] > 0X59) 
	       return 0;
	    if(s[2] > 0X59) 
	       return 0;
	    if(s[3] > 0X23) 
	       return 0;

	   // if(s[4] > 0X06) 
	   //    return 0; 

		//星期(0X00-0X06)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
		if(s[4] > 6)	//星期 2004.11.04
			s[4] = 0;

	    if( (s[5] > 0X31) || (s[5]==0) )
	       return 0; 
	    if( (s[6] > 0X12) || (s[6]==0) )
	       return 0;
	    if(s[7] > 0X99) 
	       return 0;                
	    //--------------
	    I2CStart();               /*启动总线*/
	 
	    I2CSendByte(0X64);            /*发送器件地址*/
	           
	    if(WaitAck() == 0)
	       return 0;  
	  //--------------------------
	   	I2CSendByte(0XF0);            /*发送器件子地址*/
	    
	    if(WaitAck() == 0)
	       return 0;  
	  //-----------------
	     
	   	for(i = 0;i < no;i++)
	    	{
	          I2CSendByte(*s);               /*发送数据*/          
	          
	          if(WaitAck() == 0)
	              return 0;  
	          
	           s++;
	        }
	 
	     I2CStop();                 /*结束总线*/  
	     return TRUE;
	}
}
/**--------------------------------------------------------------------------------
调用方式:uchar I2CReceive(void) ﹫2003/06/06
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
uchar I2CReceiveByte(void)
{
    unsigned char i = 8;
    unsigned char ddata = 0;

    SDAH;//SDA=1;   

    while (i--)
    {
        ddata *= 2;        
        
        SCLKL;//SCL=0;          

        SomeNOP();
        SomeNOP();  
            
        SCLKH;//SCL=1;

        SomeNOP();  //难点之二
        SomeNOP();       

        if (SDA)
        {
            ddata++;
        }
    }
        
        SCLKL;//SCL=0;      

    SomeNOP(); 

    return ddata;
}

/*******************************************************************
                    向有子地址器件读取多字节数据函数
函数原型: bit  READ_RTC(uchar *s,uchar no);
功能:     从启动总线到发送地址(0X65),读数据,结束总线的全过程,
          分别从子地址FH,0H,1H...EH读出的内容放入s指向的存储区,读no个字节。
          如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar READ_RTC(uchar* s, uchar no)
{
    uchar i;
    uchar   xdata* sss;

	if(SwitchRTC ==  NEW_RTC)
	{
	    I2CStart();               /*启动总线*/
	
	    I2CSendByte(0Xd0);            /*发送器件子地址*/
	
	     if(WaitAck() == 0)
	       return 0;     
	    I2CSendByte(0X0);            /*发送REG地址*/
	     if(WaitAck() == 0)
	       return 0;    
		 I2CStart(); 
	
		I2CSendByte(0Xd1);            /*发送器件地址*/
	     
	     if(WaitAck() == 0)
	       return 0;     	
	
	    //---------------------------------------
	
	    for (i = 0; i < no; i++)
	    {
	        *s = I2CReceiveByte();               /*接收数据*/     
	
	        if (i != (no - 1))
	        {
	            SendAck();
	        }
	        s++;
	    }  
	
	    SendNotAck();
	    I2CStop();                    /*结束总线*/ 
	    sss = (uchar *) (s - no);
	    
	    return TRUE;
	}
	else
	{
		I2CStart();               /*启动总线*/
	      
	     I2CSendByte(0x65);            /*发送器件子地址*/
	     
	     if(WaitAck() == 0)
	       return 0;     
	     //---------------------------------------
	     
	     for(i=0;i<no;i++)
	       {
	         *s = I2CReceiveByte();               /*接收数据*/     
	        
	          if(i != (no - 1))
	          SendAck();
	          s++;
	       }  
	       
	       SendNotAck();
	       I2CStop();                    /*结束总线*/ 
	       sss = (uchar *)(s-no);	       
	 
	       return TRUE; 
	}
} 

/***********************************************************************************
*** 函 数 名: 	uchar RtcTask(void)
*** 功能描述:读取RTC
*** 参    数:  输入:	无
***            输出: 	无
*** 功能模块: 
*** 返 回 值:	1.TRUE	:正确读取RTC				
				2.FALSE :错误读取RTC
*** 模块信息: 
*************************************************************************************/
uchar RtcTask(void)
{
	if(SwitchRTC ==  NEW_RTC)
	{	
	    if (READ_RTC(MRD, 7))
		{
			MRD[7] = MRD[6];  //年
			
			MRD[6] = MRD[5];
			MRD[6] &= 0x1f;    //月
			
			MRD[5] = MRD[4]; 
			MRD[5] &= 0x3f;    //日期
			
			MRD[4] = MRD[3];
			MRD[4] &= 0x07;    //星期
			MRD[4] -= 1;    
			
			MRD[3] = MRD[2];
			MRD[3] &= 0x3f;    //小时
			
			MRD[2] = MRD[1];
			MRD[2] &= 0x7f;    //分钟
			
			MRD[1] = MRD[0];
			MRD[1] &= 0x7f;   //秒
	
			bufTime[0] = 0x32;
	 		bufTime[1] = 0x30;
			bufTime[2] = 0x30 +(MRD[7]>>4);
			bufTime[3] = 0x30 +(MRD[7]&0x0f);
	
			bufTime[4] = 0x30 +(MRD[6]>>4);
			bufTime[5] = 0x30 +(MRD[6]&0x0f);
	
			
			bufTime[6] = 0x30 + (MRD[5]>>4);
			bufTime[7] = 0x30 +(MRD[5]&0x0f);
	
			bufTime[8] = 0x30+(MRD[3]>>4);
			bufTime[9] = 0x30+(MRD[3]&0x0f);
	
			bufTime[10] = 0x30+(MRD[2]>>4);
			bufTime[11] = 0x30+(MRD[2]&0x0f);
	
			bufTime[12] = 0x30+(MRD[1]>>4);
			bufTime[13] = 0x30+(MRD[1]&0x0f);

			//星期(0X01-0X07)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
			bufTime[14] = 0x30+(MRD[4]>>4);	//星期 2004.11.04
			bufTime[15] = 0x30+(MRD[4]&0x0f);

	        return(TRUE);
	    }
	    else	//读取不正确的相应处理
	    {  
	        return(FALSE);
	    }
	}
	else
	{
		if(READ_RTC(MRD,8))
		{
			bufTime[0] = '2';
			bufTime[1] = '0';
			bufTime[2] = 0x30 +(MRD[7]>>4);
			bufTime[3] = 0x30 +(MRD[7]&0x0f);
	
			bufTime[4] = 0x30 +(MRD[6]>>4);
			bufTime[5] = 0x30 +(MRD[6]&0x0f);
	
			bufTime[6] = 0x30 + (MRD[5]>>4);
			bufTime[7] = 0x30 +(MRD[5]&0x0f);
	
			bufTime[8] = 0x30+(MRD[3]>>4);
			bufTime[9] = 0x30+(MRD[3]&0x0f);
	
			bufTime[10] = 0x30+(MRD[2]>>4);
			bufTime[11] = 0x30+(MRD[2]&0x0f);
	
			bufTime[12] = 0x30+(MRD[1]>>4);
			bufTime[13] = 0x30+(MRD[1]&0x0f);

			//星期(0X00-0X06)分别为:星期日、星期一、星期二、星期三、星期四、星期五、星期六
			bufTime[14] = 0x30+(MRD[4]>>4);	//星期 2004.11.04
			bufTime[15] = 0x30+(MRD[5]&0x0f);
			
			return(TRUE);
		}
		else	//读取不正确的相应处理
		{
			return(FALSE);
		}
	}
}

/***********************************************************************************
*** 函 数 名: 	uchar WriteRtc(void)
*** 功能描述:设置RTC
*** 参    数:  输入:	无
***            输出: 	无
*** 功能模块: 
*** 返 回 值:	1.TRUE	:正确设置RTC					
				2.FALSE	:错误设置RTC
*** 模块信息: 
*************************************************************************************/
uchar WriteRtc(void)
{
    uchar j;

	if(SwitchRTC ==  NEW_RTC)
	{
	    j = 7;
	}
	else
	{
		j = 8;
	}

	if (SET_RTC(MTD, j))
	{
	    return TRUE;
	}
	else
	{
	    return FALSE;
	}	
}


⌨️ 快捷键说明

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