当前位置: 代码迷 >> 单片机 >> 单片机温习程序例举005 - DS1302时钟芯片
  详细解决方案

单片机温习程序例举005 - DS1302时钟芯片

热度:126   发布时间:2016-04-28 15:00:33.0
单片机复习程序例举005 -- DS1302时钟芯片

用AT89S52单片机、DS1302时钟芯片、1602LCD做一个电子表 。各文件例举如下:

1、main()函数所在文件部分:

/****************************************************************************** *	说明:AT89S52芯片,12M晶振 *	外设:HD44780控制的1602LCD 和 DS1302时钟芯片 *	本程序:做一个电子时钟,显示日历,时间 *			K1设置确认键,K2设置位选择键,K3设置参数减,K4设置参数加 ******************************************************************************///#include <reg52.h>//#include <intrins.h>#include "DELAY_FUNCTION_FELL.h"#include "HD44780_1602LCD.h"#include "DS1302_SPIdriver.h"#include "DIY_clock.h"//用户要显示的字符串unsigned char calendar[17] = "Data:2000-00-00" ; //calendar[i] 年:i = 7,8 月:i= 10,11 日:i=13,14unsigned char clock_time[17] = "00:00:00" ;	//clock_time[i] 时:i=0,1 分:i=3,4 秒i=6,7/******************************************************************************===============================================================================                       void main(void)函数部分===============================================================================*******************************************************************************/void main(void){	//1、定义相关变量//	unsigned char i ;	//2、初始化	HD44780_1602LCD_Init() ;	DS1302_Init() ;	//3、在HD44780控制的1602LCD上显示时钟信息	Clear_Screen() ;	while(1)	{		Get_Curren_Time() ;	//获取当前时间		Dis_Str(0 , 1 , calendar) ; 		Dis_Str(1 , 5 , clock_time) ;		User_Set_Time() ; //用户通过按键设置时间								 					}					}/****************************************************************************** *	名称: *	功能: *	参数: *	返回: ******************************************************************************/

2、实现电子时钟功能设置部分的函数

//DIY_clock.c#include "DIY_clock.h"//定义字符数组显示数字unsigned char code digit[10]={"0123456789"};   //用户自定义的字符编码方式:在8*8的点阵中选“右上角”的“5列*7行”点阵 存放数据//unsigned char code user_str0[] = {0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};/* 自定义字符 ℃ *//****************************************************************************** *	名称:Get_Curren_Time() *	功能:获取当前时间 *	参数:无 *	返回:无 ******************************************************************************/ void Get_Curren_Time(void) {	int temp ;	temp = Read_DS1302_Year() ;	calendar[7] = digit[temp / 10] ;	calendar[8] = digit[temp % 10] ;	temp = Read_DS1302_Month() ;	calendar[10] = digit[temp / 10] ;	calendar[11] = digit[temp % 10] ;	temp = Read_DS1302_Day() ;	calendar[13] = digit[temp / 10] ;	calendar[14] = digit[temp % 10] ;	temp = Read_DS1302_Hour() ;	clock_time[0] = digit[temp / 10] ;	clock_time[1] = digit[temp % 10] ; 	temp = Read_DS1302_Minute() ;	clock_time[3] = digit[temp / 10] ;	clock_time[4] = digit[temp % 10] ; 	temp = Read_DS1302_Second() ;	clock_time[6] = digit[temp / 10] ;	clock_time[7] = digit[temp % 10] ; }/****************************************************************************** *	名称:User_Set_Time_Second() *	功能:本地用户通过按键设置 秒位 *	参数:无 *	返回:无 ******************************************************************************/void User_Set_Time_Second(void){	int temp , switch_temp ;	switch_temp = 1 ;	//程序停留在某一个设置为的开关	/*------按一次 K1 设置:时、分、秒-------------------*/	/*``````设置:second`````````````````````*/	temp = Read_DS1302_Second() ;	while(switch_temp)	{		if(K4 == 0)  //增加 秒		{			delay1ms(15) ;			if(K4 == 0)			{				while(K4 == 0) { ; } //等待按键释放				temp++ ;				if(temp == 60)				{					temp = 0 ;				}			}					}		if(K3 == 0)  //减少 秒		{			delay1ms(15) ;			if(K3 == 0)			{				while(K3 == 0) { ; } //等待按键释放				temp-- ;				if(temp == 0)				{					temp = 60 ;				}			}					}		DS1302_Set_Second(temp) ;		Get_Curren_Time() ;		Dis_Str(1 , 5 , clock_time) ;		//按 K1 键 跳出设置 秒 的循环		if(K1 == 0)		{			delay1ms(15) ;			if(K1 == 0)			{				while(K1 == 0) { ; } //等待按键释放				switch_temp = 0 ;			}		}						} }/****************************************************************************** *	名称:User_Set_Time_Minute() *	功能:本地用户通过按键设置 分钟位 *	参数:无 *	返回:无 ******************************************************************************/void User_Set_Time_Minute(void){	int temp , switch_temp ;	switch_temp = 1 ;	//程序停留在某一个设置为的开关	/*------按一次 K1 设置:时、分、秒-------------------*/	/*``````设置:minute`````````````````````*/	temp = Read_DS1302_Minute() ;	while(switch_temp)	{		if(K4 == 0)  //增加 分钟值		{			delay1ms(15) ;			if(K4 == 0)			{				while(K4 == 0) { ; } //等待按键释放				temp++ ;				if(temp == 60)				{					temp = 0 ;				}			}					}		if(K3 == 0)  //减少 分钟值		{			delay1ms(15) ;			if(K3 == 0)			{				while(K3 == 0) { ; } //等待按键释放				temp-- ;				if(temp == 0)				{					temp = 60 ;				}			}					}		DS1302_Set_Minute(temp) ;		Get_Curren_Time() ;		Dis_Str(1 , 5 , clock_time) ;		//按 K1 键 跳出设置 分钟 的循环		if(K1 == 0)		{			delay1ms(15) ;			if(K1 == 0)			{				while(K1 == 0) { ; } //等待按键释放				switch_temp = 0 ;			}		}						} }/****************************************************************************** *	名称:User_Set_Time_Hour() *	功能:本地用户通过按键设置 分钟位 *	参数:无 *	返回:无 ******************************************************************************/void User_Set_Time_Hour(void){	int temp , switch_temp ;	switch_temp = 1 ;	//程序停留在某一个设置为的开关	/*------按一次 K1 设置:时、分、秒-------------------*/	/*``````设置:hour`````````````````````*/	temp = Read_DS1302_Hour() ;	while(switch_temp)	{		if(K4 == 0)  //增加 分钟值		{			delay1ms(15) ;			if(K4 == 0)			{				while(K4 == 0) { ; } //等待按键释放				temp++ ;				if(temp == 24)				{					temp = 0 ;				}			}					}		if(K3 == 0)  //减少 分钟值		{			delay1ms(15) ;			if(K3 == 0)			{				while(K3 == 0) { ; } //等待按键释放				temp-- ;				if(temp == 0)				{					temp = 24 ;				}			}					}		DS1302_Set_Hour(temp) ;		Get_Curren_Time() ;		Dis_Str(1 , 5 , clock_time) ;		//按 K1 键 跳出设置 分钟 的循环		if(K1 == 0)		{			delay1ms(15) ;			if(K1 == 0)			{				while(K1 == 0) { ; } //等待按键释放				switch_temp = 0 ;			}		}						} }/****************************************************************************** *	名称:User_Set_Time_Day() *	功能:本地用户通过按键设置 分钟位 *	参数:无 *	返回:无 ******************************************************************************/void User_Set_Time_Day(void){	int temp , switch_temp ;	switch_temp = 1 ;	//程序停留在某一个设置为的开关	/*------按一次 K1 设置:时、分、秒-------------------*/	/*``````设置:day`````````````````````*/	temp = Read_DS1302_Day() ;	while(switch_temp)	{		if(K4 == 0)  //增加 分钟值		{			delay1ms(15) ;			if(K4 == 0)			{				while(K4 == 0) { ; } //等待按键释放				temp++ ;				if(temp == 31)				{					temp = 0 ;				}			}					}		if(K3 == 0)  //减少 分钟值		{			delay1ms(15) ;			if(K3 == 0)			{				while(K3 == 0) { ; } //等待按键释放				temp-- ;				if(temp == 0)				{					temp = 31 ;				}			}					}		DS1302_Set_Day(temp) ;		Get_Curren_Time() ;		Dis_Str(1 , 5 , clock_time) ;		Dis_Str(0 , 1 , calendar) ;		//按 K1 键 跳出设置 分钟 的循环		if(K1 == 0)		{			delay1ms(15) ;			if(K1 == 0)			{				while(K1 == 0) { ; } //等待按键释放				switch_temp = 0 ;			}		}						} }/****************************************************************************** *	名称:User_Set_Time_Month() *	功能:本地用户通过按键设置 分钟位 *	参数:无 *	返回:无 ******************************************************************************/void User_Set_Time_Month(void){	int temp , switch_temp ;	switch_temp = 1 ;	//程序停留在某一个设置为的开关	/*------按一次 K1 设置:时、分、秒-------------------*/	/*``````设置:month`````````````````````*/	temp = Read_DS1302_Month() ;	while(switch_temp)	{		if(K4 == 0)  //增加 分钟值		{			delay1ms(15) ;			if(K4 == 0)			{				while(K4 == 0) { ; } //等待按键释放				temp++ ;				if(temp == 12)				{					temp = 0 ;				}			}					}		if(K3 == 0)  //减少 分钟值		{			delay1ms(15) ;			if(K3 == 0)			{				while(K3 == 0) { ; } //等待按键释放				temp-- ;				if(temp == 0)				{					temp = 12 ;				}			}					}		DS1302_Set_Month(temp) ;		Get_Curren_Time() ;		Dis_Str(1 , 5 , clock_time) ;		Dis_Str(0 , 1 , calendar) ;		//按 K1 键 跳出设置 分钟 的循环		if(K1 == 0)		{			delay1ms(15) ;			if(K1 == 0)			{				while(K1 == 0) { ; } //等待按键释放				switch_temp = 0 ;			}		}						} }/****************************************************************************** *	名称:User_Set_Time_Year() *	功能:本地用户通过按键设置 分钟位 *	参数:无 *	返回:无 ******************************************************************************/void User_Set_Time_Year(void){	int temp , switch_temp ;	switch_temp = 1 ;	//程序停留在某一个设置为的开关	/*------按一次 K1 设置:时、分、秒-------------------*/	/*``````设置:year`````````````````````*/	temp = Read_DS1302_Year() ;	while(switch_temp)	{		if(K4 == 0)  //增加 分钟值		{			delay1ms(15) ;			if(K4 == 0)			{				while(K4 == 0) { ; } //等待按键释放				temp++ ;				if(temp == 99)				{					temp = 0 ;				}			}					}		if(K3 == 0)  //减少 分钟值		{			delay1ms(15) ;			if(K3 == 0)			{				while(K3 == 0) { ; } //等待按键释放				temp-- ;				if(temp == 0)				{					temp = 99 ;				}			}					}		DS1302_Set_Year(temp) ;		Get_Curren_Time() ;		Dis_Str(1 , 5 , clock_time) ;		Dis_Str(0 , 1 , calendar) ;		//按 K1 键 跳出设置 分钟 的循环		if(K1 == 0)		{			delay1ms(15) ;			if(K1 == 0)			{				while(K1 == 0) { ; } //等待按键释放				switch_temp = 0 ;			}		}						} }/****************************************************************************** *	名称:User_Set_Time() *	功能:本地用户通过按键设置时钟日历 *	参数:无 *	返回:无 ******************************************************************************/void User_Set_Time(void){	int temp , switch_temp ;	int set_bit = 0 ;	/*------1、按一次 K1 键,进入设置环节------------------------------*/	if(K1 == 0)	{		delay1ms(15) ;  //按键消抖		if(K1 == 0)		{			while(K1 == 0)	{ ; } //等待按键释放			/*------2、按 K2 键,通过设置num,确定设置的是时钟的哪一位---*/			switch_temp = 1 ;			while(switch_temp)			{				//将set_bit打印到1602lcd上,判断要设置哪一位时钟信息				Dis_Char(1,0,'F') ;				Dis_Char(1,1,digit[set_bit]) ;				Dis_Char(1,2,':') ;				if(K2 == 0)				{					delay1ms(10) ;					if(K2 == 0)					{						delay1ms(7) ;						if(K2 == 0)						{							while(K2 == 0)	{ ; } //等待按键释放							set_bit++ ;							if(set_bit == 6)							{								set_bit = 0 ;							}							}										}				}				//按 K1 跳出设置num的循环				if(K1 == 0)				{					delay1ms(15) ;					if(K1 == 0)					{						while(K1 == 0)	{ ; } //等待按键释放						switch_temp = 0 ;					}				}			}			/*------3、根据 set_bit 的值调用不同的函数,对时钟进行设置---*/			switch(set_bit)			{				case 0 ://设置second位					User_Set_Time_Second() ;					break;				case 1 ://设置minute位					User_Set_Time_Minute() ;					break;				case 2 ://设置hour位					User_Set_Time_Hour() ;					break;				case 3 ://设置day位					User_Set_Time_Day() ;					break;				case 4 ://设置month位					User_Set_Time_Month() ;					break;				case 5 ://设置year位					User_Set_Time_Year() ;					break;				default ://其他值不设置					break;			}		}	}	/*------4、清除1602LCD屏幕上的设置标志位-----------------------------*/	Dis_Char(1,0,' ') ;	Dis_Char(1,1,' ') ;	Dis_Char(1,2,' ') ;}/****************************************************************************** *	名称: *	功能: *	参数: *	返回: ******************************************************************************/
//DIY_clock.h#ifndef __DIY_CLOCK_H__#define __DIY_CLOCK_H__#include <reg52.h>#include <intrins.h>#include "DELAY_FUNCTION_FELL.h"#include "HD44780_1602LCD.h"#include "DS1302_SPIdriver.h"sbit K1 = P1^4 ;	//User设置时间的开关sbit K2 = P1^5 ;	//设置参数,确定具体设置时钟的哪一位sbit K3 = P1^6 ;	//设置位的值递减sbit K4 = P1^7 ;	//设置位的值递增extern unsigned char calendar[17] ;extern unsigned char clock_time[17] ; void Get_Curren_Time(void) ; void User_Set_Time_Second(void) ; void User_Set_Time_Minute(void) ; void User_Set_Time_Hour(void) ; void User_Set_Time_Day(void) ; void User_Set_Time_Month(void) ; void User_Set_Time_Year(void) ; void User_Set_Time(void) ;#endif

