void main() { unsigned char key3_flag=0,key4_flag=0; TMOD |=0x01; TH0=0xd8; TL0=0xf0; ET0=1; TR0=0; TMOD |=0x10; TH1=0xF8; TL1=0xf0; ET1=1; TR1=1; EA =1; sec=0; ms=0; P1=0xff; i=0; j=0; start: while(1) { //¿ªÊ¼¡¢ÔÝÍ£ if(!key1) { delay(50); if(!key1) while(!key1) {;} TR0=!TR0; } //¼Ç¼ if(!key2) { delay(50); if(!key2) { while(!key2) //µÈ´ý°´¼üÊÍ·Å {;} if(i==8) {TR0=0; goto start;} Sec[i]= sec; Ms[i]= ms; i++; } } //ÉÏ· if(!key3) { delay(50); if(!key3) { while(!key3) {;} TR0=0; key3_flag=1; //°´¼ü3±êÖ¾ if(j==i) goto start; else if(key4_flag) j+=2; key4_flag=0; sec=Sec[j];ms=Ms[j]; j++; } } //Ï· if(!key4) { delay(50); if(!key4) { while(!key4) {;} TR0=0; key4_flag=1; if(j<0) goto start; else if(key3_flag) j-=2; key3_flag=0; sec=Sec[j];ms=Ms[j]; j--; } } if(!key5) { delay(50); if(!key5) while(!key5) {;} TR0=0; ms=0; sec=0; for(i=0;i<8;i++) { Sec[i]=0;Ms[i]=0; } i=0; }} void time1_isr(void) interrupt 3 using 0 { static unsigned char num; TH1=0xF8; TL1=0xf0; switch(num) { case 0: P2=0xfe;P0=tab[sec/10];break; case 1: P2=0xfd;P0=tab1[sec%10];break; case 2: P2=0xfb;P0=tab[ms/10];break; case 3: P2=0xf7;P0=tab[ms%10];break; default:break; } num++; if(num==4) num=0; }
时间: 2023-10-22 09:03:25 浏览: 80
这是代码的第二部分,其中定义了一个名为 `time1_isr` 的中断处理函数。
1. 首先定义了一个静态无符号字符型变量 `num`,用于记录当前显示的数码管位数。
2. 在中断处理函数中,首先设置了定时器1的高位和低位初值,分别是 `TH1=0xF8` 和 `TL1=0xf0`。
3. 使用一个 `switch-case` 结构根据变量 `num` 的值来选择要显示的数码管位数。
4. 当 `num` 的值为0时,设置 P2 端口的状态为 0xfe,表示选择第一个数码管,并将要显示的数值 `sec/10` 通过 `tab` 数组查找对应的显示值,并赋给 P0 端口。
5. 当 `num` 的值为1时,设置 P2 端口的状态为 0xfd,表示选择第二个数码管,并将要显示的数值 `sec%10` 通过 `tab1` 数组查找对应的显示值,并赋给 P0 端口。
6. 当 `num` 的值为2时,设置 P2 端口的状态为 0xfb,表示选择第三个数码管,并将要显示的数值 `ms/10` 通过 `tab` 数组查找对应的显示值,并赋给 P0 端口。
7. 当 `num` 的值为3时,设置 P2 端口的状态为 0xf7,表示选择第四个数码管,并将要显示的数值 `ms%10` 通过 `tab` 数组查找对应的显示值,并赋给 P0 端口。
8. `switch-case` 结构结束后,递增变量 `num`。
9. 如果 `num` 的值等于4,将其重置为0。
这个中断处理函数的作用是通过定时器1的中断来循环显示计时器的秒数和毫秒数在四个数码管上。
相关问题
void main() { unsigned char key3_flag=0,key4_flag=0; TMOD |=0x01; TH0=0xd8; TL0=0xf0; ET0=1; TR0=0; TMOD |=0x10; TH1=0xF8; TL1=0xf0; ET1=1; TR1=1; EA =1; sec=0; ms=0; P1=0xff; i=0; j=0; start: while(1) { //¿ªÊ¼¡¢ÔÝÍ£ if(!key1) { delay(50); if(!key1) while(!key1) {;} TR0=!TR0; } //¼Ç¼ if(!key2) { delay(50); if(!key2) { while(!key2) //µÈ´ý°´¼üÊÍ·Å {;} if(i==8) {TR0=0; goto start;} Sec[i]= sec; Ms[i]= ms; i++; } } //ÉÏ· if(!key3) { delay(50); if(!key3) { while(!key3) {;} TR0=0; key3_flag=1; //°´¼ü3±êÖ¾ if(j==i) goto start; else if(key4_flag) j+=2; key4_flag=0; sec=Sec[j];ms=Ms[j]; j++; } } //Ï· if(!key4) { delay(50); if(!key4) { while(!key4) {;} TR0=0; key4_flag=1; if(j<0) goto start; else if(key3_flag) j-=2; key3_flag=0; sec=Sec[j];ms=Ms[j]; j--; } } if(!key5) { delay(50); if(!key5) while(!key5) {;} TR0=0; ms=0; sec=0; for(i=0;i<8;i++) { Sec[i]=0;Ms[i]=0; } i=0; } } }代码每一步的讲解
这段代码是一个主函数,主要用于控制一个计时器。我会逐步讲解代码的每一步。
1. 首先定义了两个无符号字符型的变量 `key3_flag` 和 `key4_flag`,用于记录按键3和按键4的状态。
2. 然后设置了定时器模式TMOD的值。通过 `TMOD |=0x01` 和 `TMOD |=0x10` 分别设置定时器0和定时器1的工作模式。
3. 接着设置了定时器0的高位和低位初值,分别是 `TH0=0xd8` 和 `TL0=0xf0`。
4. 然后使能了定时器0中断,通过 `ET0=1`。
5. 将定时器0的启动状态设为0,通过 `TR0=0`。
6. 接下来设置了定时器1的高位和低位初值,分别是 `TH1=0xF8` 和 `TL1=0xf0`。
7. 使能了定时器1中断,通过 `ET1=1`。
8. 将定时器1的启动状态设为1,通过 `TR1=1`。
9. 最后使能了总中断,通过 `EA =1`。
10. 定义了变量 `sec` 和 `ms`,并将其初始化为0。
11. 将P1端口的初始值设置为全1,通过 `P1=0xff`。
12. 定义了变量 `i` 和 `j`,并将其初始化为0。
13. 标记一个 `start` 标签,用于后面的跳转。
14. 进入一个无限循环 `while(1)`。
15. 如果按键1被按下,通过 `!key1` 来判断,执行以下操作:
- 延时50毫秒,通过 `delay(50)`。
- 再次判断按键1的状态,通过 `!key1`。
- 当按键1仍然被按下时,进入一个空循环,通过 `while(!key1) {;}`。
- 将定时器0的启动状态取反,通过 `TR0=!TR0`。
16. 如果按键2被按下,通过 `!key2` 来判断,执行以下操作:
- 延时50毫秒,通过 `delay(50)`。
- 再次判断按键2的状态,通过 `!key2`。
- 当按键2仍然被按下时,进入一个空循环,通过 `while(!key2) {;}`。
- 如果变量 `i` 的值等于8,则跳转到标签 `start`。
- 否则,将当前的秒数和毫秒数分别保存到数组 `Sec` 和 `Ms` 中,并递增变量 `i`。
17. 如果按键3被按下,通过 `!key3` 来判断,执行以下操作:
- 延时50毫秒,通过 `delay(50)`。
- 再次判断按键3的状态,通过 `!key3`。
- 当按键3仍然被按下时,进入一个空循环,通过 `while(!key3) {;}`。
- 将定时器0的启动状态设为0,通过 `TR0=0`。
- 将变量 `key3_flag` 设为1,表示按键3被按下。
- 如果变量 `j` 的值等于变量 `i`,则跳转到标签 `start`。
- 否则,如果变量 `key4_flag` 的值为真(非零),则将变量 `j` 增加2。
- 将变量 `key4_flag` 设为0。
- 将数组 `Sec` 和 `Ms` 中第 `j` 个位置的值分别赋给变量 `sec` 和 `ms`。
- 递增变量 `j`。
18. 如果按键4被按下,通过 `!key4` 来判断,执行以下操作:
- 延时50毫秒,通过 `delay(50)`。
- 再次判断按键4的状态,通过 `!key4`。
- 当按键4仍然被按下时,进入一个空循环,通过 `while(!key4) {;}`。
- 将定时器0的启动状态设为0,通过 `TR0=0`。
- 将变量 `key4_flag` 设为1,表示按键4被按下。
- 如果变量 `j` 的值小于0,则跳转到标签 `start`。
- 否则,如果变量 `key3_flag` 的值为真(非零),则将变量 `j` 减少2。
- 将变量 `key3_flag` 设为0。
- 将数组 `Sec` 和 `Ms` 中第 `j` 个位置的值分别赋给变量 `sec` 和 `ms`。
- 递减变量 `j`。
19. 如果按键5被按下,通过 `!key5` 来判断,执行以下操作:
- 延时50毫秒,通过 `delay(50)`。
- 再次判断按键5的状态,通过 `!key5`。
- 当按键5仍然被按下时,进入一个空循环,通过 `while(!key5) {;}`。
- 将定时器0的启动状态设为0,通过 `TR0=0`。
- 将毫秒数和秒数重置为0,通过 `ms=0; sec=0`。
- 将数组 `Sec` 和 `Ms` 中的所有元素都设为0,通过一个循环:`for(i=0;i<8;i++){ Sec[i]=0; Ms[i]=0; }`。
- 将变量 `i` 重置为0。
20. 回到循环的开头,继续下一轮循环。
#include <reg51.h> sbit lamp_pwm = P2^3; sbit key0 = P3^0; sbit key1 = P3^1; #define uint unsigned int #define uchar unsigned char uint inc = 8000; uint flag=0; void main() { TMOD |= 0x01; IT0 = 1; EX0 = 1; ET0 = 1; EA = 1; while (1) ; } void INT0s() interrupt 0 using 0 { TR0 = 0; if (!key0) // liangdu- { inc += 50; if (inc >= 8000) { inc = 8000; } } if (!key1) //liangdu+ { inc -= 50; if (inc <= 800) { inc = 800; } } TH0 = (65536 - inc) / 256; TL0 = (65536 - inc) % 256; TR0 = 1; } void timer1() interrupt 1 using 0 { unsigned char q; lamp_pwm = 0; for (q = 0; q < 2; q++); lamp_pwm = 1; }在此代码中加入一个总开关,负责灯炮pwm的开关
可以在主函数中加入一个变量来表示总开关的状态,然后在INT1的中断函数中判断总开关状态,根据状态来控制灯炮PWM的开关。代码如下:
#include <reg51.h>
sbit lamp_pwm = P2^3;
sbit key0 = P3^0;
sbit key1 = P3^1;
sbit switch = P3^2; // 总开关
#define uint unsigned int
#define uchar unsigned char
uint inc = 8000;
uint flag = 0;
bit switch_state = 1; // 总开关状态,默认为开
void main()
{
TMOD |= 0x01;
IT0 = 1;
EX0 = 1;
ET0 = 1;
EA = 1;
while (1)
{
switch_state = switch; // 读取总开关状态
}
}
void INT0s() interrupt 0 using 0
{
TR0 = 0;
if (!key0) // 亮度+
{
inc += 50;
if (inc >= 8000)
{
inc = 8000;
}
}
if (!key1) // 亮度-
{
inc -= 50;
if (inc <= 800)
{
inc = 800;
}
}
TH0 = (65536 - inc) / 256;
TL0 = (65536 - inc) % 256;
TR0 = 1;
}
void timer1() interrupt 1 using 0
{
if (switch_state) // 总开关为开
{
unsigned char q;
lamp_pwm = 0;
for (q = 0; q < 2; q++);
lamp_pwm = 1;
}
}
在以上代码中,我们新增了一个sbit变量switch,表示总开关的状态。在主函数中,我们通过读取P3口的第二位来获取总开关状态。在timer1中断函数中,我们加入了对总开关状态的判断,只有当总开关为开时,才执行灯炮PWM的开关。
阅读全文