欢迎光临~啄木鸟电子科技

软件设计

DS1302 时钟



#include
#include"ds1302.h"
#include"oled.h"

/*实验要求 :开发板上XJ8 PS/2与DS1302,要用跳线帽短接到DS1302_CLK 和 DS1302_IO */
// DDR 数据 方向 寄存器; 
// ODR 输出 数据 寄存器; 
// IDR 输入引脚 寄存器;
// CR1 控制寄存器1; 
// CR2 控制寄存器2; 

#define  DS1302_IO_OUT  PB_ODR_ODR2     //DS1302输入输出端口(输出)
#define  DS1302_IO_IN   PB_IDR_IDR2     //DS1302输入输出端口(输入)
#define  DS1302_SCK     PB_ODR_ODR3     //DS1302时钟端口
#define  DS1302_RST     PB_ODR_ODR4     //DS1302复位端口

/***********************用户自定义数据区域***********************/
u8 table1[]="==System  init==";//LCD1602显示字符串数组1显示效果用

#define DS1302_sec_add          0x80  //秒 数据地址
#define DS1302_min_add          0x82  //分 数据地址
#define DS1302_hr_add           0x84  //时 数据地址

#define DS1302_date_add         0x86  //日 数据地址
#define DS1302_month_add        0x88  //月 数据地址
#define DS1302_day_add          0x8A  //星 期数据地址

#define DS1302_year_add         0x8C  //年 数据地址
#define DS1302_control_add      0x8e  //控制 数据地址

#define DS1302_charger_add      0x90 					 
#define DS1302_clkburst_add     0xbe


// 定义 变量;  //初始时间2010年6月1号23点59分55秒 星期二
u8 time_buf[8]={0x20,0x95,0x012,0x31,0x23,0x59,0x55,0x03};

u8 dis_time_buf[16] = {0};
u8 *WEEK[] = {"SUN", "MON", "TUS", "WEN", "THU", "FRI", "SAT"};


void DS1302_Time_Now(void)
{
	DS1302_UPDATA();
		  
	OLED_ShowChar(32 , 2 , '/');
	OLED_ShowChar(56 , 2 , '/');
		
	OLED_ShowChar(16 , 4 , ':');
	OLED_ShowChar(40 , 4 , ':');
		  
//	年
	OLED_ShowChar(0 , 2 , dis_time_buf[0] +'0');
	OLED_ShowChar(8 , 2 , dis_time_buf[1] +'0');
	OLED_ShowChar(16 , 2 , dis_time_buf[2] +'0');
	OLED_ShowChar(24 , 2 , dis_time_buf[3] +'0');
		
//	月
	OLED_ShowChar(40 , 2 , dis_time_buf[4] +'0');  	// 月 高位; 
	OLED_ShowChar(48 , 2 , dis_time_buf[5] +'0'); 	// 月 低位; 

//	日
	OLED_ShowChar(64 , 2 , dis_time_buf[6] +'0');
	OLED_ShowChar(72 , 2 , dis_time_buf[7] +'0');

		
//	时
	OLED_ShowChar(0 , 4 , dis_time_buf[8] +'0');
	OLED_ShowChar(8 , 4 , dis_time_buf[9] +'0');
		
//	分
	OLED_ShowChar(24 , 4 , dis_time_buf[10] +'0');
	OLED_ShowChar(32 , 4 , dis_time_buf[11] +'0');	
		
//	秒		 
	OLED_ShowChar(48 , 4 ,  dis_time_buf[12]  +'0'); 
	OLED_ShowChar(56 , 4 ,  dis_time_buf[13]  +'0');
		
//	周		 
	OLED_ShowString(88 , 2 ,  WEEK[dis_time_buf[14]]);
	
}  		
		