3、DS1302时钟芯片配置文件

//DS1302_SPIdriver.c#include "DS1302_SPIdriver.h"/*****************************************************函数功能:向1302写一个字节数据入口参数:x***************************************************/ void Write1302(unsigned char dat){  unsigned char i;   SCLK=0;            //拉低SCLK,为脉冲上升沿写入数据做好准备  delay1us(2);       //稍微等待,使硬件做好准备  for(i=0;i<8;i++)      //连续写8个二进制位数据    {	     DATA=dat&0x01;    //取出dat的第0位数据写入1302  低位在前,高位在后		 delay1us(2);       //稍微等待,使硬件做好准备		 SCLK=1;           //上升沿写入数据		 delay1us(2);      //稍微等待,使硬件做好准备		 SCLK=0;           //重新拉低SCLK,形成脉冲		 dat>>=1;          //将dat的各数据位右移1位,准备写入下一个数据位	  }	 }/*****************************************************函数功能:根据命令字,向1302写一个字节数据入口参数:Cmd,储存命令字;dat,储存待写的数据***************************************************/ void WriteSet1302(unsigned char Cmd,unsigned char dat) {	          RST=0;           //禁止数据传递        SCLK=0;          //确保写数居前SCLK被拉低	    RST=1;           //启动数据传输	    delay1us(2);     //稍微等待,使硬件做好准备	    Write1302(Cmd);  //写入命令字	    Write1302(dat);  //写数据	    SCLK=1;          //将时钟电平置于高电平状态	    RST=0;           //禁止数据传递 }/*****************************************************函数功能:从1302读一个字节数据入口参数:x***************************************************/  unsigned char Read1302(void) {    unsigned char i,dat;	delay1us(2);       //稍微等待,使硬件做好准备	for(i=0;i<8;i++)   //连续读8个二进制位数据	 {	 dat>>=1;		 if(DATA==1)    //如果读出的数据是1		 dat|=0x80;    //将1取出,写在dat的最高位		 SCLK=1;       //将SCLK置于高电平,为下降沿读出		 delay1us(2);  //稍微等待		 SCLK=0;       //拉低SCLK,形成脉冲下降沿		 delay1us(2);  //稍微等待	  }	   return dat;        //将读出的数据返回}  /*****************************************************函数功能:根据命令字,从1302读取一个字节数据入口参数:Cmd***************************************************/ unsigned char  ReadSet1302(unsigned char Cmd) {  unsigned char dat;  RST=0;                 //拉低RST  SCLK=0;                //确保写数居前SCLK被拉低  RST=1;                 //启动数据传输  Write1302(Cmd);       //写入命令字  dat=Read1302();       //读出数据  SCLK=1;              //将时钟电平置于已知状态  RST=0;               //禁止数据传递  return dat;          //将读出的数据返回}/****************************************************************************** *	名称:DS1302_Set_Second() *	功能:设置时钟 秒 位 *	参数:int second *	返回:无 ******************************************************************************/ void DS1302_Set_Second(int second) { 	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 	   	WriteSet1302(0x80,((second/10)<<4|(second%10)));   //根据写秒寄存器命令字,写入秒的初始值		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令 } /****************************************************************************** *	名称:DS1302_Set_Minute() *	功能:设置时钟 分 位 *	参数:int minute *	返回:无 ******************************************************************************/ void DS1302_Set_Minute(int minute) { 	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 		WriteSet1302(0x82,((minute/10)<<4|(minute%10)));   //根据写分寄存器命令字,写入分的初始值		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令 } /****************************************************************************** *	名称:DS1302_Set_Hour() *	功能:设置时钟 时 位 *	参数:int hour *	返回:无 ******************************************************************************/ void DS1302_Set_Hour(int hour) { 	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 		WriteSet1302(0x84,((hour/10)<<4|(hour%10))); //根据写小时寄存器命令字,写入小时的初始值		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令 } /****************************************************************************** *	名称:DS1302_Set_Day() *	功能:设置时钟 日 位 *	参数:int day *	返回:无 ******************************************************************************/ void DS1302_Set_Day(int day) { 	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 		WriteSet1302(0x86,((day/10)<<4|(day%10))); //根据写日寄存器命令字,写入日的初始值		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令 } /****************************************************************************** *	名称:DS1302_Set_Month() *	功能:设置时钟 月 位 *	参数:int month *	返回:无 ******************************************************************************/ void DS1302_Set_Month(int month) { 	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 		WriteSet1302(0x88,((month/10)<<4|(month%10))); //根据写月寄存器命令字,写入月的初始值		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令 } /****************************************************************************** *	名称:DS1302_Set_Weekday() *	功能:设置时钟 星期 位 *	参数:int weekday *	返回:无 ******************************************************************************/ void DS1302_Set_Weekday(int weekday) { 	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 		WriteSet1302(0x8a,( weekday%7 ));  //根据写星期寄存器命令字,写入星期的初始值		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令 } /****************************************************************************** *	名称:DS1302_Set_Year() *	功能:设置时钟 年 位 *	参数:int year *	返回:无 ******************************************************************************/ void DS1302_Set_Year(int year) { 	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 		WriteSet1302(0x8c,((year/10)<<4|(year%10)));  //根据写年寄存器命令字,写入年的初始值		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令 }/*****************************************************函数功能: 1302进行初始化设置***************************************************/ void DS1302_Init(void){	  unsigned char flag;       flag= ReadSet1302(0x81);	if(flag&0x80)		{      //判断时钟芯片是否关闭	    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 	   	WriteSet1302(0x80,((55/10)<<4|(55%10)));   //根据写秒寄存器命令字,写入秒的初始值		WriteSet1302(0x82,((59/10)<<4|(59%10)));   //根据写分寄存器命令字,写入分的初始值		WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值		WriteSet1302(0x86,((5/10)<<4|(5%10))); //根据写日寄存器命令字,写入日的初始值		WriteSet1302(0x88,((4/10)<<4|(4%10))); //根据写月寄存器命令字,写入月的初始值		WriteSet1302(0x8a,( 6%7 ));  //根据写星期寄存器命令字,写入星期的初始值		WriteSet1302(0x8c,((14/10)<<4|(14%10)));  //根据写年寄存器命令字,写入年的初始值		WriteSet1302(0x90,0xa5);                //打开充电功能 选择2K电阻充电方式		WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令	}  }/****************************************************************************** *	名称:Read_DS1302_Second() *	功能:读DS1302的 秒 位 *	参数:无 *	返回:second ******************************************************************************/ int Read_DS1302_Second(void) { 	  int second ;	  unsigned char ReadValue ;  	  ReadValue = ReadSet1302(0x81);   //从秒寄存器读数据     second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化十进制数	 return second ; } /****************************************************************************** *	名称:Read_DS1302_Minute() *	功能:读DS1302的 分 位 *	参数:无 *	返回:minute ******************************************************************************/ int Read_DS1302_Minute(void) { 	  int minute ;	  unsigned char ReadValue ;	  ReadValue = ReadSet1302(0x83);  //从分寄存器读      minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化	  return minute ;  } /****************************************************************************** *	名称:Read_DS1302_Hour() *	功能:读DS1302的 时 位 *	参数:无 *	返回:hour ******************************************************************************/ int Read_DS1302_Hour(void) { 	  int hour ;	  unsigned char ReadValue ;     ReadValue = ReadSet1302(0x85);  //从分寄存器读     hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化	 return hour ;  } /****************************************************************************** *	名称:Read_DS1302_Day() *	功能:读DS1302的 日 位 *	参数:无 *	返回:day ******************************************************************************/ int Read_DS1302_Day(void) { 	  int day ;	  unsigned char ReadValue ;     ReadValue = ReadSet1302(0x87);  //从分寄存器读     day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化	 return day ;   } /****************************************************************************** *	名称:Read_DS1302_Month() *	功能:读DS1302的 月 位 *	参数:无 *	返回:month ******************************************************************************/ int Read_DS1302_Month(void) { 	  int month ;	  unsigned char ReadValue ;	  ReadValue = ReadSet1302(0x89);  //从月寄存器读      month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化	  return month ; } /****************************************************************************** *	名称:Read_DS1302_Weekday() *	功能:读DS1302的 星期 位 *	参数:无 *	返回:weekday ******************************************************************************/ int Read_DS1302_Weekday(void) { 	  int weekday ;	  unsigned char ReadValue ; 	  ReadValue = ReadSet1302(0x81);   //从星期寄存器读数据      weekday = ReadValue&0x0F ;//将读出数据转化	  return weekday ;  } /****************************************************************************** *	名称:Read_DS1302_Year() *	功能:读DS1302的 年 位 *	参数:无 *	返回:year ******************************************************************************/ int Read_DS1302_Year(void) { 	  int year ;	  unsigned char ReadValue ;	  ReadValue = ReadSet1302(0x8d);  //从年寄存器读      year = ((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化	  return year ;  }
//DS1302_SPIdriver.h#ifndef __SPIDRIVER_H__#define __SPIDRIVER_H__#include<reg52.h>     //包含单片机寄存器的头文件#include<intrins.h>   //包含_nop_()函数定义的头文件#include "DELAY_FUNCTION_FELL.h"sbit SCLK=P1^0;   //位定义1302芯片的接口,时钟输出端口定义在P1.0引脚sbit DATA=P1^1;   //位定义1302芯片的接口,数据输出端定义在P1.1引脚sbit RST=P1^2;    //位定义1302芯片的接口,复位端口定义在P1.2引脚 void Write1302(unsigned char dat) ;	//向DS1302写一个字节的数据(或指令) unsigned char Read1302(void) ;	//从DS1302中读一个字节的数据 void WriteSet1302(unsigned char Cmd,unsigned char dat) ;//根据命令字,向1302写一个字节数据 unsigned char  ReadSet1302(unsigned char Cmd) ; //根据命令字,从1302读取一个字节数据 void DS1302_Set_Second(int second) ; //设置秒 void DS1302_Set_Minute(int minute) ;	//设置分 void DS1302_Set_Hour(int hour) ;	//设置时 void DS1302_Set_Day(int day) ;	//设置日 void DS1302_Set_Month(int month) ;	//设置月 void DS1302_Set_Weekday(int weekday) ;	//设置星期 void DS1302_Set_Year(int year) ;	//设置年  void DS1302_Init(void) ; //对1302进行初始化设置 int Read_DS1302_Second(void)	; int Read_DS1302_Minute(void) ;  int Read_DS1302_Hour(void) ;  int Read_DS1302_Day(void) ; int Read_DS1302_Month(void) ;  int Read_DS1302_Weekday(void) ; int Read_DS1302_Year(void) ;#endif

