📄 ds1302+ch452.c
字号:
/*********************************************************************
公司名称:
模块名称:数码管显示时钟演示程序
功 能:利用实时时钟 时钟芯片型号:DS1302
说 明:
程序设计:曾海龙
设计时间:2008.04.22
版 本 号: V1.0
*********************************************************************/
#include<reg51.h>
#include <ch452cmd.h> // CH452常量定义
#include<intrins.h>
sbit CH452_DCLK=P3^0;
sbit CH452_DIN =P3^1;
sbit CH452_LOAD=P3^2;
//sbit k1=P3^4;
//sbit k2=P3^5;
//sbit k3=P3^6;
//sbit k4=P3^7;
sbit ds1302_RST =P0^6;
sbit ds1302_IO =P0^7;
sbit ds1302_SCLK=P3^3;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
#define uchar unsigned char
#define uint unsigned int
/******** 4线接口的位操作,与单片机有关 *********/
#define CH452_DCLK_SET {CH452_DCLK=1;}
#define CH452_DCLK_CLR {CH452_DCLK=0;}
#define CH452_DIN_SET {CH452_DIN=1;}
#define CH452_DIN_CLR {CH452_DIN=0;}
#define CH452_LOAD_SET {CH452_LOAD=1;}
#define CH452_LOAD_CLR {CH452_LOAD=0;}
#define DISABLE_KEY_INTERRUPT {EX1=0;}
#define CH452_DCLK_D_OUT {} // 设置DCLK为输出方向,对于双向I/O需切换为输出
#define CH452_DIN_D_OUT {} // 设置DIN为输出方向,对于双向I/O需切换为输出
#define CH452_LOAD_D_OUT {} // 设置LOAD为输出方向,对于双向I/O需切换为输出
//#define CH452_DOUT_D_IN {CH452_DOUT=1;} // 设置DOUT为输入方向,对于双向I/O需切换为输入
void init();
void delay_50us(uint t);
void display();
void write_Byte(uchar tdata);
void write_data_ds1302(uchar taddr,uchar tdata);
void set_ds1302(uchar *P1302);
void get_ds1302() ;
void init_ds1302();
uchar read_Byte();
uchar read_data_ds1302(uchar taddr);
uchar tab[10]={1,2,3,4,5,6,7,8,9,0};
uchar initial_time[]={0x00,0x00,0x12};//秒分时日月周年
uchar data now_time[3];
/******* 延时1uS子程序,主要用于2线接口,与单片机速度有关 ********/
//#define DELAY_1US {} // MCS51<=10MHz
#define DELAY_1US {_nop_();} // MCS51<=20MHz
//#define DELAY_1US {_nop_();_nop_();} // MCS51<=30MHz
//==延迟函数=================================//
void delay1ms(int x)
{
int i,j;
for(i=0;i<x;i++)
for(j=1;j<=120;j++);
}
/**************写12bit控制字函数*******************/
void CH452_Write(unsigned short cmd)
{
unsigned char i;
DISABLE_KEY_INTERRUPT;//禁止键盘中断,防止传输过程中被CH452中断
//而进入中断服务程序中再次传输
CH452_LOAD_CLR; //命令开始,LOAD=0
CH452_LOAD_D_OUT; // 设置LOAD为输出方向
// CH452_DOUT_D_IN; // 设置DOUT为输入方向
CH452_DIN_D_OUT; // 设置DIN为输出方向
CH452_DCLK_D_OUT; // 设置DCLK为输出方向
for(i=0;i!=12;i++) //送入12位数据,低位在前
{
// if (cmd&1) {CH452_DIN_SET;}
// else {CH452_DIN_CLR;} // 输出位数据
CH452_DCLK_CLR;
CH452_DIN=cmd&1;
CH452_DCLK_SET; //上升沿有效
cmd=cmd>>1;
}
CH452_LOAD_SET; //加载数据,LOAD上升沿
DELAY_1US; //命令数据加载周期不小于6US,CH451不需要该周期
DELAY_1US;
DELAY_1US;
}
void main()
{
// init_ds1302();
// set_ds1302(initial_time);
while(1)
{
CH452_Write(CH452_RESET);
CH452_Write(CH452_BCD + 8); // 选择BCD译码方式,扫描极限为8个数码管
//CH452_Write(CH452_SELF_BCD ); // 选择自定义BCD译码方式,扫描极限为8个数码管
// CH452_Write(CH452_TWINKLE + 0x24);//设置闪烁控制,
CH452_Write(CH452_SYSON1); // 开启显示
get_ds1302();
display();
}
}
/********************************************************************
*函 数 名:delay_50us(uchar )
*功能描述:延时
*函数说明:延时50us
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:A1
***********************************************************************/
void delay_50us(uint t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
/********************************************************************
*函 数 名:数码管显示模块部分
*功能描述:数码管显示
*函数说明:
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:A1
***********************************************************************/
void display()
{
uchar i;
i=now_time[0]%16; //显示秒个
CH452_Write(CH452_DIG7 | i);
delay_50us(10);
i=now_time[0]/16; //显示秒十
CH452_Write(CH452_DIG6 | i);
delay_50us(10);
CH452_Write(CH452_DIG5 | 19);
delay_50us(10);
i=now_time[1]%16; //显示分个
CH452_Write(CH452_DIG4 | i);
delay_50us(10);
i=now_time[1]/16; //显示分十
CH452_Write(CH452_DIG3 | i);
delay_50us(10);
CH452_Write(CH452_DIG2 | 19);
delay_50us(10);
i=now_time[2]%16; //显示时个
CH452_Write(CH452_DIG1 | i);
delay_50us(100);
i=now_time[2]/16; //显示时十
CH452_Write(CH452_DIG0 | i);
delay_50us(100);
}
/*ds1302模块部分*/
/********************************************************************
*函 数 名:read_Byte()
*功能描述:实时时钟读一字节
*函数说明:读DS13021Byte数据 下降沿输出一位数据
*调用函数:
*全局变量:
*输 入:ds1302_SCLK=0;
*返 回:ACC
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:
***********************************************************************/
uchar read_Byte()
{
uchar i;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=ds1302_IO;//由于ds1302读数据的时候,第一个数据读取在发一个Byte命令后,在第八位的下降沿
ds1302_SCLK=1;
ds1302_SCLK=0;//产生下降沿输出一位数据
}
return(ACC);
}
/********************************************************************
*函 数 名:write_Byte()
*功能描述:实时时钟写一字节
*函数说明:往DS1302写入1Byte数据 上升沿输入数据
*调用函数:
*全局变量:
*输 入:ds1302_SCLK=0;tdata
*返 回:
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:
***********************************************************************/
void write_Byte(uchar tdata)
{
uchar i;
ACC=tdata;
for(i=8;i>0;i--)
{
ds1302_IO=ACC0;
ds1302_SCLK=1;
ds1302_SCLK=0;//产生上升沿输入数据
ACC=ACC>>1;
}
}
/********************************************************************
*函 数 名:write_data_ds1302(uchar taddr,uchar tdata)
*功能描述:实时时钟写数据
*函数说明:先写地址,后写命令/数据
*调用函数:write_Byte(uchar tdata)
*全局变量:
*输 入:taddr;tdata
*返 回:
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:
***********************************************************************/
void write_data_ds1302(uchar taddr,uchar tdata)
{
ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
write_Byte(tdata);
ds1302_RST=0;
ds1302_SCLK=1;
}
/********************************************************************
*函 数 名:read_data_ds1302(uchar taddr,uchar tdata)
*功能描述:读实时时钟地址里的数据
*函数说明:先写地址,后读命令/数据
*调用函数:write_Byte(uchar tdata);read_Byte()
*全局变量:
*输 入:taddr;
*返 回:tdata
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:
***********************************************************************/
uchar read_data_ds1302(uchar taddr)
{
uchar tdata;
ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
tdata=read_Byte();
ds1302_RST=0;
ds1302_SCLK=1;
return(tdata);
}
/********************************************************************
*函 数 名:set_ds1302()
*功能描述:设置初始时间
*函数说明:先写地址,后读命令/数据
*调用函数:
*全局变量:
*输 入:taddr;
*返 回:tdata
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:
***********************************************************************/
void set_ds1302(uchar *P1302)
{
uchar i;
uchar taddr = 0x80;
write_data_ds1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/
for(i =3; i>0; i--)
{
write_data_ds1302(taddr,*P1302); /* 秒 分 时 日 月 星期 年 */
P1302++;
taddr+=2;
}
write_data_ds1302(0x8e,0x80); /* 控制命令,WP=1,写保护*/
}
/********************************************************************
*函 数 名:get_ds1302()
*功能描述:设置初始时间
*函数说明:先写地址,后读命令/数据
*调用函数:
*全局变量:
*输 入:now_time[];
*返 回:
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:
***********************************************************************/
void get_ds1302()
{
uchar k;
uchar taddr = 0x81;
for (k=0; k<3.; k++)
{
now_time[k] = read_data_ds1302(taddr);/*格式为: 秒 分 时 日 月 星期 年 */
taddr+= 2;
}
}
/********************************************************************
*函 数 名:init_ds1302()
*功能描述:初始化ds1302
*函数说明:先写地址,后读命令/数据
*调用函数:
*全局变量:
*输 入:
*返 回:
*设 计:曾海龙 日 期:2008-04-26
*修 改: 日 期:
*版 本:
***********************************************************************/
void init_ds1302()
{
ds1302_RST=0;
ds1302_SCLK=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -