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

📄 rtc-ds1302.c

📁 时钟芯片DS1302的uclinux2.4下的驱动程序
💻 C
字号:
#include <stdio.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <time.h>#include "../include/ped.h"//#include "../include/rtc.h"//#define RTC_DATA  *(unsigned char *)0xfffff439 &= 0x02; static unsigned char convert_bcd(unsigned char ch){	if (((ch & 0x0f) > 9) || (((ch>>4)&0x0f) > 9))		return 0xff;	return ((ch>>4)&0x0f)*10 + (ch&0x0f);}    void set_clk_high(){	*(unsigned char *)0xfffff43b |= 0x04;	*(unsigned char *)0xfffff438 |= 0x04;	*(unsigned char *)0xfffff439 |= 0x04;	//*(unsigned char *)0xfffff43b &= 0xfb;	}void set_clk_low(){	*(unsigned char *)0xfffff43b |= 0x04;	*(unsigned char *)0xfffff438 |= 0x04;	*(unsigned char *)0xfffff439 &= 0xfb;	//*(unsigned char *)0xfffff43b &= 0xfb;}void set_rst_high(){	*(unsigned char *)0xfffff43b |= 0x01;	*(unsigned char *)0xfffff438 |= 0x01;	*(unsigned char *)0xfffff439 |= 0x01;	//*(unsigned char *)0xfffff43b &= 0xfe;	}void set_rst_low(){	*(unsigned char *)0xfffff43b |= 0x01;	*(unsigned char *)0xfffff438 |= 0x01;	*(unsigned char *)0xfffff439 &= 0xfe;	//*(unsigned char *)0xfffff43b &= 0xfe;}void set_datout_high(){	*(unsigned char *)0xfffff413 |= 0x02;	*(unsigned char *)0xfffff410 |= 0x02;	*(unsigned char *)0xfffff411 |= 0x02;	//*(unsigned char *)0xfffff43b &= 0xfd;	}void set_datout_low(){	*(unsigned char *)0xfffff413 |= 0x02;	*(unsigned char *)0xfffff410 |= 0x02;	*(unsigned char *)0xfffff411 &= 0xfd;	//*(unsigned char *)0xfffff43b &= 0xfd;}unsigned char DS1302_Read_Byte() {	unsigned char temp,rbyte=0,A;		//set PJ1 I/O function,Input	*(unsigned char *)0xfffff413 |= 0x02;	*(unsigned char *)0xfffff410 &= 0xfd;	for(temp=8;temp > 0;temp--) 	    {		 rbyte=rbyte>>1;		 A =	*(unsigned char *)0xfffff411;	 		 if(A &= 0x02)		 	{		 		rbyte=rbyte | 0x80;		 		}		 		else		 			{		 				rbyte=rbyte & 0x7f;		 			}		 						 		set_clk_high();		 		set_clk_low();		     }	return(rbyte);}//20050110发现没有任何延迟都没有问题void DS1302_Write_Byte(unsigned char input){	unsigned char temp;	set_clk_low();  //set_rst_low();      //set_rst_high();	//set PJ1 I/O function,Outout	//*(unsigned char *)0xfffff43b |= 0x02;	//*(unsigned char *)0xfffff438 |= 0x02;//  Write data valade at clock rising edge     //set_clk_low();		for(temp=8;temp > 0;temp--) 	   {   			   if(input & 0x01)	   	{	   		set_datout_high();	   			   	}	   	else	   		{	   			set_datout_low();	   		}	   			    //DelayMs(5);	    set_clk_high();	    	    set_clk_low();	    input= input >> 1;	  }}//写DS1302时钟的有关数据void DS1302_Write(unsigned char add,unsigned char d){	  set_clk_low();    set_rst_low();        set_rst_high();    DS1302_Write_Byte(add);    DS1302_Write_Byte(d);    set_rst_low();    *(unsigned char *)0xfffff43b &= 0xf8;}//读DS1302时钟的有关数据unsigned char DS1302_Read(unsigned char add){    unsigned char a;    set_rst_low();    set_clk_low();    set_rst_high();    DS1302_Write_Byte(add);        a=DS1302_Read_Byte();    set_rst_low();    *(unsigned char *)0xfffff43b &= 0xf8;    return a;}void DS1302_START(void){    set_rst_low();	      set_clk_low();        set_rst_high();	    DS1302_Write_Byte(0x80);    DS1302_Write_Byte(0x00);    set_rst_low();}/////////////////////////////////////////////////////////////////////////////////////  原型:   void    DS1302_Rtime(unsigned char *a)//  功能:   用单字节方式读DS1302时钟的所有数据,内部的无限制//          包括CONTROL 位和CHG位//  输入:   *a  接收数据的地址//  输出:   9位数据,包括CONTROL 和CHG///////////////////////////////////////////////////////////////////////////////////void    DS1302_Rtime(unsigned char *a){//秒-0   *(a+5)=DS1302_Read(0x81);//分-1    *(a+4)=DS1302_Read(0x83);    //时-2    *(a+3)=DS1302_Read(0x85);    //日-3    *(a+2)=DS1302_Read(0x87);    //月-4    *(a+1)=DS1302_Read(0x89);  //年-6    *a=DS1302_Read(0x8d);    //星期-5   // *(a+6)=DS1302_Read(0x8b);    //CONTROL-7  //  *(a+7)=DS1302_Read(0x8f);    //充电-8    //*(a+8)=DS1302_Read(0x91);    }/////////////////////////////////////////////////////////////////////////////////////  原型:   void    DS1302_Wtime(unsigned char *a)//  功能:   用单字节方式写DS1302时钟的所有数据,内部的无限制//          包括CONTROL 位和CHG位//  输入:   *a  接收数据的地址/////////////////////////////////////////////////////////////////////////////////////set YY MM DD HH MI SE WEvoid    DS1302_Wtime(unsigned char *a){//秒-0    DS1302_Write(0x80,*a);//分-1    DS1302_Write(0x82,*(a+1));    //时-2    DS1302_Write(0x84,*(a+2));    //日-3    DS1302_Write(0x86,*(a+3));    //月-4    DS1302_Write(0x88,*(a+4));    //年-6    DS1302_Write(0x8C,*(a+5));    //星期-5    DS1302_Write(0x8A,*(a+6));        //CONTROL-7  //  DS1302_Write(0x8E,*(a+7));    //充电-8   // DS1302_Write(0x90,*(a+8));    }/********************************************************************				设置系统日期和时间unsigned char	SetTime(unsigned char	*TimeBuf);功能:	设置系统日期和时间输入:	TimeBuf:日期时间参数的指针,格式为YYMMDDhhmmss,参数为BCD码,共6个字节长返回:	0-Success	1-参数中年份非法	2-参数中月份非法	3-参数中日份非法	4-参数中小时份非法	5-参数中分钟非法	6-参数中秒钟非法	0xff-参数中有非数字项。********************************************************************/int	SetTime(unsigned char	*TimeBuf){	unsigned char	TmpBuf[7];	unsigned char str[20];	unsigned char cDaysInMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};	unsigned char wYear;	unsigned char bMon, bDay;	unsigned long i,dwDays; 	struct tm tp;	time_t t;	memcpy(str, TimeBuf, 7);	//file://YXF 2001/06/05	//Year--up to 2100	if(((str[0]&0xf0)> 0x20)||((str[0]&0x0f)>9))		return 1;	//file://Tong 2001/02/21	for(i=1; i<6; i++)	{		if (((str[i] & 0xf0) > 0x90) || ((str[i] & 0x0f) > 9))			return 0xff;	}	wYear = (str[0]>>4)*10 + (str[0]&0x0f);	bMon = (str[1]>>4)*10 + (str[1]&0x0f);	bDay = (str[2]>>4)*10 + (str[2]&0x0f);	if(wYear >= 50)		wYear += 1900;	else		wYear += 2000;	if ((bMon <= 0) || (bMon > 12))		return 2;	if ((bDay <= 0) || (bDay > cDaysInMonth[bMon-1]))	{		if (bMon != 2)			return 3;		if ( (wYear%400==0) || ((wYear%4==0)&&(wYear%100!=0)) )		{  // Leap year			if ((bDay > 29)||(bDay<=0))			{				return 3;   // large than 29 or equals to 0			}		}		else		{			return 3;    // Not leap year large than 28		}	}	if (str[3] >= 0x24)		return 4;	if (str[4] >= 0x60)		return 5;	if (str[5] >= 0x60)		return 6;	dwDays = 0;	for (i=1950; i<wYear; i++)	{		dwDays += 365;		if ( (i%400==0) || ((i%4==0)&&(i%100!=0)) )			dwDays ++;	}	for(i=1; i<bMon; i++)		dwDays += cDaysInMonth[i-1];	dwDays += bDay;	if (bMon > 2)	{		if ( (wYear%400==0) || ((wYear%4==0)&&(wYear%100!=0)) )			dwDays ++;	}	if (str[5] == 0x59)		str[5] = 0x58;	str[6] = (unsigned char)((dwDays-1)%7);	if (str[6] == 0)	{		str[6] = 7;	}	tp.tm_year = str[0]+100;	tp.tm_mon = str[1]-1;	tp.tm_mday = str[2];	tp.tm_hour = str[3];	tp.tm_min = str[4];	tp.tm_sec = str[5];	tp.tm_isdst = 0;	t = mktime(&tp);	if (t == (time_t)(-1))		return -1;	if (stime(&t) == -1)		return -1;		TmpBuf[0]=str[5]; //second	TmpBuf[1]=str[4]; //minute	TmpBuf[2]=str[3]; //hour	TmpBuf[3]=str[2]; //day	TmpBuf[4]=str[1]; //month	//TmpBuf[5]=str[6]; //week	TmpBuf[5]=str[0]; //year	DS1302_Wtime(TmpBuf);		return 0;}void GetTime(unsigned char *str){	struct tm *tp;	time_t t;	int i;	time(&t);	tp = localtime(&t);	i = tp->tm_year-100;	str[0] = (((i/10)<<4) & 0xf0) | (i % 10);	i = tp->tm_mon+1;	str[1] = (((i/10)<<4) & 0xf0) | (i % 10);	i = tp->tm_mday;	str[2] = (((i/10)<<4) & 0xf0) | (i % 10);	i = tp->tm_hour;	str[3] = (((i/10)<<4) & 0xf0) | (i % 10);	i = tp->tm_min;	str[4] = (((i/10)<<4) & 0xf0) | (i % 10);	i = tp->tm_sec;	str[5] = (((i/10)<<4) & 0xf0) | (i % 10);	i = tp->tm_wday;	if (i == 0)		i = 7;	str[6] = (((i/10)<<4) & 0xf0) | (i % 10);}/********************************************************************				读取实时时钟当前日期和时间void GetRTCTime(unsigned char *str)功能:	读取实时时钟当前日期和时间输入:	str:7字节时钟数据地址(秒、分、时、日、月、年)返回:	None********************************************************************/void GetRTCTime(unsigned char *str){	unsigned char i;/*	for(i=0; i<7; i++)	{		str1[i] = DS1302_Read(0x81+i+i);				str[i] = (str1[i] >> 4)*10 + (str1[i] & 0x0f);			}*/		DS1302_Rtime(str);		//如果读出时间秒的最高位为1,说明时钟已经停止,重新设置。	while(str[0] & 0x80)	{		str[0] &= 0x7f;				DS1302_Wtime(str);		DS1302_Rtime(str);	}/*	for(i=0; i<7; i++)	{		str[i] = convert_bcd(str[i]);					}*/	}

⌨️ 快捷键说明

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