当前位置: 首页 > news >正文

实时时钟芯片HYM1381的使用(51单片机)

HYM1381是一款低功耗串行实时时钟芯片

两种工作方式:12小时格式/24小时格式

3根通信线:RST(复位)、SCLK(串行时钟)、IO(数据线)

数据存储格式:BCD码(4位二进制数表示一位十进制数)

1381.h:

#define RST P15       //推挽
#define SCLK P03      //推挽
#define DSIO P04      //初始化为推挽输出,发送数据时为推挽,接收数据时为悬空输入/上拉输入

#define Year 6
#define Month 4
#define Date 3
#define Hour 2
#define Minute 1
#define Seconds 0

void HYM1381Init();  //初始化函数
void DataPros();   //时间显示函数
void HYM1381_TimeSet(u8 address);   //时间设定函数
//void HYM1381ReadTime();

extern uchar Time_Set[7];

extern uchar Read_TIME[7];

1381.c:


#include "HYM1381.h"
#include "sysClk_Cfg.h"
#include <INTRINS.H>     //为了使用nop空指令

// HYM1381存储格式使用BCD码,使用过程中涉及十进制和BCD码之间的转换

u8 code Read_RTC_Addr[7]  = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; //读取地址
u8 code Write_RTC_Addr[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //写入地址

// 时钟初始化2025-3-4星期二9点51分30秒,存储顺序按照秒分时日月周年,
uchar xdata TIME[7]={30,51,9,4,3,2,25};		//时间初始值---十进制

uchar Read_TIME[7];          //用来储存读到的时间信息
uchar Time_Set[7];           //用来设置时间 

底层驱动,向1381写入数据和从1381读取数据:

// 向HYM1381发送命令,向地址addr写入数据dat
void HYM1381Write(uchar addr, uchar dat)
{
	uchar i;		
 					
	SCLK = 0;  					// 拉低SCLK,SCLK为低时才可拉高RST
	_nop_ ();          
	RST = 1;            // RST拉高,整个读写期间保持RST高电平
	_nop_ ();  
	P0MDH = 0xaa;  //输出模式
	for(i = 0;i < 8;i++)  // 从低位开始传送八位地址addr
	{
		DSIO = addr&0x01;
		addr>>=1;
		SCLK=1;  						//上升沿向HYM1381写数据
		_nop_ ();
		SCLK=0;  						//SCLK拉低为下一位传送做准备
		_nop_ ();
	}
	
	for(i = 0;i < 8;i++)  // 从低位开始传送八位数据dat
	{
		DSIO = dat&0x01;
		dat>>=1;
		SCLK = 1;           // 上升沿向HYM1381写数据
		_nop_ ();
		SCLK = 0;           // SCLK拉低为下一位传送做准备
		_nop_ ();
	}
	
	// 数据传送结束,将RST拉低,为下一次传送做准备
	RST = 0;
	_nop_ ();
}

// 从HYM1381中读取地址addr的数据dat
uchar HYM1381Read(uchar addr)
{
	uchar i;
	uchar dat = 0, bi;
 
	SCLK = 0;  				// 拉低SCLK,SCLK为低时才可拉高RST
	_nop_ ();
	RST = 1;  				// RST拉高,整个读写期间保持RST高电平
	_nop_ ();  
	P0MDH = 0xaa;
	for(i=0;i<8;i++)  // 从低位开始传送八位地址addr
	{
		DSIO = addr&0x01;
		addr>>=1;
		SCLK = 1;      // 上升沿向HYM1381写数据
		_nop_ ();
		SCLK = 0;      // SCLK拉低为下一位传送做准备
		_nop_ ();
	}
	_nop_ ();
	
	SCLK = 1;  
	P0MDH = 0xa9;
	
	for(i = 0;i < 8;i++)  // 从低位开始读取八位数据dat
	{
		bi = DSIO;
		dat = (dat>>1)|(bi<<7);
//		SCLK = 1;  					// 上升沿向HYM1381写数据
		SCLK = 0;  
		_nop_ ();
//		SCLK = 0;  					// SCLK拉低为下一位传送做准备
		SCLK = 1 ;
		_nop_ ();
	}
	SCLK = 1;
	_nop_ ();
	// 数据传送结束,将RST拉低,为下一次传送做准备
	RST = 0;
	_nop_ ();
	
	_nop_ ();
	// HYM1381复位稳定时间
	
	DSIO = 0;
//	_nop_ ();
//	DSIO = 1;
//	_nop_ ();
	return dat;
}

HYM1381的初始化:

// HYM1381初始化
// 1. 在对HYM1381操作之前需要关闭写保护,0x8e写0x00
// 2. 写入设置的时间
// 3. 打开写保护功能
void HYM1381Init()
{
	uchar i;
	HYM1381Write(0x8E, 0x00);  // 关闭写保护
	for(i = 0;i < sizeof(Write_RTC_Addr);i++)  // 设置时间
	{			
		HYM1381Write(Write_RTC_Addr[i],(TIME[i]/10*16+TIME[i]%10));    //将十进制的时间数据转换为BCD格式写入HYM1381		
	}
	HYM1381Write(0x8E, 0x80);  // 打开写保护
  
}

从HYM1381读取时间:

// 从HYM1381中读取时间信息
void HYM1381ReadTime()
{
	uchar i;		
	for(i = 0;i < sizeof(Read_RTC_Addr);i++)
	{
		Read_TIME[i] = HYM1381Read(Read_RTC_Addr[i]);		
	}			
}

读取到时间之后,就要对时间进行处理和显示了:

以年为例,读到之后转换为十进制,使用段码屏进行显示

void DataPros()
{

	u8 i;
	
	HYM1381ReadTime();  // 首先读取时间信息
	for(i = 0;i < 7;i++)  //将读到的BCD格式转换为十进制
	{
		Read_TIME[i] = Read_TIME[i]/16*10+Read_TIME[i]%16; 
	}
	
		
		
//	Read_TIME[6] = Read_TIME[6]/16*10+Read_TIME[6]%16;    //年--读到的BCD格式转换为十进制
	Disp_Buff[15] = NumLib6_16[Read_TIME[6]%10];		      //年--个位	(十进制除以10取余数得到个位)
	Disp_Buff[15] = Disp_Buff[15]|0x80;     //年和月之间的“-”
	Disp_Buff[16] = NumLib6_16[Read_TIME[6]/10];	        //年--十位   (十进制除以10取正数得到十位)
	Disp_Buff[16] = Disp_Buff[16]|0x80;     //月和日之间的“-”

}

接下来是用户交互的内容,可以通过按键自己调整时间:

//时间设定函数
void HYM1381_TimeSet(u8 address)
{
	HYM1381Write(0x8E, 0x00);  // 关闭写保护

	switch(address)
	{
		case Year:
		{
			HYM1381Write(0x8c,(Time_Set[6]/10*16+Time_Set[6]%10));    //将十进制的时间数据转换为BCD格式写入HYM1381		
		}break;
		case Month:
		{
			HYM1381Write(0x88,(Time_Set[4]/10*16+Time_Set[4]%10));    	
		}break;
		case Date:
		{
			HYM1381Write(0x86,(Time_Set[3]/10*16+Time_Set[3]%10));    		
		}break;
		case Hour:
		{
			HYM1381Write(0x84,(Time_Set[2]/10*16+Time_Set[2]%10));    	
		}break;
		case Minute:
		{
			HYM1381Write(0x82,(Time_Set[1]/10*16+Time_Set[1]%10));    		
		}break;
		case Seconds:
		{
			HYM1381Write(0x80,(Time_Set[0]/10*16+Time_Set[0]%10));    		
		}break;
	}
	
		
	HYM1381Write(0x8E, 0x80);  // 打开写保护
}

因为HYM1381的存储顺序,对数组来说,从左往右依次是:秒、分、时、日、月、周、年

以年为例,数据存在Read_TIME[6],那么
 

Time_Set[6] = Read_TIME[6] - 1;      //每按一次置零键,年份减1
if(Time_Set[6] <= 0) Time_Set[6] = 99;   //年份小于0之后回到99
HYM1381_TimeSet(Year);

特别要说明日期的调整,要根据月份确定,并且2月份要区分平年还是闰年

switch(Read_TIME[Month])
 {
   case 1:
   case 3:
   case 5:
   case 7:
   case 8:
   case 10:
   case 12:
	{
		Time_Set[Date] = Read_TIME[Date] - 1;
		if(Time_Set[Date] < 1) Time_Set[Date] = 31;					
	}
	 break;       //一三五七八十腊,31天
					
	case 2:     //二月份判断闰年平年
	{
	  if((Time_Set[Year] % 4 == 0 && Time_Set[Year] % 100 != 0) || Time_Set[Year] % 400 == 0)//如果是闰年
	  {
		Time_Set[Date] = Read_TIME[Date] - 1;
		if(Time_Set[Date] < 1) Time_Set[Date] = 29;										
	  }
	 else  //平年
	  {
		Time_Set[Date] = Read_TIME[Date] - 1;
		if(Time_Set[Date] < 1) Time_Set[Date] = 28;																									
	   }				
     }
	break;
					
	default:    //其他月份30天
	  {
		Time_Set[Date] = Read_TIME[Date] - 1;
		if(Time_Set[Date] < 1) Time_Set[Date] = 30;															
	  }
		break;												
 }								
	HYM1381_TimeSet(Date);					
 

相关文章:

  • 在K8S中挂载 Secret 到 Pod
  • 【C#知识点详解】ExcelDataReader介绍
  • day3 微机运算基础
  • 【LINUX操作系统】 动静态库的链接原理
  • 指令系统2(Load/Store 指令)
  • 打靶笔记:利用站点Install功能连接Kali本地数据库
  • 传输层协议 — TCP协议与套接字
  • Practical Data Science with SAP Machine Learning Techniques for Enterprise Data
  • KMP-子串匹配算法-关键点理解
  • 蓝桥杯 对联【算法赛】
  • 仙剑奇侠传1隐藏宝箱
  • 【小派项目书】sprintboot + vue 语言实现
  • 单机游戏的工作逻辑
  • Spring IoC DI入门
  • QT-LINUX-Bluetooth蓝牙开发
  • 解释 TypeScript 中的类型保护(type guards),如何使用类型保护进行类型检查?
  • 麦肯锡外运集团企业卓越采购供应链管理体系规划(117页PPT)(文末有下载方式)
  • 阿里云平台Vue项目打包发布
  • 识别并脱敏上传到deepseek/chatgpt的文本文件中的护照信息
  • 晶鑫股份迈向敏捷BI之路,永洪科技助力启程
  • 新华每日电讯:博物馆正以可亲可近替代“高冷范儿”
  • 一个留美学生的思想转向——裘毓麐的《游美闻见录》及其他
  • 女生“生理期请病假要脱裤子证明”?高校回应:视频经处理后有失真等问题
  • 联合国:欢迎俄乌伊斯坦布尔会谈,希望实现全面停火
  • 试点首发进口消费品检验便利化措施,上海海关与上海商务委发文
  • 京东CEO许冉:外卖日单量接近2000万单,看到外卖对平台拉动和转化效应