这种要求的程序很简单,也用不着138、573,给你一个示例参考,另加闹钟也是轻而易举的事。黑币你就自己留着吧。
- #include <reg51.H>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define key_S 8 //宏定义短按(约20ms)
- #define key_L key_S*30 //宏定义长按(约600ms)
- #define key_I key_S*20 //宏定义长按连+间隔(约200ms)
- //DS1302引脚连接定义
- sbit DSIO = P3^2;
- sbit REST = P3^0;
- sbit SCLK = P3^1;
- sbit key1 = P3^3;
- uchar code table[]={//共阴数码管段码"0~f-."
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80};
- uchar dis_buf[8]={0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00}; //数码管显示缓存数组
- //DS1302读取和写入时分秒日月周年的地址
- uchar code READ_RTC_ADDR[7]= {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; //读出地址
- uchar code WRITE_RTC_ADDR[7]= {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //写入地址
- // 秒 分 时 日 月 周 年
- uchar TIME[7]={0x00, 0x00, 0x12, 0x04, 0x01, 0x03, 0x23};//读取Ds1302 存储顺序是秒分时日月周年
- //---全局变量声明---
- uint Cnt2ms; //2.5ms计数变量
- uint num; //计数变量
- uchar KeySec; //键值变量
- bit flashing; //闪烁标志
- //---本地函数声明---//
- void Ds1302Init(); //DS1302初始化
- void Ds1302Write(uchar addr, uchar dat);//向1302芯片写入地址和数据
- uchar Ds1302Read(uchar addr); //从1302读数据
- void Ds1302ReadTime(); //读取秒分时日月周年信息
- uchar BCD_D(uchar bcd); //BCD码转十进制函数
- uchar D_BCD(uchar Dec); //十进制转BCD码函数
- void Timer0Init(void); //定时器T0初始化
- //==============DS1302驱动部分=====================
- //写1302时钟数据
- void Ds1302Write(uchar addr, uchar dat)
- {
- uchar i;
- REST= 0;
- SCLK= 0;
- REST= 1;
- for(i=0;i<8;i++) // 写地址
- {
- DSIO=addr & 0x01; //数据从低位开始传送
- addr>>=1;
- SCLK = 1; //数据在上升沿时,DS1302读取数据
- SCLK = 0;
- }
- for(i=0;i<8;i++) //写数据
- {
- DSIO=dat & 0x01;
- dat>>= 1;
- SCLK = 1; // 数据在上升沿时,DS1302读取数据
- SCLK = 0;
- }
- REST = 0; // 传送数据结束
- }
- //读1302时钟数据
- uchar Ds1302Read(uchar addr)
- {
- uchar i,dat,dat1;
- REST = 0;
- SCLK = 0;
- REST = 1;
- for(i=0; i<8; i++) // 开始传送八位地址命令
- {
- DSIO = addr & 0x01; // 数据从低位开始传送
- addr >>= 1;
- SCLK = 1; // 上升沿有效,DS1302读取数据
- SCLK = 0;
- }
- for(i=0;i<8;i++) // 读取8位数据
- {
- dat1 = DSIO; // 从最低位开始接收
- dat=(dat>>1)|(dat1<<7);
- SCLK = 1; // 上升沿有效,DS1302读取数据
- SCLK = 0;
- }
- REST = 0; // 以下为DS1302复位的稳定时间,必须的。
- SCLK = 1;
- DSIO = 0;
- DSIO = 1;
- return dat;
- }
- //初始化DS1302
- void Ds1302Init()
- {
- uchar i;
- Ds1302Write(0x8E,0x00); // 禁止写保护功能
- for(i=0;i<3;i++) // 写入3个字节的时钟信号:分秒时
- Ds1302Write(WRITE_RTC_ADDR[i],TIME[i]);
- Ds1302Write(0x8E,0x80); // 打开写保护功能
- }
- //BCD码转十进制函数
- uchar BCD_D(uchar bcd)
- {
- return ((bcd>>4)*10)+(bcd & 0x0f);
- }
- //十进制转BCD码函数,返回BCD码
- uchar D_BCD(uchar Dec)
- {
- return (Dec/10*16+Dec%10);
- }
- //读取时钟信息
- void Ds1302ReadTime()
- {
- uchar i;
- for(i=0;i<3;i++) //读取3个字节的时钟信号:秒分时
- TIME[i]=BCD_D(Ds1302Read(READ_RTC_ADDR[i]));//BCD转换成十进制保存
- }
- //按键服务函数
- void key_scan()
- {
- static uint time=0; //计数变量
- if(!key1) //按键按下
- {
- time++;
- if(time>=key_L) //长按
- {
- switch(KeySec)
- {
- case 1: TIME[2]++;if(TIME[2]>23)TIME[2]=0;break;
- case 2: TIME[1]++;if(TIME[1]>59)TIME[1]=0;TIME[0]=0;break;
- }
- time=key_I; //连+间隔
- num=2000; //自复位变量赋值(5秒)
- }
- }
- else //松手
- {
- if(time>key_S && time<key_I)//短按
- {
- num=2000; //自复位变量赋值(5秒)
- KeySec++;
- if(KeySec>2)
- {
- // KeySec=0;
- num=1;
- }
- }
- time=0;
- }
- }
- // 数码管显示函数
- void display()
- {
- uchar i;
- if(KeySec==0) //常态显示
- {
- dis_buf[0]=table[TIME[2]/10];
- dis_buf[1]=table[TIME[2]%10];
- dis_buf[3]=table[TIME[1]/10];
- dis_buf[4]=table[TIME[1]%10];
- dis_buf[6]=table[TIME[0]/10];
- dis_buf[7]=table[TIME[0]%10];
- }
- if(KeySec==1) //调整时
- {
- if(!key1)//持续不变表示键长按连加,时不闪烁
- {
- dis_buf[0]=table[TIME[2]/10];
- dis_buf[1]=table[TIME[2]%10];
- }
- else //松手 时闪烁
- {
- if(flashing)
- {
- dis_buf[0]=table[TIME[2]/10];
- dis_buf[1]=table[TIME[2]%10];
- }
- else
- {
- dis_buf[0]=0x00;
- dis_buf[1]=0x00;
- }
- }
- dis_buf[3]=table[TIME[1]/10];
- dis_buf[4]=table[TIME[1]%10];
- dis_buf[6]=table[TIME[0]/10];
- dis_buf[7]=table[TIME[0]%10];
- }
- if(KeySec==2) //调整分
- {
- dis_buf[0]=table[TIME[2]/10];
- dis_buf[1]=table[TIME[2]%10];
- if(!key1)//持续不变表示键长按连加,分不闪烁
- {
- dis_buf[3]=table[TIME[1]/10];
- dis_buf[4]=table[TIME[1]%10];
- }
- else //松手 分闪烁
- {
- if(flashing)
- {
- dis_buf[3]=table[TIME[1]/10];
- dis_buf[4]=table[TIME[1]%10];
- }
- else
- {
- dis_buf[3]=0x00;
- dis_buf[4]=0x00;
- }
- }
- dis_buf[6]=table[TIME[0]/10];
- dis_buf[7]=table[TIME[0]%10];
- }
- P2=0xff;
- P0=dis_buf[i];
- P2=~(0x01<<i);
- i=++i%8;
- }
- //初始化定时器
- void Timer0Init(void) //2500微秒@12.000MHz
- {
- TMOD |= 0x01; //设置定时器模式
- TL0 = 0x3C; //设置定时初始值
- TH0 = 0xF6; //设置定时初始值
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- }
- //主函数
- void main()
- {
- uchar t;
- Ds1302Init();
- Timer0Init(); //初始化定时器
- while(1)
- {
- if(TF0) //周期2.5ms
- {
- TF0=0;
- TL0 = 0x3C; //设置定时初始值
- TH0 = 0xF6; //设置定时初始值
- if(++Cnt2ms==400)Cnt2ms=0;
- key_scan();//按键扫描
- if(num!=0)
- {
- if(Cnt2ms%80==0)//0.2s 设置状态时、分快闪
- flashing=~flashing;
- num--;
- if(num==0)//按键停止操作5秒自动恢复正常显示
- {
- for(t=1;t<3;t++)//数据转码导入写入缓存
- TIME[t]=D_BCD(TIME[t]);//十进制转BCD码
- Ds1302Init();//写入实时时间
- KeySec=0;//键值清0
- }
- }
- else //设置时间时 不读取DS1302实时时间
- {
- Ds1302ReadTime();//读DS1302实时时间
- }
- display();// 数码管显示函数
- }
- }
- }
复制代码
|