(1)设计精度为0.1S的秒表系统。 (2)设置启动、暂停、清零按钮。 (3)秒表支持设置最长倒计时长度,超过此长度报警。 目前进程:设计精度为0.1s完成、设置启动、暂停、清零完成,秒表支持设置最长倒计时时间完成。现在就剩下如何当设置的倒计时时间到达后,蜂鸣器响了。蜂鸣器为P1^0.是不是应该在中断函数中加程序。
单片机源程序如下:
- #include<reg52.h> // 包含 52 单片机寄存器定义的头文件
- unsigned char Tab1[ ]={0x3f,0x06,0x5b,0x4f ,0x66,0x6d,0x7d,0x07,0x7f ,0x6f }; // 段码表
- unsigned char Tab2[ ]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 个位段码表
- unsigned int x;
- unsigned char k;
- sbit int0=P3^2; //开始/暂停//
- sbit int1=P3^3;
- sbit SUB60=P1^1; //正计时/倒计时//
- sbit S60=P1^2; //控制60s//
- sbit K5=P1^3;//加1s//
- sbit K6=P1^4;//减1s//
- sbit K7=P1^5; //赋值60s//
- sbit K8=P1^6; //清零//
- sbit baojing=P1^0;// 报警灯
- /*************************** 延时 1ms 基准 ******************************************/
- void delay1ms(unsigned int i)
- {
- unsigned char j;
- while(i--)
- {
- for(j=0;j<125;j++) //1ms 基准延时程序 12MHZ 晶振
- {
- ;
- }
- }
- }
- /********************************************************************************
- ****************** 数码管显示程序 ***********************************************/
- void Display(unsigned int x)
- {
- P2=0xfe; //P2.0 引脚输出低电平, DS6 点亮
- P0=Tab1[x/1000]; // 显示百位
- delay1ms(6);
- P2=0xfd; //P2.1 引脚输出低电平, DS6 点亮
- P0=Tab1[x%1000/100]; // 显示十位
- delay1ms(6);
- P2=0xfb; //P2.2 引脚输出低电平, DS6 点亮
- P0=Tab2[x%100/10]; // 显示个位
- delay1ms(6);
- P2=0xf7; //P2.3 引脚输出低电平, DS7 点亮
- P0=Tab1[x%10]; // 显示 0.1 位
- delay1ms(6);
- P2=0xff;
- }
- /*******************************************
- 函数功能:主函数
- ******************************************/
- void main(void)
- {
- x=0;
- TMOD=0x01; // TMOD=0000 0001B, 使用计数器 T0 的工作方式 1
- EA=1; // 开起总中断
- ET0=1; // 允许定时器 T0 的中断
- EX0=1; // 允许外中断 INT0
- IT0=1; //INT0 为下负脉冲触发方式
- TH0=(65536-50000)/256; // 计数器 T0 高 8 位赋初值
- TL0=(65536-50000)%256; // 计数器 T0 低 8 位赋初值
- TF0=0; // 溢出标志位清零
- while(1)
- {
- /************************************************************
- ****************K5 P1.3 按一次加 1 开关 S1***************************/
- if(K5==0)
- {
- delay1ms(20);
- if(K5==0)
- {
- x=x+10;
- }
- while(!K5); // 摁键关断 摁一次触发一次
- }
- /***********************************************************
- ************K6 P1.4 按一次减 1 开关 S2**************************/
- if(K6==0)
- {
- delay1ms(20);
- if(K6==0)
- {
- if(x==0)
- {
- x=10; // 在 00.0 的时候停止
- }
- x=x-10;
- }
- while(!K6); // 摁键关断 摁一次触发一次
- }
- /*********************************************************************
- ******************K7 P1.5 初始值 赋值为 60.0 秒开关 S5********************/
- if(K7==0)
- {
- delay1ms(20);
- if(K7==0)
- {
- x=600; // 赋初值 60.0 秒
- }
- while(!K7); // 摁键关断 摁一次触发一次
- }
- /*********************************************************************
- ******************S60 控制 60S 停止开关 P1.2****************************/
- if(x==600)
- {
- if(S60==0) // 如果 P1.2 口是低电平,秒表变化范围 00.0~60.0
- {
- TR0=0;
- }
- }
- /********************************************************************
- ******************K8 P1.6 清零 clear0 摁键开关 S3************************/
- if(K8==0)
- {
- delay1ms(20); // 延时消震
- if(K8==0)
- {
- x=0; // 数据清 0 数码管显示 000.0
- TR0=0; // 溢出标志位清 0
- }
- }
- /************ 数码管显示 ***************************************/
- Display(x);
- }
- }
- /**********INT0 中断函数 用于开始或暂停开关 S4******************
- **************************************************************/
- void begin_stop() interrupt 0
- {
- if(int0==0)
- {
- delay1ms(30); // 延时消震
- if(int0==0)
- {
- TR0=~TR0; // 按键摁一次 读秒开始或暂停
- if(x==0&&SUB60==0)
- {
- TR0=0;
- }
- }
- }
- }
- /*********************************************************
- ******T0 计数器中断 控制每隔加 0.1 秒 ***********************/
- void add_one0() interrupt 1
- {
- k++;
- if(k==2)
- {
- k=0;
- TF0=0;
- if(SUB60==1) // 当 P1.1 口是高电平时秒表加 0.1s
- // 当 P1.1 口是低电平时秒表减 0.1s
- {
- x=x+1; // 秒表加 0.1s
- }
- else
- {
- x=x-1; // 秒表减 0.1s
- }
- if(x==0)
- {
- TR0=0;
- }
- if(x==9999)
- {
- TR0=0;
- }
- }
- TH0=(65536-50000)/256; // 计数器 T0 高 8 位赋初值
- TL0=(65536-50000)%256; // 计数器 T0 低 8 位赋初值
- }
复制代码
|