作业讲解
第三题:
先用定时器0把流水灯的写出来,再写定时器1的数码管显示,用变量存储765432,再定时器中断函数里自减,当到达7654398时,关闭定时器就不会变化了,这里765是不变的,偷懒,只管432。写完数码管停止和流水灯停止都试验后再写剩下的。改变定时器计时时间这里要记住。
1 #include<reg51.h> 2 #include<intrins.h> 3 4 #define uchar unsigned char 5 #define uint unsigned int 6 7 void Delay1ms(); 8 void delay(int n); 9 void display(uchar a,uchar b,uchar c,uchar bai,uchar shi,uchar ge); 10 void init(); 11 sbit WEI=P2^7; 12 sbit DUAN=P2^6; 13 14 uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x76,0x79,0x38,0x3f}; 15 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示 H E L O 16 uchar flag=0,flag1=0; 17 uchar t0=0,t1=0; 18 uint number=432; 19 uchar bai=0,shi=0,ge=0; 20 void main() 21 { 22 init(); 23 bai=number/100; 24 shi=number/10%10; 25 ge=number%10; 26 while(1) 27 { 28 if(flag1!=1) 29 { 30 display(7,6,5,bai,shi,ge); 31 } 32 else 33 { 34 display(17,18,19,19,20,16); 35 } 36 } 37 } 38 39 void delay(int n) 40 { 41 while(n--) 42 { 43 Delay1ms(); 44 } 45 } 46 void Delay1ms() //@12.000MHz 47 { 48 unsigned char i, j; 49 50 i = 2; 51 j = 239; 52 do 53 { 54 while (--j); 55 } while (--i); 56 } 57 void init() 58 { 59 P1=0xfe; 60 TMOD=0x11;//两个定时器都设置为方式1 61 TH0=(65536-50000)/256; 62 TL0=(65536-50000)%256; 63 TH1=(65536-50000)/256; 64 TL1=(65536-50000)%256; 65 EA=1; 66 ET0=1; 67 TR0=1; 68 ET1=1; 69 TR1=1; 70 } 71 void timer1() interrupt 3 72 { 73 TH1=(65536-50000)/256; 74 TL1=(65536-50000)%256; 75 t1++; 76 if(t1==2) 77 { 78 t1=0; 79 number--; 80 bai=number/100; 81 shi=number/10%10; 82 ge=number%10; 83 if(number==398) 84 { 85 //定时器0到这个位置还在运行,且TH0和TL0不知道是多少,所以要重新赋值 86 TR0=0; 87 88 TH0=(65536-50000)/256; 89 TL0=(65536-50000)%256; 90 TR0=1; 91 flag=1; 92 t0=0; 93 P1=0xff; 94 TR1=0; 95 } 96 } 97 } 98 void timer0() interrupt 1 99 { 100 TH0=(65536-50000)/256; 101 TL0=(65536-50000)%256; 102 t0++; 103 if(flag!=1) 104 { 105 if(t0==10) 106 { 107 t0=0; 108 P1=_crol_(P1,1); 109 } 110 } 111 else 112 { 113 if(t0%4==0) 114 { 115 P1=~P1; 116 if(t0==60) 117 { 118 TR0=0; 119 P1=0xff; 120 flag1=1; 121 } 122 } 123 } 124 } 125 void display(uchar a,uchar b,uchar c,uchar bai,uchar shi,uchar ge) 126 { 127 DUAN=1; 128 P0=Table[a]; 129 DUAN=0; 130 131 P0=0xff; 132 WEI=1; 133 P0=0xfe; 134 WEI=0; 135 delay(1); 136 137 DUAN=1; 138 P0=Table[b]; 139 DUAN=0; 140 141 P0=0xff; 142 WEI=1; 143 P0=0xfd; 144 WEI=0; 145 delay(1); 146 147 DUAN=1; 148 P0=Table[c]; 149 DUAN=0; 150 151 P0=0xff; 152 WEI=1; 153 P0=0xfb; 154 WEI=0; 155 delay(1); 156 157 DUAN=1; 158 P0=Table[bai]; 159 DUAN=0; 160 161 P0=0xff; 162 WEI=1; 163 P0=0xf7; 164 WEI=0; 165 delay(1); 166 167 DUAN=1; 168 P0=Table[shi]; 169 DUAN=0; 170 171 P0=0xff; 172 WEI=1; 173 P0=0xef; 174 WEI=0; 175 delay(1); 176 177 DUAN=1; 178 P0=Table[ge]; 179 DUAN=0; 180 181 P0=0xff; 182 WEI=1; 183 P0=0xdf; 184 WEI=0; 185 delay(1); 186 }
中断函数不能太长,我们每50ms进入一次中断,如果中断函数长达50ms,那么当下一次中断进入函数时,上一次中断没退出,就会把下一次的丢失,程序就会出错。如何看这个时间呢,一个机器周期1us,指令有单周期指令和双周期指令,一般指令都是单周期指令,一个单周期指令1us,双周期2us,如果函数有1000条指令也才1ms,所以没问题,只要不加延时函数一般没事。
键盘