📄 ds1302_.c
字号:
/*********************************************************************/
/* 实时时钟模块 时钟芯片型号:DS1302 */
/*********************************************************************/
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit T_CLK = P2^1; //实时时钟时钟线引脚
sbit T_IO = P2^2; //实时时钟数据线引脚
sbit T_RST = P2^0; //实时时钟复位线引脚
bit charge_sw_flag; //充电开关标志,1为开,0为关
bit dis_clock_flag=0; //时钟始停开关,1为开,0为关
bit clock_type_flag; //时钟显示类型,1为12小时制,0为24小时制
bit dis_calendar_flag=0;//只读开关标志,1为只读,0为非只读(可写)
uchar idata cur_time_cach[7];
// uchar arrow_roll_clock; // 箭头滚动时钟计数器
// uchar arrow_roll_coun;
#define SEG_reg cur_time_cach[0]
#define MIN_reg cur_time_cach[1]
#define HR_reg cur_time_cach[2]
#define DATE_reg cur_time_cach[3]
#define MONTH_reg cur_time_cach[4]
#define DAY_reg cur_time_cach[5]
#define YEAR_reg cur_time_cach[6]
#define sec_l SEG_reg & 0x0f
#define sec_h (SEG_reg >> 4) & 0x07
#define min_l MIN_reg & 0x0f
#define min_h (MIN_reg >> 4) & 0x07
#define hr_l HR_reg & 0x0f
#define hr_h (HR_reg >> 4) & 0x03
#define date_l DATE_reg & 0x0f
#define date_h (DATE_reg >> 4) & 0x03
#define month_l MONTH_reg & 0x0f
#define month_h (MONTH_reg >> 4) & 0x01
#define day (DAY_reg & 0x07) //english
#define year_l YEAR_reg & 0x0f
#define year_h (YEAR_reg >> 4) & 0x0f
// dis part
//uchar date_space_x, date_space_y, date_size, date_b_c, date_col, date_AT_sw;
//uchar clock_space_x,clock_space_y,clock_size,clock_b_c, clock_col,clock_AT_sw;
// dis part end
/*********************************************************************************************************
** 函数名称: dis_calendar( )
** 功能描述: 将日历以 年,月,日,星期 的形式显示
********************************************************************************************************/
void dis_calendar()
{
uint week;
switch(day)
{
case 1:week=0x150;break;
case 2:week=0x153;break;
case 3:week=0x156;break;
case 4:week=0x159;break;
case 5:week=0x15c;break;
case 6:week=0x160;break;
case 7:week=0x163;break;
default:week=0x150;
break;
}
h.u.text_6[0] = (year_h);
h.u.text_6[1] = (year_l);
h.u.text_6[2] = 0x24;
h.u.text_6[3] = (month_h);
h.u.text_6[4] = (month_l);
h.u.text_6[5] = 0x24;
h.u.text_6[6] = (date_h);
h.u.text_6[7] = (date_l);
h.u.text_6[8] = (week);
h.u.text_6[9] = (week+1);
h.u.text_6[10]= (week+2);
h.u.text_6[11]= 0xff;
}
/*********************************************************************************************************
** 函数名称: dis_clock()
** 功能描述: 将楼层值 h,m,s 作OSD
********************************************************************************************************/
dis_clock()
{
h.u.text_6[12] = (hr_h);
h.u.text_6[13] = (hr_l);
h.u.text_6[14] = 0x27;
h.u.text_6[15] = (min_h);
h.u.text_6[16] = (min_l);
h.u.text_6[17] = 0x27;
h.u.text_6[18] = (sec_h);
h.u.text_6[19] = (sec_l);
}
/********************************************************************
* 名称: v_RTInputByte
* 说明:
* 功能: 往DS1302写入1Byte数据
* 调用:
* 输入: ucDa 写入的数据
* 返回值: 无
***********************************************************************/
void v_RTInputByte(uchar ucDa)
{
uchar i;
ACC = ucDa;
for(i=8; i>0; i--)
{
T_IO = ACC0;
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1; /*相当于汇编中的 RRC */
}
}
/********************************************************************
* 名称: uchar uc_RTOutputByte
* 说明:
* 功能: 从DS1302读取1Byte数据
* 调用:
* 输入:
* 返回值: ACC
***********************************************************************/
uchar uc_RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return (ACC);
}
/*********************************************************************
* 名称: v_W1302
* 说明: 先写地址,后写命令/数据
* 功能: 往DS1302写入数据
* 调用: v_RTInputByte()
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值: 无
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); // 地址,命令
v_RTInputByte(ucDa); // 写1Byte数据
T_CLK = 1;
T_RST =0;
}
/*********************************************************************
* 名称: uc_R1302
* 说明: 先写地址,后读命令/数据
* 功能: 读取DS1302某地址的数据
* 调用: v_RTInputByte() , uc_RTOutputByte()
* 输入: ucAddr: DS1302地址
* 返回值: ucDa :读取的数据
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); // 地址,命令
ucDa = uc_RTOutputByte(); // 读1Byte数据
T_CLK = 1;
T_RST =0;
return(ucDa);
}
// DS1302备用电源充电开关,charge_sw为‘1’时允许充电,‘0’时禁止
void charge_sw( bit charge_sw )
{
uchar sw_word;
if( charge_sw ) sw_word |= 0xbb; // enable :charge_word= 1010 10 10
else sw_word &= 0x00; //disenable
v_W1302( 0x90,sw_word );
}
//时钟“停止”,“工作"控制: clock_sw_flag为‘1’时停,‘0’时工作
/*
void clock_stop( bit clock_sw )
{
if( clock_sw ) SEG_reg |= 0x80; // stop
else SEG_reg &= 0x7f; // worker
v_W1302( 0x80,SEG_reg );
}
*/
//时钟类型选择:clock_type_flag 为‘1’时是24小时方式,为‘0’时为12小时方式
void clock_type( bit clock_type )
{
if( clock_type ) HR_reg |= 0x80; //12小时制 P267
else HR_reg &= 0x7f; //24小时制
v_W1302( 0x84,HR_reg );
}
/*
//只读开关,only_read_sw_flag为‘1’时为只读。
void only_read_sw( bit only_read_sw )
{
uchar sw_word;
if( only_read_sw ) sw_word = 0x80; // only_read
else sw_word = 0x00; // allow write
v_W1302( 0x8e,sw_word );
}
*/
//以非连续方式写(设置)DS1302时钟数据
//-----------------------------------------------------------------------
//
// 名称: v_Set1302
// 说明: 此程序已设置了写保护的相关功能
// 功能: 设置初始时间
// 调用: v_W1302()
// 输入: pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年
// 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
// 返回值: 无
//------------------------------------------------------------------------
void v_Set1302(uchar *pSecDa)
{
uchar i;
uchar ucAddr = 0x80; // 设置时钟"写"地址
v_W1302(0x8e,0x00); // 控制命令,WP=0,写操作
for(i =7;i>0;i--)
{
v_W1302(ucAddr,*pSecDa); // 秒 分 时 日 月 星期 年
pSecDa++;
ucAddr +=2;
}
v_W1302(0x8e,0x80); // 控制命令,WP=1,写保护
}
//------------------------------------------------------------------------
//
// 名称: v_Get1302
// 说明:
// 功能: 读取DS1302当前时间
// 调用: uc_R1302()
// 输入: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
// 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
// 返回值: 无
//------------------------------------------------------------------------
void v_Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81; //设置时钟"读"地址
for (i=0;i<7;i++)
{
ucCurtime[i] = uc_R1302(ucAddr); //格式为: 秒 分 时 日 月 星期 年
ucAddr += 2;
}
}
/*
//以连续方式写(设置)DS1302时钟数据
void Burst_set_1302_T(uchar *p_ini_time_tab)
{
uchar i;
//only_read_sw( 0 ); // allow write ds1302
v_W1302(0x8e,0x00); // allow write ds1302
T_RST = 0;
T_CLK = 0;
T_RST = 1;
//----------------------------------------------------------------------------------------------
v_RTInputByte(0xbe); //---b e: 1 0 1 1 1 1 1 0 连续时钟多字节 时钟 写命令
// clock address write
//注意:此处address应为:1111 当再次调用RTinputbyte函数时才能将数据输入0单元
//----------------------------------------------------------------------------------------------
for(i=0;i<7;i++)
{
v_RTInputByte( *p_ini_time_tab );
p_ini_time_tab++;
}
//only_read_sw( 1 ); // only read ds1302
}
//连续方式读DS1302时钟数据
void Burst_get_1302_T(uchar *p_cur_time_tab)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 0;
//----------------------------------------------------------------------------------------------
v_RTInputByte(0xbf); //---b f: 1 0 1 1 1 1 1 1 连续时钟多字节 时钟 读命令
// clock address read
//注意:此处address应为:1111 当再次调用RTinputbyte函数时才能将数据输入0单元
//----------------------------------------------------------------------------------------------
for(i=0;i<7;i++)
{
*p_cur_time_tab = uc_RTOutputByte();
p_cur_time_tab++;
}
T_CLK = 1;
T_RST = 0;
}
*/
/*
void main()
{
charge_sw( 1 );
clock_type( 1 );
clock_stop( 0 );
v_Set1302( ini_time_data ); // 设置1302初始值 // Burst_set_1302_T(ini_time_data);
for(;;)
{
v_Get1302( cur_time_cach ); // 读取1302当前值 // Burst_get_1302_T( cur_time_cach );
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -