完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
|
|
牛人 就是牛人 自愧不如啊
|
|
|
|
|
|
本帖最后由 friend0720 于 2016-2-25 17:52 编辑
!!!!!!!!!!!!!! |
|
|
|
|
|
利用鸿哥的程序框架写的,供大家看看。
/* 单片机课程设计 课题名称 :基于单片机的电子时钟设计 时间 :2013年6月13日 硬件 :P0口 接数码管的段码。 P2口 接数码的位选 六个独立按键接 P1^0 到 P1^5 口 晶振 12 MHz 单片机 AT89C51 功能 : 利用定时中断进行计时,有正常时间显示, 有秒表启动、停止、复位功能 ,时间可以 调整, 时间调整 按加键时间加1,若不松开, 1s后进入连续加1直至松开按钮。 */ #include #define cnt_delay_cnt1 25 //按键去抖延时 void delay1(unsigned int de); // 小延时 数码管显示暂留延时 void display(); // 显示函数 void key_scan(); //按键扫描函数放在中断函数里面 void key_service(); //案件服务函数放在主函数里面 ***it key_sr1=P1^0;//独立按键输入 启动 ***it key_sr2=P1^1;//独立按键输入 停止 ***it key_sr3=P1^2;//。。。。。。 复位 ***it key_sr4=P1^3; // 模式 ***it key_sr5=P1^4; // 加 ***it key_sr6=P1^5; // 减 unsigned char key_lock1=0; //按键自锁标志 unsigned char key_lock2=0; unsigned char key_lock3=0; unsigned char key_lock4=0; unsigned char key_lock5=0; unsigned char key_lock6=0; unsigned int delay_cnt=0; // 6号键长按延时 unsigned int delay_cnt_1=0; // 5号键长按延时 unsigned int delay_cnt1=0; //延时计数器的变量 unsigned int delay_cnt2=0; unsigned int delay_cnt3=0; unsigned int delay_cnt4=0; unsigned int delay_cnt5=0; unsigned int delay_cnt6=0; unsigned char key_sec=0;//哪个键被触发 unsigned char wd_sec = 1; bit biaozhi = 1; // 位闪烁用 时间标志 bit start =0; // 秒表开始标志 bit sec_sec = 0; //用来区分 从秒表模式切换到 正常显示(1) 还是 调整时间(0) unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; // 段码数组 0到9 + '-' + ' ' unsigned char code wele[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; // 数码管位选码 unsigned char temp[]={0,0,10,0,0,10,0,0}; // 显示缓冲区 (原先将 '-' 写入) int time=0,sec=0,min=0,hour=0 ; // 定义时间的 变量 int timesec=0,time_sec =0, time_min=0; // 定义秒表的变量 void InitTimer1(void) // 系统初始化 函数 { TMOD = 0x10; TH1 = 0x0D8; TL1 = 0x0F0; EA = 1; ET1 = 1; TR1 = 1; } void main(void) // 主函数 { InitTimer1(); // 初始化 while(1) { display(); // 显示子程序 key_service(); //按键服务程序 } } void display() // 显示函数 { static unsigned char i; switch(wd_sec) // 不同模式(窗口)下给显示缓冲区的值不同 { case 1: // 正常显示时间 temp[7]=sec%10; temp[6]=sec/10; temp[4]=min%10; temp[3]=min/10; temp[1]=hour%10; temp[0]=hour/10; break; case 2: // 显示秒表模式 // **************** temp[7]=timesec%10; temp[6]=timesec/10; temp[4]=time_sec%10; temp[3]=time_sec/10; temp[1]=time_min%10; temp[0]=time_min/10; break; case 3: // 时间调整 秒 temp[4]=min%10; temp[3]=min/10; if (biaozhi) // 闪烁标志 { temp[7]=sec%10; // 显示 temp[6]=sec/10; } else { temp[7]=11 ; // 灭 temp[6]=11 ; } temp[1]=hour%10; // 分离个位 temp[0]=hour/10; // 分离十位 break; case 4:// 时间调整 分 temp[7]=sec%10; temp[6]=sec/10; if (biaozhi) // 闪烁标志 { temp[4]=min%10; temp[3]=min/10; } else { temp[4]=11 ; temp[3]=11 ; } temp[1]=hour%10; temp[0]=hour/10; break; case 5:// 时间调整 时 temp[7]=sec%10; temp[6]=sec/10; temp[4]=min%10; temp[3]=min/10; if (biaozhi) // 闪烁标志 { temp[1]=hour%10; temp[0]=hour/10; } else { temp[1]=11; temp[0]=11 ; } break; } delay1(1); P0=0xff; // 关段码 P2= 0x00; // 关位码 用于消影 delay1(1); P2=wele[i]; // 位选 P0=table[temp[i]]; //段选 delay1(50); // 延时 视觉暂留 if(++i>8) i=0; } void delay1(unsigned int de) //延时函数 { unsigned int t; for(t=0;t void key_scan() // 按键扫描函数 { if(key_sr1==1) // 第一个按键松开 { key_lock1=0; // 解锁 delay_cnt1=0; // 延时计数清零 } else if(key_lock1==0) // { ++delay_cnt1; if(delay_cnt1>cnt_delay_cnt1) // 消抖动 { delay_cnt1=0; key_lock1=1; key_sec=1;//触发1号键 } } if(key_sr2==1) { key_lock2=0; delay_cnt2=0; } else if(key_lock2==0) { ++delay_cnt2; if(delay_cnt2>cnt_delay_cnt1) { delay_cnt2=0; key_lock2=1; key_sec=2;//触发2号键 } } if(key_sr3==1) { key_lock3=0; delay_cnt3=0; } else if(key_lock3==0) { ++delay_cnt3; if(delay_cnt3>cnt_delay_cnt1) { delay_cnt3=0; key_lock3=1; key_sec=3;//触发3号键 } } if(key_sr4==1) { key_lock4=0; delay_cnt4=0; } else if(key_lock4==0) { ++delay_cnt4; if(delay_cnt4>cnt_delay_cnt1) { delay_cnt4=0; key_lock4=1; key_sec=4;//触发4号键 } } if(key_sr5==1) { key_lock5=0; delay_cnt5=0; delay_cnt_1=0; } else //if(key_lock5==0) { ++delay_cnt5; if(delay_cnt5>cnt_delay_cnt1) //消抖 { // delay_cnt5=0; // key_lock5=1; // key_sec=5;//触发5号键 加 if(++delay_cnt_1 >100) // 长按延时检测 { key_sec = 11; // 连发状态 } else if (key_lock5 == 0) { key_lock5=1; key_sec = 5; //单发 } } } if(key_sr6==1) { key_lock6=0; delay_cnt6=0; delay_cnt=0; } else// if(1)//(key_lock6==0) { ++delay_cnt6; if(delay_cnt6>cnt_delay_cnt1) { //delay_cnt6=0; //key_lock6=1; //key_sec=6;//触发6号键 减 if(++delay_cnt >100) { key_sec = 12; // 连发状态 } else if (key_lock6 == 0) { key_lock6=1; key_sec = 6; //单发 } } } } void key_service() // 按键服务函数 { static unsigned char x =0; switch(key_sec) { case 1:// 开始键 switch (wd_sec) { case 2: // 秒表 模式 start = 1; // 启动秒表 sec_sec = 1; // 秒表执行标志 用于窗口转换选择 break; } key_sec = 0; break; case 2: // 停止键 switch (wd_sec) { case 2: // 秒表 模式 // qing dong miao biao start = 0; sec_sec = 1; // 秒表执行标志 用于窗口转换选择 break; } key_sec = 0;//清除键值 break; case 3: // 复位键 switch (wd_sec) { case 2: // 秒表 模式 //qing dong miao biao if(!start) // 秒表在停止状态下 才允许复位 { time_sec = 0; time_min = 0; timesec = 0; } sec_sec = 1; //秒表执行标志 用于窗口转换选择 break; } key_sec = 0;//清除键值 break; case 4: // 菜单键 switch(wd_sec) { case 1: // 正常显示 wd_sec++; sec_sec = 0; break; case 2: // 秒表模式 if (sec_sec) // 判断秒表模式是否执行了,若执行了切换到 正常显示模式 wd_sec = 1; else // 否则 转到调时间模式 wd_sec++; break; case 3: // 调秒 wd_sec++; break; case 4: // 调分 wd_sec++; break; case 5: // 调时 wd_sec=1; break; } key_sec = 0;//清除键值 break; case 5: // 时间单个加 switch (wd_sec) { case 3: if(++sec >59) //秒上限 sec = 0; break; case 4: if(++min >59) // 分上限 min = 0; break; case 5: if (++hour > 23) //时上限 hour = 0; break; } key_sec = 0; //清除键值 break; case 6: // 时间单个减 switch (wd_sec) { case 3: if (--sec < 0 ) sec = 59; break; case 4: if (--min < 0 ) min = 59; break; case 5: if (--hour <0) hour = 23; break; } key_sec = 0; //清除键值 break; case 11: // 时间连续加 if(++x>80) { x =0; switch (wd_sec) { case 3: if(++sec >59) sec = 0; break; case 4: if(++min >59) min = 0; break; case 5: if (++hour > 23) hour = 0; break; } key_sec = 0; //清除键值 } break; case 12: // 时间连续减 if(++x>80) { x =0; switch (wd_sec) { case 3: if (--sec < 0 ) sec = 59; break; case 4: if (--min < 0 ) min = 59; break; case 5: if (--hour <0) hour = 23; break; } key_sec = 0;//清除键值 } break; } } void Timer1Interrupt(void) interrupt 3 // 10 ms 中断函数 { static unsigned char time1; TH1 = 0x0D8; // 重新装入初值 TL1 = 0x0F0; if (!(wd_sec == 3 | wd_sec == 4 | wd_sec == 5 )) // 时间在 调整过程中不允许走时 { if(++time==100) // 一秒时间到 { time=0; if(++sec==60) // 一分钟时间到 { sec=0; if(++min==60) // 一小时时间到 { min=0; if(++hour==24) // 一天时间到 { hour=0; } } } } } if (wd_sec == 2 && start==1) // 秒表开始计时条件( 在秒表模式且秒表启动 ) { if (++timesec == 100) // 1秒时间到 { timesec =0; if (++time_sec == 60) // 1分钟时间到 { time_sec =0; time_min++; } } } if (++time1>= 25) // 时间调整的闪烁标志 { time1=0; biaozhi = ~biaozhi; } key_scan(); // 按键扫描 } |
|
|
|
|
|
|
|
|
|
牛人呀 {:7:}人呀
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
求解外围电路实现的是4脚给持续低电平复位并正常工作,高电平不工作的原因
2087 浏览 1 评论
3633 浏览 3 评论
PIC1946程序有一个变量在运行过程中恢复初始值其他变量保持不变
2337 浏览 2 评论
2764 浏览 0 评论
PIC16F1825的RC5引脚,在主程序中操作无效,在中断中可以改变是为什么?
4033 浏览 5 评论
980浏览 0评论
用XC8编译PIC18F25K80时提示下面Error,求怎么解决这个问题
6366浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-5 11:15 , Processed in 1.051399 second(s), Total 90, Slave 81 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号