电子钟程序.docx
- 文档编号:24574410
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:24
- 大小:18.93KB
电子钟程序.docx
《电子钟程序.docx》由会员分享,可在线阅读,更多相关《电子钟程序.docx(24页珍藏版)》请在冰豆网上搜索。
电子钟程序
#include
//变量声明
unsignedchardate[3]={0};//日期数组
unsignedchartime[3]={0};//时间数组
unsignedcharflag[4]={0};//按键标志位数组
unsignedcharclock[2]={6,30};//闹钟数组
unsignedcharst[10]={'','','','c','l','o','c','k','',''};
unsignedcharc_flag=0;//闹钟与日期切换标志位
unsignedcharcount=0;//按键次数计数变量
sbitk_clock=P3^2;//切换日期与时钟显示的按键
sbitring=P3^0;//蜂鸣器
sbitled=P3^7;//led指示灯
/**************************ds1302声明部分***********************/
//寄存器宏定义
#defineW_YEAR0x8c
#defineW_MONTH0x88
#defineW_DAY0x86
#defineW_HOUR0x84
#defineW_MIN0x82
#defineW_SEC0x80
#defineR_YEAR0x8d
#defineR_MONTH0x89
#defineR_DAY0x87
#defineR_HOUR0x85
#defineR_MIN0x83
#defineR_SEC0x81
#defineW_PROTECT0x8e
sbitSCLK=P1^6;
sbitDIO=P1^5;
sbitRES=P1^7;
voidds_write(unsignedcharaddr,unsignedchardat);//写ds1302函数
unsignedchards_read(unsignedcharaddr);//读ds1302函数
voidinit_1302();//1302初始化函数
/***********************lcd1602声明部分***********************/
//位声明
sbitE=P2^1;
sbitRS=P2^0;
//函数声明
voidinit_1602();//1602初始化函数
voidLCD_WRITE_CHA(chardata2);//1602显示字符函数
voidLCD_WRITE_TIM(chardata1);//1602显示数字函数
voidLCD_WRITE_COM(charcom);//1602写命令函数
voiddelay(intnms);//毫秒延时函数
voiddisplay(unsignedchardat[],unsignedcharaddr);//基础显示函数
voiddisplay_time();//显示日期、时间函数
voidk_scan();//键盘扫描函数
unsignedcharbcd_change(unsignedchardat);//bcd码转换函数
voidring_test(unsignedchararr1[],unsignedchararr2[]);//闹钟响铃函数
voidshine(unsignedcharm);//日期更改闪烁函数
voidshine_clock(unsignedcharm);//闹钟更改闪烁函数
/**********************中断函数*************************/
voidc()interrupt0
{
delay
(1);
flag[2]=0;//按键标志位清零
flag[3]=0;
if(k_clock==0)//有键按下
{
c_flag=~c_flag;
}
}
/************************main函数*************************/
main()
{
unsignedchari;
IT0=0;
EA=1;
EX0=1;
c_flag=0;//闹钟显示标志位清零
init_1302();//1302初始化
init_1602();//1602初始化
while
(1)
{
k_scan();//按键扫描
if(c_flag==0)//闹钟显示标志位为0,显示日期时间
{
if(flag[2]==1)//判断按键3是否按下
{
shine(count);//闪烁
if(flag[3]==1)//判断返回键是否按下
{
flag[2]=0;
flag[3]=0;
date[0]=bcd_change(date[0]);//将数据转换成BCD码
date[1]=bcd_change(date[1]);
date[2]=bcd_change(date[2]);
time[0]=bcd_change(time[0]);
time[1]=bcd_change(time[1]);
ds_write(W_PROTECT,0x00);//将转换为BCD码后的数据写入ds1302
ds_write(W_YEAR,date[0]);
ds_write(W_MONTH,date[1]);
ds_write(W_DAY,date[2]);
ds_write(W_HOUR,time[0]);
ds_write(W_MIN,time[1]);
ds_write(W_PROTECT,0x80);
}
if(flag[1]==1)//判断“减1”键是否按下
{
switch(count)//根据count的值确定更改哪一个时间
{
case1:
date[0]--;//count=1时,更改“年”
if(date[0]==255)
{
date[0]=99;
}
break;
case2:
date[1]--;//count=2时,更改“月”
if(date[1]==0)
{
date[1]=12;
}
break;
case3:
date[2]--;//count=3时,更改“日”
switch(date[1])
{
case1:
case3:
case5:
case7:
case8:
case10:
case12:
if(date[2]==0)
{
date[2]=31;
}
break;
case2:
if(date[2]==0)
{
date[2]=28;
}
break;
case4:
case6:
case9:
case11:
if(date[2]==0)
{
date[2]=30;
}
break;
}
break;
case4:
time[0]--;//count=4时,更改“小时”
if(time[0]==255)
{
time[0]=23;
}
break;
case5:
time[1]--;//count=5时,更改“分”
if(time[1]==255)
{
time[1]=59;
}
break;
default:
break;
}
flag[1]=0;
}
if(flag[0]==1)//判断“加1”键是否按下
{
switch(count)
{
case1:
date[0]++;
if(date[0]>99)
{
date[0]=0;
}
break;
case2:
date[1]++;
if(date[1]>12)
{
date[1]=1;
}
break;
case3:
date[2]++;
switch(date[1])
{
case1:
case3:
case5:
case7:
case8:
case10:
case12:
if(date[2]==32)
{
date[2]=1;
}
break;
case2:
if(date[2]==29)
{
date[2]=1;
}
break;
case4:
case6:
case9:
case11:
if(date[2]==31)
{
date[2]=1;
}
break;
}
break;
case4:
time[0]++;
if(time[0]==24)
{
time[0]=0;
}
break;
case5:
time[1]++;
if(time[1]==60)
{
time[1]=0x00;
}
break;
default:
break;
}
flag[0]=0;
}
}
display_time();//调用函数显示日期、时间
ring_test(time,clock);//检测是否到达闹钟时间,若是,则蜂鸣器响
}
else//闹钟显示标志位为1,显示时钟
{
LCD_WRITE_COM(0x80+0x02);//在第一行显示“clock”字符串
for(i=0;i<10;i++)
{
LCD_WRITE_CHA(st[i]);
}
if(flag[2]==1)//判断“更改时间”按键是否按下
{
shine_clock(count);//闪烁
if(flag[3]==1)//判断“返回”键是否按下
{
flag[2]=0;
flag[3]=0;
}
if(flag[1]==1)//判断“减1”键是否按下
{
i=count%2;
switch(i)//根据i值的不同,分别修改“小时”和“分钟”
{
case1:
clock[0]--;//i=1修改“小时”
if(clock[0]==255)
{
clock[0]=23;
}
break;
case0:
clock[1]--;//i=0修改“分钟”
if(clock[1]==255)
{
clock[1]=59;
}
break;
default:
break;
}
flag[1]=0;
}
if(flag[0]==1)//判断“加1”键是否按下
{
count=count%2;
switch(count)
{
case1:
clock[0]++;
if(clock[0]==24)
{
clock[0]=0;
}
break;
case0:
clock[1]++;
if(clock[1]==60)
{
clock[1]=0;
}
break;
default:
break;
}
flag[0]=0;
}
}
display(clock,0x80+0x40);//调用函数显示闹钟时间
}
delay(150);
}
}
/******************正常显示时间函数*********************/
voiddisplay_time()
{
LCD_WRITE_COM(0x80+0x02);//向1602输入年份的前两位,即20--
LCD_WRITE_TIM(0x14);
if(flag[2]==0)
{
date[0]=ds_read(R_YEAR);//从ds1302中读取年月日时分秒的值
date[1]=ds_read(R_MONTH);
date[2]=ds_read(R_DAY);
time[0]=ds_read(R_HOUR);
time[1]=ds_read(R_MIN);
time[2]=ds_read(R_SEC);
}
display(date,0x80);//调用函数显示年-月-日
display(time,(0x80+0x40));//调用函数显示时-分-秒
}
/*************************显示函数*************************/
/*函数功能:
给定一个数组和显示的初始地址,即可在1602上
以xx-xx-xx的格式显示该数组*/
voiddisplay(unsignedchardat[],unsignedcharaddr)
{
LCD_WRITE_COM(addr+4);
LCD_WRITE_TIM(dat[0]);
LCD_WRITE_CHA('-');
LCD_WRITE_TIM(dat[1]);
LCD_WRITE_CHA('-');
LCD_WRITE_TIM(dat[2]);
}
/*****************键盘扫描函数*********************/
voidk_scan()
{
unsignedchartemp;
temp=P1;
temp=temp&0x0f;
if(temp!
=0x0f)
{
delay(10);
temp=P1;
temp=temp&0x0f;
if(temp!
=0x0f)
{
switch(temp)
{
case0x0E:
flag[0]=1;
break;
case0x0D:
flag[1]=1;
break;
case0x0B:
flag[2]=1;
count++;
if(count>=6)
{
count=1;
}
break;
case0x07:
flag[3]=1;
break;
default:
break;
}
}
}
}
/********************延时函数*************************/
voiddelay(intnms)
{
inti;
intj;
for(i=nms;i>0;i--)
{
for(j=110;j>0;j--);
}
}
/**************************LCD1602*************************/
voidLCD_WRITE_COM(charcom)//1602写指令
{
E=0;
RS=0;//rs=0,写入命令
P0=com;
delay
(1);
E=1;//e=1
delay
(1);
E=0;//e=0
}
voidLCD_WRITE_TIM(chardata1)//1602写时间
{
charh,l;
h=data1/10;//取十位
l=data1%10;//取个位
h=h+0x30;
l=l+0x30;
RS=1;//rs=1,写入数据
P0=h;
delay
(1);
E=1;
delay
(1);
E=0;
RS=1;
P0=l;
delay
(1);
E=1;
delay
(1);
E=0;
}
voidLCD_WRITE_CHA(chardata2)//1602写符号
{
E=0;
RS=1;
P0=data2;
delay
(1);
E=1;
delay
(1);
E=0;
}
voidinit_1602()//1602初始化
{
LCD_WRITE_COM(0x38);//设置16*2显示
LCD_WRITE_COM(0x0c);//设置开显示,不显示光标
LCD_WRITE_COM(0x06);//写一个字符后地址指针加1
LCD_WRITE_COM(0x01);
LCD_WRITE_COM(0x14);
}
/**************************DS1302*************************/
/*ds1302写数据函数*/
/*函数功能:
向ds1302中写数据*/
/*参数:
目的地址和要写入的数据*/
voidds_write(unsignedcharaddr,unsignedchardat)
{
unsignedchari;
unsignedchartemp;
RES=0;//res清零,禁止传送
SCLK=0;//时钟清零
RES=1;//res置1,允许传送
//发送地址模块
temp=addr;
for(i=0;i<8;i++)
{
if(temp&0x01==1)
{
DIO=1;
}
else
{
DIO=0;
}
SCLK=0;//上升沿发送数据
delay
(1);
SCLK=1;
temp>>=1;
}
//发送数据模块
temp=dat;
for(i=0;i<8;i++)
{
if(temp&0x01==1)
{
DIO=1;
}
else
{
DIO=0;
}
SCLK=0;
delay
(1);
SCLK=1;
temp>>=1;
}
RES=0;
}
/*ds1302读数据函数*/
/*函数功能:
读取1302中的数据*/
/*参数:
要读取的数据所在的地址*/
unsignedchards_read(unsignedcharaddr)
{
unsignedchari;
unsignedchartemp;
unsignedchardat;
RES=0;
SCLK=0;
RES=1;
//发送地址模块
temp=addr;
for(i=0;i<8;i++)
{
if(temp&0x01==1)
{
DIO=1;
}
else
{
DIO=0;
}
SCLK=0;//上升沿发送数据
delay
(1);
SCLK=1;
temp>>=1;
}
//接收数据模块
temp=0;
for(i=0;i<8;i++)
{
if(DIO==0)
{
temp=temp&(0x7f);
}
else
{
temp=temp|(0x80);
}
SCLK=1;//单字节读数据,下降沿
delay
(1);
SCLK=0;
temp>>=1;
}
dat=temp/16;
temp=temp%16;
dat=dat*10+temp;
return(dat);
}
/*初始化1302函数*/
voidinit_1302()
{
ds_write(W_PROTECT,0x00);
ds_write(W_YEAR,0x11);
ds_write(W_MONTH,0x07);
ds_write(W_DAY,0x23);
ds_write(W_HOUR,0x08);
ds_write(W_MIN,0x00);
ds_write(W_SEC,0x00);
ds_write(W_PROTECT,0x80);
}
unsignedcharbcd_change(unsignedchardat)
{
unsignedchari=0;
i=dat/10;
dat=dat%10;
i<<=4;
i=i&0xf0;
dat=dat&0x0f;
dat=i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子钟 程序