/****************************************************************/
//延时函数Delay_Nms(),有形参Count用于控制延时函数执行次数,无返回值
/****************************************************************/
void Delay_Nms(u16 Count)//延时函数
{
  u8 i,j;
  while (Count--)//Count形参控制延时次数
  {
    for(i=0; i<50; i++) for(j=0; j<20; j++); } } /****************************************************************/ //DS1302初始化函数DS1302_init(),无形参,无返回值 /****************************************************************/ void DS1302_init(void) { DS1302_RST=0; //DS1302_RST脚置低 DS1302_SCK=0; //DS1302_SCK脚置低 } /**************************************************************** void DS1302_Reset(void) 无形参,无 返回值 ****************************************************************/ void DS1302_Reset(void) { DS1302_SCK=0; //DS1302_SCK脚置 低 DS1302_RST=0; //DS1302_RST脚置 低 DS1302_RST=1; //DS1302_RST脚置 高 } /**************************************************************** //DS1302芯片IO引脚方向性配置函数DS1302_IO_DDR(), 有形参ddr无返回值 ****************************************************************/ void DS1302_IO_DDR(u8 ddr) { if(ddr == 1) //配置为 输出方式 { PB_DDR_DDR2= 1; //配置PC1引脚为输出引脚 PB_CR1_C12 = 1; //配置PC1引脚为推挽输出模式 PB_CR2_C22 = 0; //配置PC1引脚低速率输出模式 } else //配置为 输入方式 { PB_DDR_DDR2= 0; //配置PC1引脚为输入引脚 PB_CR1_C12 = 1; //配置PC1引脚为弱上拉输入模式 PB_CR2_C22 = 0; //禁止PC1引脚外部中断功能 } } /**************************************************************** //向DS1302写入一字节数据函数DS1302_write_byte(u8 addr, u8 data) //有形参addr、data,无返回值 指定地址,写入 1 字节(8位) ****************************************************************/ void DS1302_write_byte(u8 addr, u8 data) { u8 i; DS1302_IO_DDR(1); //配置DS1302_IO引脚为输出方式 DS1302_RST=1; //启动DS1302总线 //写入目标地址:addr addr = addr & 0xFE;//最低位置零,寄存器0位为0时写,为1时读 1111 1110 for(i=0; i<8; i++) { if(addr & 0x01) DS1302_IO_OUT = 1; else DS1302_IO_OUT = 0; DS1302_SCK = 1; //产生时钟 DS1302_SCK = 0; addr = addr >> 1;
  }	
  
  	//写入数据:data
  	for(i=0; i<8; i++) { if(data & 0x01) DS1302_IO_OUT = 1; else DS1302_IO_OUT = 0; DS1302_SCK = 1; //产生时钟 DS1302_SCK = 0; data = data >> 1;
  }
  DS1302_RST=0;			//停止DS1302总线
}

/****************************************************************
//从DS1302读出一字节数据函数DS1302_read_byte(u8 addr)
//有形参addr,有返回值

指定地址,读出 1 字节(8位) 
****************************************************************/
u8 DS1302_read_byte(u8 addr)
{
  	u8 i,temp;				//i为循环控制变量,temp为读取回单片机的数据	
  	DS1302_IO_DDR(1);		//配置DS1302_IO引脚为输出方式
  	DS1302_RST = 1;			//启动DS1302总线
  
  	//写入目标地址:addr
  	addr=addr|0x01;			//最低位置高,寄存器0位为0时写,为1时读
  	for(i=0;i<8;i++) { if(addr&0x01) //送出地址 DS1302_IO_OUT=1; else DS1302_IO_OUT=0; DS1302_SCK = 1; //产生时钟 DS1302_SCK = 0; addr = addr >> 1;
  }	
  
  //输出数据:temp
  DS1302_IO_DDR(0);			//配置DS1302_IO引脚为输入方式
  for(i=0;i<8;i++) { temp=temp >> 1;
    if(DS1302_IO_IN)		//取回IO线路状态
      temp |= 0x80;			//数据位为“1”时
    else
      temp &= 0x7F;			//数据位为“0”时
    DS1302_SCK = 1;			//产生时钟
    DS1302_SCK = 0;
  }	
  DS1302_RST = 0;				//停止 DS1302 总线
  
  return temp;				//返回读取数据temp
}
/****************************************************************
//向 DS1302 写入时钟数据函数 DS1302_write_time(),
无形参,
无返回值
****************************************************************/
void DS1302_write_time(void) 
{
  DS1302_write_byte(DS1302_control_add, 0x00);          //关闭写保护 
  
  DS1302_write_byte(DS1302_sec_add, 0x80);              //暂停时钟 
  //DS1302_write_byte(DS1302_charger_add, 0xa9);        //涓流充电 
  DS1302_write_byte(DS1302_year_add, 	time_buf[1]);   //年 
  DS1302_write_byte(DS1302_month_add, 	time_buf[2]);   //月 
  DS1302_write_byte(DS1302_date_add, 	time_buf[3]);   //日 
  DS1302_write_byte(DS1302_hr_add, 		time_buf[4]);	//时 
  DS1302_write_byte(DS1302_min_add, 	time_buf[5]);   //分
  DS1302_write_byte(DS1302_sec_add, 	time_buf[6]);   //秒
  DS1302_write_byte(DS1302_day_add, 	time_buf[7]);   //周 
  
  DS1302_write_byte(DS1302_control_add, 0x80);          //打开写保护     
}