4、HD44780控制的1602LCD部分的配置文件

/************************************************************************************************** * 	HD44780_1602LCD配置文件名:HD44780_1602LCD.c      *	和HD44780_1602LCD.h配套使用 *	本程序当时是依据AT89S52单片机开发板写的 *	RS R/W E 这三位引脚分别和单片机引脚 P2^0 P2^1 P2^2 相连 *	八位数据引脚DB0……DB7分别和单片机的P0端口的P0^0……P0^7相连 (BF位其实就对应DB7引脚和P0^7相连) *	将此文件来驱动1602LCD时,只需更改下面的位定义和数据线的端口号即可 *	对于HD44780控制的1602LCD的详细资料和11条指令的描述参考一下连接 *	http://blog.csdn.net/dragon12345666/article/details/22819827 **************************************************************************************************/#include"HD44780_1602LCD.h"/****************************************************************************** *	名称:Busy_Test() *	功能:检测HD44780控制的1602LCD是否处于忙状态 *	参数:无							    *	返回:bit result  忙则返回 1 , 不忙则返回 0 。 ******************************************************************************/bit Busy_Test(void){	//1、定义变量,存储返回值	bit result ;	//2、读状态位	RS = 0 ; RW = 1 ; 	E = 1 ;	_nop_() ; _nop_() ; _nop_() ; _nop_() ;	 //延时4个机器周期,给硬件响应,											 //即:使E=1;稳定	result = BF ;	//将忙状态位BF的值读给函数要返回的变量	//3、将时能位E复位到低电平	E = 0 ;	//4、将忙状态位读的结果作为函数的参数返回	return result ;} /****************************************************************************** *	名称:Write_Com() *	功能:向HD44780写控制1602LCD的控制指令 *	参数:unsigned char dictate *	返回:无 ******************************************************************************/ void Write_Com(unsigned char dictate) { 	//1、检测LCD忙状态,忙,则等待	while(Busy_Test() == 1) { ; }	//2、向HD44780控制的1602LCD写控制指令		/*----2.1、操作对象是指令,执行对象:写入----------------------------*/			RS = 0 ;		    RW = 0 ;		/*----2.2、在E 为 0 时,先将指令数据写到P0口的DB0--DB7数据线上-------*/			E = 0 ;			_nop_() ; //给硬件反应时间,等待E = 0 ;稳定 			_nop_() ;			P0 = dictate ;	//将指令先暂时写到数据线上			_nop_() ; //确保硬件把指令数据写完了			_nop_() ; 			_nop_() ; 			_nop_() ; 		/*----2.3、在E 为 1 时,将数据线上的指令数据写到DH44780的寄存器里----*/			E = 1 ;			_nop_(); _nop_(); _nop_(); _nop_(); //等待 E = 1 稳定		/*----2.4、在E 为 下降沿 时,执行写入的指令--------------------------*/			E = 0 ;	//从 E = 1 到 E = 0 产生下降沿,HD44780执行指令 }/****************************************************************************** *	名称:Write_Address() *	功能:通过指令来控制第一个要显示的字符或下一个即将要显示的字符在LCD上的位置 *	参数:unsigned char addr  在LCD上要显示的位置 *	返回:无 ******************************************************************************/void Write_Address(unsigned char addr){	//向HD44780写指令8:设定DDRAM地址的指令。	//即:即将要显示的字符在1602LCD上的指令需要的地址 = 0x80|(字符在LCD屏幕上的位置)	Write_Com(0x80|addr) ;}/****************************************************************************** *	名称:Write_Data() *	功能:1、向HD44780控制的1602LCD写要显示的字符数据; *		  2、向CGRAM中,对应地址的存储单元写用户自定义的字符数据 *	参数:unsigned char char_data 要显示的字符(其实字符的值和它的ASCII码值一样) *	返回:无 ******************************************************************************/void Write_Data(unsigned char char_data){	//1、检测HD44780控制的1602LCD忙状态位,忙,则等待	while(Busy_Test() == 1) { ; }	//2、向HD44780控制的1602LCD写要显示的字符数据		/*----2.1、操作对象是数据,执行对象:写入----------------------------*/			RS = 1 ;		    RW = 0 ;		/*----2.1、在E 为 0 时,先将字符数据写到P0口的DB0--DB7数据线上-------*/			E = 0 ;			_nop_() ; _nop_() ; //给硬件反应时间,等待E = 0 ;稳定			P0 = char_data ;	//将字符数据先暂时写到数据线上			_nop_() ; _nop_() ; _nop_() ; _nop_() ; //确保硬件把字符数据写完了		/*----2.2、在E 为 1 时,将数据线上的字符数据写到DH44780的寄存器里----*/			E = 1 ;			_nop_(); _nop_(); _nop_(); _nop_(); //等待 E = 1 稳定		/*----2.3、在E 为 下降沿 时,执行写入的指令--------------------------*/			E = 0 ;	//从 E = 1 到 E = 0 产生下降沿,HD44780执行指令}/****************************************************************************** *	名称:HD44780_1602LCD_Init() *	功能:对HD44780控制的1602LCD进行初始化 (包含硬件类型,屏显,光标) *	参数:无 *	返回:无 ******************************************************************************/void HD44780_1602LCD_Init(void){	//1、首次写指令前,给LCD硬件一段较长的反应时间	delay1ms(15) ;	//2、显示模式设置		/*----1、匹配硬件的设置: 指令6:8位数据线,2行显示,5*7点阵------------*/		Write_Com(0x38) ; delay1ms(5) ; //3次写指令,确保硬件匹配成功		Write_Com(0x38) ; delay1ms(5) ; 		Write_Com(0x38) ; delay1ms(5) ; 		/*----2、显示屏、光标、闪烁的设置: 指令4:开显示,不开光标,光标不闪烁------*/		Write_Com(0x0c) ; delay1ms(5) ;		/*----3、光标、屏幕移动的设置: 指令3:光标右移,屏幕整体不移动----------*/		Write_Com(0x06) ; delay1ms(5) ;	//3、清屏。指令1	Write_Com(0x01) ; delay1ms(5) ;	 }/****************************************************************************** *	名称:Write_User_char() *	功能:将一个用户自定义的字符写入CGRAM中(CGRAM最多写8个字符) *	参数:unsigned char addr_num : 存入CGRAM中的第addr_num个8字节存储块 (0--8) *	参数:unsigned char *str : 指向存放用户自定义字符的数组 *	返回:无 ******************************************************************************/ void Write_User_char(unsigned char addr_num , unsigned char *str) {	/*----1、定义变量--------------------------------------------------------*/ 	unsigned char i ; 	unsigned char CGRAM_addr ;	/*----2、处理地址,CGRAM存储单元有8*8==64个字节,可存入8个自定义字符-----*/	//指令7的指令码	  01 xxx 000 :第一个 xxx 表示自定义字符存入 第xxx个8字节的存储空间	//									 000 表示第xxx个8字节存储空间的首地址	addr_num = _crol_(addr_num,3) ;		CGRAM_addr = 0x40 | addr_num ;	/*----1、指令7:设定将自定义字符数据存入CGRAM中存储单元的地址------------*/	//指令固定值01、第n个自定义字符、存储第n个自定义字符的数组的首地址(8byte)	Write_Com(CGRAM_addr) ; //	delay1ms(5) ;		/*----2、将用户自定义的字符写入CGRAM中对应地址的存储单元中----------------*/	i = 0 ;	for(i = 0 ; i < 8 ; i++)	{		Write_Data(str[i]) ;	} }/****************************************************************************** *	名称:Dis_User_char() *	功能:显示自定义字符:在1602LCD屏幕指定位置上显示第num个自定义字符 *	参数:unsigned char line , unsigned char x	 在屏幕的第line行第x列显示  *	参数:unsigned char num	 :显示CGRAM中8个自定义字符的第num个 num = 0-->7 *	返回:无 ******************************************************************************/void Dis_User_char(unsigned char line , unsigned char x ,unsigned char num){//3.2.2 	/*----1、设定在1602LCD屏幕上显示的坐标位置(地址)------------*/ 	Write_Address(0x40 * line + x) ; //显示在第line行的第x位	delay1ms(5) ;	/*----2、将CGROM/CGRAM对应地址中的数据,显示在屏幕对应的位置---*/	Write_Data(num) ; //显示CGRAM中8个自定义字符的第num个 num = 0-->7					   //和显示CGROM中数据不同之处在于:不用和0x80相与}/****************************************************************************** *	名称:Switch_Screen() *	功能:控制显示屏开关,(不显示光标) *	参数:unsigned char scr_key = 1:开 ; = 0:关 *	返回:无 ******************************************************************************/ void Switch_Screen(unsigned char scr_key) { 	delay1ms(50) ;	if(scr_key == 1)	{		Write_Com(0x0c) ; //指令4 ,0000 1100 :开屏幕显示 ,无光标	}	if(scr_key == 0)	{		Write_Com(0x08) ; //指令4 ,0000 1100 :关屏幕显示	} 	delay1ms(50) ; } /****************************************************************************** *	名称:Switch_Cursor() *	功能:控制光标开关和闪烁 *	参数:unsigned char cursor_key  *	参数:unsigned char twinkle_key *	返回:无 ******************************************************************************/ void Switch_Cursor(unsigned char cursor_key , unsigned char twinkle_key) { 	delay1ms(50) ;	if(cursor_key == 1)	{		if(twinkle_key == 1)		{			Write_Com(0x0f) ; //指令4 ,0000 1111 :开屏幕显示,开光标,光标闪烁		}		else		{			Write_Com(0x0e) ; //指令4 ,0000 1110 :开屏幕显示 ,开光标				}	}	if(cursor_key == 0)	{		Write_Com(0x0c) ; //指令4 ,0000 1100 :开屏幕显示	} 	delay1ms(50) ; }/****************************************************************************** *	名称:Move_Screen() *	功能:控制屏幕整体左右移动 *	参数:unsigned char r_l = 1 :右移  ; = 0 :左移 *	参数:unsigned char move_bit_num  :屏幕向右或向左移动多少位 *	参数:unsigned char move_delay :每移动一位后,延时多少 ms *	返回:无 ******************************************************************************/ void Move_Screen(unsigned char r_l,unsigned char move_bit_num,unsigned char move_delay) { 	unsigned char i ; 	delay1ms(move_delay) ;	if(r_l == 1) //屏幕整体右移	{		for(i = 0 ; i < move_bit_num ; i++)		{			Write_Com(0x1c) ; //指令5 : 0001 1100 屏幕整体右移一位				delay1ms(move_delay) ;			}	}	if(r_l == 0) //屏幕整体左移	{		for(i = 0 ; i < move_bit_num ; i++)		{			Write_Com(0x18) ; //指令5 : 0001 1000 屏幕整体左移一位				delay1ms(move_delay) ;			}	} }/****************************************************************************** *	名称:Dis_Str() *	功能:在显示HD44780控制的1602LCD上显示一个字符串 *	参数:unsigned char line , unsigned char x 在LCD上显示的位置 *	参数:unsigned char *str 要显示的字符串的指针(首地址) *	返回:无 ******************************************************************************/void Dis_Str(unsigned char line , unsigned char x , unsigned char *str){	unsigned char i ;	//1、 设置在LCD1602上显示字符的开始位置 : 从 第line行 坐标x 开始显示	Write_Address(0x40 * line + x) ; delay1ms(5) ;		//2、 显示要显示的字符串	i = 0 ;	while(str[i] != '\0')	{		Write_Data(str[i]) ;		i++ ;		delay1ms(1) ;	}}/****************************************************************************** *	名称:Dis_Char() *	功能:在显示HD44780控制的1602LCD上显示一个字符 *	参数:unsigned char line , unsigned char x 在LCD上显示的位置 *	参数:unsigned char ch 要显示的字符 *	返回:无 ******************************************************************************/void Dis_Char(unsigned char line , unsigned char x , unsigned char ch){	//1、 设置在LCD1602上显示字符的开始位置 : 从 第line行 坐标x 开始显示	Write_Address(0x40 * line + x) ; delay1ms(5) ;		//2、 显示要显示的字符串	Write_Data(ch) ;	delay1ms(10) ;}/****************************************************************************** *	名称:Clear_Screen() *	功能:清屏 *	参数:无 *	返回:无 ******************************************************************************/ void Clear_Screen(void) {	delay1ms(5) ;	Write_Com(0x01) ; 	delay1ms(5) ;  }
/************************************************************************************************** * 	HD44780_1602LCD配置文件:HD44780_1602LCD.h *	本程序当时是依据AT89S52单片机开发板写的 *	RS R/W E 这三位引脚分别和单片机引脚 P2^0 P2^1 P2^2 相连 *	八位数据引脚DB0……DB7分别和单片机的P0端口的P0^0……P0^7相连 (BF位其实就对应DB7引脚和P0^7相连) *	将此文件来驱动1602LCD时,只需更改下面的位定义和数据线的端口号即可 *	对于HD44780控制的1602LCD的详细资料和11条指令的描述参考一下连接 *	http://blog.csdn.net/dragon12345666/article/details/22819827 **************************************************************************************************/#ifndef __HD44780_1602LCD_H__#define __HD44780_1602LCD_H__#include<reg52.h>#include<intrins.h>#include "DELAY_FUNCTION_FELL.h"sbit RS = P2^0 ;	//对象标志位: = 0(对象是指令或状态位);= 1(对象是数据)sbit RW = P2^1 ;	//读写标志位: = 0(写);= 1(读)sbit E  = P2^2 ;	//使能位:为 1 时,读写信息,为 负跳变 时,执行指令sbit BF = P0^7 ;	//HD44780控制的1602LCD的 忙 状态位(只能通过指令读取) bit Busy_Test(void) ; void Clear_Screen(void) ; void Dis_Str(unsigned char line , unsigned char x , unsigned char *str) ; void Dis_User_char(unsigned char line , unsigned char x ,unsigned char num) ; void Dis_Char(unsigned char line , unsigned char x , unsigned char ch) ; void HD44780_1602LCD_Init(void) ; void Move_Screen(unsigned char r_l,unsigned char move_bit_num,unsigned char move_delay) ; void Switch_Cursor(unsigned char cursor_key , unsigned char twinkle_key) ; void Switch_Screen(unsigned char scr_key) ; void Write_Address(unsigned char addr) ; void Write_Com(unsigned char dictate) ; void Write_Data(unsigned char char_data) ; void Write_User_char(unsigned char addr_num , unsigned char *str) ; #endif


5、延时函数部分配置文件

//DELAY_FUNCTION_FELL.c#include "DELAY_FUNCTION_FELL.h"/****************************************************************************** *	名称:dlcd_delay1us() *	功能:延时若干1ns *	参数:int t *	返回:无 ******************************************************************************/void delay1us(int t){	while(t--)	{		_nop_() ;	}}/****************************************************************************** *	名称:dlcd_delay1ms() *	功能:延时若干1ms *	参数:int t *	返回:无 ******************************************************************************/void delay1ms(int t){	unsigned char i ;	while(t--)	{		for(i = 0 ; i < 125 ; i++)		{			;		}	}}
//DELAY_FUNCTION_FELL.h#ifndef __DELAY_FUNCTION_FELL_H__#define __DELAY_FUNCTION_FELL_H__#include<reg52.h>     //包含单片机寄存器的头文件#include<intrins.h>   //包含_nop_()函数定义的头文件extern void delay1us(int t) ;extern void delay1ms(int t) ;#endif