正计时状态
倒计时状态
锂电池及带保护的充电模块
安装中
电路图
单片机源程序如下:
- /* PIC16F630为核心的厨房定时器 注:所有的(12个)I/O口都用完
- * 功能:倒(正)计时1秒-99分59秒
- * 显示:数码管显示分钟和秒钟;双色LED秒闪显示秒状态;两种LED分别显示功能状态:倒计
- 时橙色灯和正计时绿色灯显示。
- * 提示音:1、计时结束:嘟嘟嘟连续响五次;2、正计时逢5分钟提示一个长音:嘟;3正计时
- 逢10分钟提示两个半长音:嘟-嘟
- * 人机交互:五个按键分别是启动/停止;正/倒计时;加十分;加1分;加1秒/暂停/继续
- * 电源开启:默认倒计时状态-加分加秒-启动
- * 计时精度依赖于PIC16F630内部振荡器(4M)的精度和程序设计定时器初值的设定
- */
- /* 本程序已经成功制作出成品,外壳使用的是银行点钞机外显示外壳
- #include<pic.h>
- __CONFIG(0x3184); //配置:禁止数据和程序的代码保护;禁止低电压检测;RA3作为普通I/O口
- ;上电复位开;看门狗关闭;使用内部振荡器。
- //输入键:RA3,RC1,RC3,RC4,RC5。其余键均为输出
- #define BZZP RC2 //蜂鸣器接口
- #define CLK RA5 // 74HC164时钟输入
- #define DAT RA4 // 74HC164数据端口
- #define WEI3 RA0 // 秒十位
- #define WEI4 RA1 // 秒个位
- #define WEI1 RA2 // 分十位
- #define WEI2 RC0 // 分个位
- #define QID RC1 //启动/停止键
- #define ZDAO RC3 //正/倒计时
- #define JSHF RC4 //加十分
- #define JGOF RC5 //加个分
- #define JMIAO RA3 //加秒
- #define uchar unsigned char
- #define uint unsigned int
- uchar timecnt = 0,fs=0,fg=0,ms=0,mg=0;
- bit zhengdao,qidong,zhantin;
- //mss:秒闪烁;zdjs:正倒计时0倒1正;qdtz:启动停止0停1动;ztjx暂停/继续 0暂停 1继续
- const unsigned char LED[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
- //0-9十个数值的编码(共阴数码管)
- void delay(uint);//延时函数
- void dududu(void);//嘟嘟嘟
- void changdu(void);//长嘟
- void dudu(void);//嘟嘟
- void smduan(uchar);//写串行数据入164
- void keytest(void); //键扫描函数
- void Init(void); //初始化子函数
- void zhengjishi(void); //正计时函数
- void daojishi(void); //倒计时函数
- void interrupt ISR(void) //PIC单片机的所有中断都是这一个入口
- {
- if(TMR1IF==1) //需要进一步判断是否是T1中断
- {
- TMR1H=0x0B; //重置初值
- TMR1L=0xEA; //重置初值 E9
- TMR1IF=0; //清中断标志位,以备下次中断
- //***此处用户自行添加定时器T1中断处理程序***
- timecnt++;
- if(timecnt==2)
- {timecnt=0;
- if(qidong==1)
- { if(zhengdao==1) zhengjishi();
- else daojishi();
- }
- }
- }
- }
- main()
- {
- uchar x;
- Init();
- while(1)
- {
- keytest();
- if(fs>0)
- {smduan(LED[fs]);
- WEI1=0;
- delay(3);
- WEI1=1;
- }
- if(timecnt==1) x=LED[fg]+0x80;
- else x=LED[fg];
- smduan(x);
- WEI2=0;
- delay(3);
- WEI2=1;
- if(zhengdao==0) x=LED[ms]+0x80;
- else x=LED[ms];
- smduan(x);
- WEI3=0;
- delay(3);
- WEI3=1;
- if(zhengdao==1) x=LED[mg]+0x80;//正计时灯亮
- else x=LED[mg];
- smduan(x);
- WEI4=0;
- delay(3);
- WEI4=1;
- }
- }
- void zhengjishi(void) //正计时函数
- {
- mg++;
- if(mg==10)
- { mg=0;
- ms++;
- if(ms==6)
- {
- ms=0;
- fg++;
- if(fg==5) changdu();
- if(fg==10)
- {
- fg=0;
- fs++;
- dudu();
- if(fs==10)
- fs=0;
- }
- }
- }
- }
- void delay(uint x) //延时函数
- {
- uint a,b;
- for(a=x;a>0;a--)
- for(b=100;b>0;b--);
- }
- void dududu(void) //连续三声嘟
- {
- uchar i,j;
- for(j=5;j>0;j--)
- {for(i=3;i>0;i--)
- {
- BZZP=1;
- delay(200);
- BZZP=0;
- delay(30);
- }
- delay(300);
- }
- }
- void changdu(void) //长嘟
- {
- BZZP=1;
- delay(300);
- BZZP=0;
- }
- void dudu(void) //两声嘟
- {
- uchar i;
- for(i=2;i>0;i--)
- {
- BZZP=1;
- delay(200);
- BZZP=0;
- delay(20);
- }
- }
- //按键处理程序
- void keytest(void)
- {
- if(QID==0)
- {
- while(QID==0) //按键去抖
- { delay(100);}
- qidong=!qidong;
- if(qidong==0)
- {
- TMR1ON=0; //关闭定时器1
- fs=fg=ms=mg=0;
- zhengdao=0; //停止时默认倒计时
- }
- else TMR1ON=1; //启动定时器1
- }
- ///////////////// 正倒计时转换
- if(ZDAO==0)
- {
- while(ZDAO==0) //按键去抖
- { delay(100);}
- if(qidong==0) //停止状态有效
- zhengdao=!zhengdao;
- }
- //////////////// 加分十位
- if(JSHF==0)
- {
- while(JSHF==0) //按键去抖
- { delay(100);}
- if(zhengdao+qidong==0) // 倒计时和停止状态下才能运行
- {
- fs++;
- if(fs==10) fs=0;
- }
- }
- /////////////////
- if(JGOF==0)
- {
- while(JGOF==0) //按键去抖
- { delay(100);}
- if(zhengdao+qidong==0) // 倒计时和停止状态下才能运行
- {
- fg++;
- if(fg==10) fg=0;
- }
- }
- ////////////////
- if(JMIAO==0)
- {
- while(JMIAO==0) //按键去抖
- { delay(100);}
- if(zhengdao+qidong==0) // 倒计时和停止状态下才能运行
- {
- mg++;
- if(mg==10)
- {
- mg=0;
- ms++;
- if(ms==6) ms=0;
- }
- }
- if(qidong==1) //暂停与继续
- {
- zhantin=!zhantin;
- if(zhantin==0)
- TMR1ON=0; //暂停:关闭定时器1
- else
- TMR1ON=1; //继续:开启定时器1
- }
- }
- }
- void Init(void) //主函数初始化
- {
- OPTION=0b10000000; //禁止弱上拉
- WPUA= 0x00; //关闭弱上拉
- TRISA=0B00001000; //RA3 口做输入,且只能作为输入
- TRISC=0B00111010; //RC5,4,3,2做输入,RC0,2做输出
- PORTA=0B00001000;
- PORTC=0B00111010;
- //INTCON=0; //关中断
- CMCON=0x07; // 设置全部为普通数字IO口 关闭所有比较器
- PIE1 = 0X01; //T1溢出中断使能位
- PIR1 = 0X00; //T1溢出标志位,每次溢出都要软件清0
- T1CON = 0X05; //设置T1中断参数
- //***定时器TMR1初始化***
- TMR1CS=0; //TMR1时钟源选择内部指令周期时钟(Fosc/4)
- T1CKPS0=1; //1:8预分频比,T1CKPS0=1
- T1CKPS1=1; //1:8预分频比,T1CKPS1=1
- TMR1H=0x0B; //定时62500×8微秒,置初值为65536-62500+13
- TMR1L=0xEA; //定时62500×8微秒,置初值为65536-62500+13
- TMR1ON=0; //启动定时器T1(暂停)
- TMR1IF=0; //清除T1的中断标志
- TMR1IE=1; //T1中断允许
- PEIE=1; //外设中断允许,TMR1属于外设中断范围
- //**********************
- //***开全局中断设置****
- //定时器T1设置了中断允许,此处要开全局中断
- GIE=1;
- WEI1=1;
- WEI2=1;
- WEI3=1;
- WEI4=1;
- zhantin=1;
- }
- void smduan(uchar udata) //向164传输段码
- {
- uchar i;
- for (i=0;i<8;i++)
- {
- if(udata&0x80)
- DAT=1;
- else
- DAT=0;
- CLK=0;
- asm("NOP");
- asm("NOP");
- CLK=1;
- udata = udata<<1;
- CLK=0;
- }
- }
- void daojishi(void) //倒计时函数
- {
- if(fs+fg+ms+mg>0)
- {
- if(mg>0) mg--;
- else
- {
- if(ms>0)
- {
- ms--;
- mg=9;
- }
- else
- {
- if(fg>0)
- {
- fg--;
- ms=5;
- mg=9;
- }
- else
- {
- if(fs>0)
- {
- fs--;
- fg=9;
- ms=5;
- mg=9;
- }
- }
- }
- }
- }
- else
- {dududu(); //倒计时}时间到,蜂鸣器工作
- zhengdao=1; //正计时开始
- }
- }
复制代码 |