功能要求:1.按下KEY1,显示数字开始每0.5秒加1,加到(10+学号)返回0,0显示2秒后继续开始重复加1。
2. 任何时候按下KEY2数字清零,并停止加1。
3. KEY1和KEY2分别采用查询和外部中断方式。
要求程序中有硬件定时和软件定时两种定时方式,给出系统的硬件电路、程序和仿真视频。
#include <REGX51.H>sbit KEY1 = P3^0; //定义按键KEY1
signed char mode = 2; //定义模式
signed char timer = 0, count = 0; //定时器0.5秒溢出计数
signed char number, number_h, number_l;//定义显示数字
unsigned char code SEG[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};//数码管显示0~9signed char nu = 1;//定时器两秒标志void Delayms(unsigned int xms) //毫秒延迟函数
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}void Mode_selection();//模式选择函数
void mode1(); //模式1
void mode2(); //模式2void main()
{EX0 = 1; //外部中断0允许IT0 = 1; //负跳变触发PX0 = 1; //外部中段0高优先级ET0 = 1; //T0定时器中断允许PT0 = 0; //T0定时器低优先级TMOD = 0x01;//T0以定时器方式1进行计数TH0 = 0x3C; //装入初值,定时50毫秒TL0 = 0xB0;EA = 1; //打开总中断TR0 = 1; //打开定时器while(1){Mode_selection();}
}void int_T0() interrupt 1
{if(number < 40)//$$$$$$$$$$$$数字根据自己需要更改{timer++;//50毫秒加一,timer == 10为0.5秒if(timer == 10){number++;//0.5秒加一if(timer == 10)timer = 0;} }if(number == 40)//$$$$$$$$$$$$数字根据自己需要更改{count++;if(count == 40)//两秒num清零$$$$$$$$$$$$数字根据自己需要更改{count = 0;nu = 0;} }TH0 = 0x3C; //重装初值TL0 = 0xB0;
}void int_EX1() interrupt 0
{mode = 2;
}void Mode_selection()
{switch(mode){case 1:mode1(); break;case 2:mode2(); break;}
}void mode1()
{while(1){//分开number高位低位number_h = number/10;number_l = number%10;P0 = 0x01;P1 = SEG[number_h];Delayms(1);P0 = 0x02;P1 = SEG[number_l];Delayms(1);if(number == 40)//加到(10+学号)返回0,0显示2秒后继续开始重复加1$$$$$$$$$$$$数字根据自己需要更改{while(nu){P0 = 0x01;P1 = SEG[0];Delayms(1);P0 = 0x02;P1 = SEG[0];Delayms(1); }number = 0;nu = 1;TH0 = 0x3C;//重装初值TL0 = 0xB0; }if(mode != 1)break;}
}void mode2()
{TR0 = 0;//关闭定时器ET0 = 0;//关闭定时器中断number = 0;while(1){P0 = 0x01;P1 = SEG[0];Delayms(1);P0 = 0x02;P1 = SEG[0];Delayms(1); if(KEY1 == 0)//检测按键KEY1是否按下{Delayms(10);if(KEY1 == 0);mode = 1;}if(mode != 2)//判断是否切换模式break;}ET0 = 1;//打开定时器中断TH0 = 0x3C;//重装初值TL0 = 0xB0; TR0 = 1;//打开定时器
}