/****************************************************************
//从DS302读出时钟数据函数DS1302_read_time(),
无形参,
无返回值
****************************************************************/
void DS1302_read_time(void)
{
  time_buf[1] = DS1302_read_byte(DS1302_year_add);        //年 
  time_buf[2] = DS1302_read_byte(DS1302_month_add);       //月 
  time_buf[3] = DS1302_read_byte(DS1302_date_add);        //日 
  time_buf[4] = DS1302_read_byte(DS1302_hr_add);          //时 
  time_buf[5] = DS1302_read_byte(DS1302_min_add);         //分 
  time_buf[6] = (DS1302_read_byte(DS1302_sec_add)) & 0x7f; 
   
  //秒,屏蔽秒的第7位,避免超出 59
  time_buf[7] = DS1302_read_byte(DS1302_day_add);         //周 	
}
/****************************************************************
//1602液晶显示DS1302时间函数Display(),无形参,无返回值

void Display(void)
{  
  //LCD1602第1行显示内容
  LCD1602_DIS_CHAR(1,0,dis_time_buf[0]+'0');
  LCD1602_DIS_CHAR(1,1,dis_time_buf[1]+'0');
  LCD1602_DIS_CHAR(1,2,dis_time_buf[2]+'0');
  LCD1602_DIS_CHAR(1,3,dis_time_buf[3]+'0');
  LCD1602_DIS_CHAR(1,4,'-');
  LCD1602_DIS_CHAR(1,5,dis_time_buf[4]+'0');
  LCD1602_DIS_CHAR(1,6,dis_time_buf[5]+'0'); 
  LCD1602_DIS_CHAR(1,7,'-');
  LCD1602_DIS_CHAR(1,8,dis_time_buf[6]+'0');
  LCD1602_DIS_CHAR(1,9,dis_time_buf[7]+'0');
  LCD1602_DIS_CHAR(1,10,'-');
  LCD1602_DIS_CHAR(1,11,'W');
  LCD1602_DIS_CHAR(1,12,'e');
  LCD1602_DIS_CHAR(1,13,'e');
  LCD1602_DIS_CHAR(1,14,'k');
  LCD1602_DIS_CHAR(1,15,dis_time_buf[14]+'0'); 
  
  //LCD1602第2行显示内容  
  LCD1602_DIS_CHAR(2,4,dis_time_buf[8]+'0');
  LCD1602_DIS_CHAR(2,5,dis_time_buf[9]+'0');
  LCD1602_DIS_CHAR(2,6,':');
  LCD1602_DIS_CHAR(2,7,dis_time_buf[10]+'0');
  LCD1602_DIS_CHAR(2,8,dis_time_buf[11]+'0');
  LCD1602_DIS_CHAR(2,9,':');
  LCD1602_DIS_CHAR(2,10,dis_time_buf[12]+'0');
  LCD1602_DIS_CHAR(2,11,dis_time_buf[13]+'0');
}
****************************************************************/

/****************************************************************
//DS1302时间更新函数 DS1302_UPDATA(),
无形参,
无返回值
****************************************************************/
void DS1302_UPDATA(void)
{
  	DS1302_read_time();						//读取时间 
  
  	dis_time_buf[0] = (time_buf[0] >> 4); 	//年 00-99  
  	dis_time_buf[1] = (time_buf[0] & 0x0F);
  
  	dis_time_buf[2] = (time_buf[1] >> 4);   // 取 高 4 位; 
  	dis_time_buf[3] = (time_buf[1] & 0x0F); // 取 低 4 位; 
  	/****************************************/
  	dis_time_buf[4] = (time_buf[2]>>4); 	//月  
  	dis_time_buf[5] = (time_buf[2]&0x0F);
  
  	/****************************************/
  	dis_time_buf[6] = (time_buf[3]>>4); 	//日   
  	dis_time_buf[7] = (time_buf[3]&0x0F);
  
  	/****************************************/
  	dis_time_buf[14] = (time_buf[7] & 0x07); //星期
  
  	/****************************************/
  	dis_time_buf[8]  = (time_buf[4] >> 4); 	//时   
  	dis_time_buf[9]  = (time_buf[4] & 0x0F);
  
  	/****************************************/  
  	dis_time_buf[10] = (time_buf[5] >> 4); 	//分   
  	dis_time_buf[11] = (time_buf[5] & 0x0F); 
  
  	/****************************************/  
  	dis_time_buf[12] = (time_buf[6] >> 4); 	//秒   
  	dis_time_buf[13] = (time_buf[6] & 0x0F);
}

操作DS1302的大致过程,
将各种数据 写入 DS1302的寄存器,以设置它当前的时间格式;
然后使DS1302开始运作,DS1302时钟会按照设置情况运转;
再用单片机将其寄存器内的数据读出。再用液晶显示,就是我们常说的简易电子钟。

上一个:字库 下一个:OLED 显示屏

联系我们

联系人:客服在线

手机:全工:13903011251

电话:李R:13530006400

邮箱:729986191@qq.com

地址: GUANGDONG PROVINCE

用手机扫描二维码关闭
二维码