📄 mainclockwws.c
字号:
/******************************************************************************************************
///////////////////////////////////////////////////////////////////////////////////////////////////////
电子时钟程序 王文硕 07-4-1/////////////////////////////////////////////////////////////////////////
//功能:---------完成分钟数的计时功能.可通过按键调整时间和设置闹钟.有2个闹钟可供使用////////////////////
//使用方法:-----时间设置:待通电后数码管显示12.00 则为当前显示时间.可通过按键4切换为时间设置模式,//////
// 按键1为小时加一,按键2为分钟数加一.按键3退出.//////////////////////////////////
//--------------闹钟1设置:待通电后数码管显示12.00 则为当前显示时间.可通过按键3切换至当前闹钟1时间,////
// 闹钟1初试值为11.11 则通过按键1来调整小时数加一,按键2来调整分钟数加一,按键4//
// 退出.////////////////////////////////////////////////////////////////////////
//--------------闹钟2设置:待通电后数码管显示12.00 则为当前显示时间.可通过按键2切换至当前闹钟1时间,////
// 闹钟2初试值为10.10 则通过按键1来调整进入小时数加一,按键2来调整分钟数加一,///
// 按键4则退出./////////////////////////////////////////////////////////////////
//注意:---------当闹钟时间设置超过30S则自动退出到当前时钟模式./////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************************************/
#include<pic.h>
static char led[15]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/////////////////////////////////不带小数点的段码
static char led1[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
/////////////////////////////////带小数点的段码
static char tab,number,k;
/////////////////////////////////取LED[]数组中的值用tab,键盘服务程序使用计数值number
static char clock[4]={0,0,2,1},wakeup1[4]={2,0,2,1},wakeup2[4]={0,1,0,1};
/////////////////////////////////时钟数组,闹钟1和闹钟2数组
static char mode=0,key=0,clktemp=0,sec=0;
/////////////////////////////////mode选择设置模式,分为时间设置mode=4,闹钟2设置mode=3,闹钟1设置mode=2
/////////////////////////////////key选择设置增加小时和分钟.clktemp为1分钟到后的中断标志位
static int i,time=0;
/////////////////////////////////循环使用值i,设置调整时间计数值,当调整内循环次数超过3000时.自动跳入主循环
/**********************************************************************
函数定义
**********************************************************************/
void initial(); //初始化函数
void speaker(char i); //蜂明器鸣响程序
void twinkle(char x); //RC5端口LED闪烁
void yw1641(char z); //移位显示函数-1段数码管
void yw1642(char z); //移位显示函数-2段数码管
void yw1643(char z); //移位显示函数-3段数码管
void yw1644(char z); //移位显示函数-4段数码管
void clkcf(); //时钟数据拆分函数
void checkclock(); //检测闹钟时间是否到了
void keyscan(); //键盘服务函数寻主键
void keyscanw(); //键盘服务函数寻副键
void DELAY2(); //短延时函数
void DELAY1(); //长延时函数
void DELAY3(); //防止按键颤抖延时函数
/************************************************************
==========================主程序==============================
**************************************************************/
void main()
{
initial(); //系统初始化
speaker(1); //蜂明器响3声
twinkle(2); //闪烁6次
INTCON=0xc0; //中断使能
PIE1=0x01; //T1中断使能
TMR1H=0x80; //32k晶振.初始值为0x8000.经调整为0x80a0.
TMR1L=0xa0;
for(;;)
{
checkclock();
switch(1) //主循环执行时钟数组扫描更新与键盘按键扫描
{
case 1: yw1641(clock[3]); //执行第一段数码管显示.显示内容为时钟数组clock[3] .
DELAY2(); //延时显示.此段延时决定数码管的亮度问题
case 2: yw1642(clock[2]); //执行第二段数码管显示.显示内容为时钟数组clock[2] .
DELAY2(); //延时显示.此段延时决定数码管的亮度问题
case 3: yw1643(clock[1]); //执行第三段数码管显示.显示内容为时钟数组clock[1] .
DELAY2(); //延时显示.此段延时决定数码管的亮度问题
case 4: yw1644(clock[0]); //执行第四段数码管显示.显示内容为时钟数组clock[0] .
DELAY2(); //延时显示.此段延时决定数码管的亮度问题
case 5: keyscan(); //外部寻找工作模式,得出工作模式mode的返回值
DELAY2(); //此段延时是为了保证程序的5次循环采用统一延时效果
break;
}
while(mode==2) //mode返回值为2--闹钟1调整
{ time=time+1; //时间设置超过3000没有任何操作则自动退出
switch(1) //次循环执行闹钟1时间的调整.即是移位164对时钟1的数组wakeup1[4]的扫描,循环显示
{
case 1: yw1641(wakeup1[3]); //执行第一段数码管显示.显示内容为时钟数组wakeup1[3] .
DELAY3(); //延时显示.此段延时决定数码管的亮度问题
case 2: yw1642(wakeup1[2]); //执行第二段数码管显示.显示内容为时钟数组wakeup1[2] .
DELAY3();
case 3: yw1643(wakeup1[1]); //执行第三段数码管显示.显示内容为时钟数组wakeup1[1] .
DELAY3();
case 4: yw1644(wakeup1[0]); //执行第四段数码管显示.显示内容为时钟数组wakeup1[0] .
DELAY3();
case 5: keyscanw(); //内部键盘循环.寻找按键是增加闹钟时间还是减小闹钟时间,跳出键
DELAY3();
break;
}
if(key==1) //按键key=1即是对闹钟1时间的增加.增加分钟时间
{
wakeup1[0]=wakeup1[0]+1; //闹钟时间分钟加一
if(wakeup1[0]==10) //闹钟分钟个位数满十
{
wakeup1[1]=wakeup1[1]+1; //则分钟数十位加一
wakeup1[0]=0; //分钟个位数清零
if(wakeup1[1]==6) //分钟十位满六
{
wakeup1[1]=0; //则分钟十位清零
wakeup1[0]=0; //分钟个位清零.相当于调整至59分钟.再从0开始加计数
}
}
key=0; //消除按键,防治再次跳入更改时间
}
if(key==3) //按键key=3对闹钟1的小时调整.
{
wakeup1[2]=wakeup1[2]+1; //闹钟小时个位加一
if(wakeup1[2]==10) //闹钟小时个位满十
{
wakeup1[3]=wakeup1[3]+1; //小时十位加一
wakeup1[2]=0; //小时个位清零
}
if(wakeup1[3]==2&&wakeup1[2]==4) //当时间增加为24小时时消为00
{
wakeup1[3]=0;wakeup1[2]=0; //小时个位十位统一清零
}
key=0; //消除按键,防治再次跳入更改时间
}
if(time>3000) mode=0;//时间设置超过3000没有任何操作则自动退出.次循环结束把模式mode值变为0,防止再次进入下模式
if(key==4) break; //按键4出现则调整闹钟结束
}
while(mode==3) //mode返回值为2--闹钟2调整
{
time=time+1; //时间设置超过3000没有任何操作则自动退出
switch(1)
{
case 1: yw1641(wakeup2[3]); //执行第一段数码管显示.显示内容为时钟数组wakeup1[3] .
DELAY3();
case 2: yw1642(wakeup2[2]); //执行第二段数码管显示.显示内容为时钟数组wakeup1[2] .
DELAY3();
case 3: yw1643(wakeup2[1]); //执行第三段数码管显示.显示内容为时钟数组wakeup1[1] .
DELAY3();
case 4: yw1644(wakeup2[0]); //执行第四段数码管显示.显示内容为时钟数组wakeup1[0] .
DELAY3();
case 5: keyscanw(); //内部键盘循环.寻找按键是增加闹钟时间还是减小闹钟时间,跳出键
DELAY3();
break;
}
if(key==1) //按键key=1即是对闹钟2时间的增加.增加分钟时间
{
wakeup2[0]=wakeup2[0]+1;
if(wakeup2[0]==10)
{
wakeup2[1]=wakeup2[1]+1;
wakeup2[0]=0;
if(wakeup2[1]==6)
{
wakeup2[1]=0;
wakeup2[0]=0;
}
}
key=0; //消除按键,防治再次跳入更改时间
}
if(key==2) //按键key=2对闹钟2的小时调整.
{
wakeup2[2]=wakeup2[2]+1;
if(wakeup2[2]==10)
{
wakeup2[3]=wakeup2[3]+1;
wakeup2[2]=0;}
if(wakeup2[3]==2&&wakeup2[2]==4) //当时间增加为24小时时消为00
{
wakeup2[3]=0;wakeup2[2]=0;
}
key=0;
}
if(time>3000) mode=0; //时间设置超过3000没有任何操作则自动退出.次循环结束把模式mode值变为0,防止再次进入下模式
if(key==4) break; //按键4出现则调整闹钟结束
}
while(mode==4) //次模式是对时间的更改模式mode=4
{
time=time+1;
switch(1)
{
case 1: yw1641(clock[3]);
DELAY3();
case 2: yw1642(clock[2]);
DELAY3();
case 3: yw1643(clock[1]);
DELAY3();
case 4: yw1644(clock[0]);
DELAY3();
case 5: keyscanw();
DELAY3();
break;
}
if(key==1) //按键key=1对当前时钟的小时调整.
{
clock[0]=clock[0]+1;
if(clock[0]==10)
{
clock[1]=clock[1]+1;
clock[0]=0;
if(clock[1]==6)
{
clock[1]=0;
clock[0]=0;
}
}
key=0;
}
if(key==2) //按键key=2对当前时钟的分钟调整.
{
clock[2]=clock[2]+1;
if(clock[2]==10)
{
clock[3]=clock[3]+1;
clock[2]=0;}
if(clock[3]==2&&clock[2]==4) //当时间增加为24小时时消为00
{
clock[3]=0;
clock[2]=0;
}
key=0;
}
if(time>3000) mode=0; //时间设置超过3000没有任何操作则自动退出.次循环结束把模式mode值变为0,防止再次进入下模式
if(key==3) break; //按键3出现则调整闹钟结束
}
if(clktemp==1) //主循环中执行对分钟标志clktemp的寻找.当出现时即对时间数组clock[4]的更新
{
clktemp=0; //清楚分钟标志
clkcf();
}
}
}
/********************************************************************
中断程序程序:
功能:执行对T1的时间溢出中断操作,当中断时再次对TMR1赋值.1S中断响应一次
********************************************************************/
void interrupt INT()
{
if(TMR1IF&&TMR1IE)
{
TMR1H=0x80; //T1时间高位赋值
TMR1L+=0xa0; //T1时间低位赋初值
TMR1IF=0; //清除中断标志位
sec=sec+1; //当中断来时,秒加一
if(sec==60) //当秒加到60的时候清零,置分钟位为1
{ sec=0; //秒计数值清零
clktemp=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -