1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
| /\*-------------------------------
--------------------------------\*/
#include <STC89C5xRC.H>
unsigned char num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数字0~9 unsigned char ctr[]={0xfa,0xf5}; //0xfa(P3\_0和P3\_2为0,即高位有效)0xf5(P3\_1和P3\_3为0,即低位有效) unsigned char disEW[2]; //记录东西向高低位数值 unsigned char disSN[2]; //记录南北向高低位数值
unsigned char v; unsigned char cnt_ctr; unsigned int scdEW,scdSN; unsigned int cntSN,cntEW; unsigned char cntP3_4,cntP3_5,cntP3_6; unsigned int cnt_num,cnt_key,cnt_flash,keyMemory; int greenEW = 20,yellowEW = 3,greenSN = 25,yellowSN = 3;
//正常显示秒数 void display(void) { cnt_num++; if(cnt_ctr == 10) { cnt_ctr = 0; P3 = 0xff; P3 = ctr[v]; P2 = num[disEW[v]]; //显示东西方向秒数 P0 = num[disSN[v]]; //显示南北方向秒数 if(v++ == 1) { v = 0; } } }
//闪烁显示秒数 void dspFlash(void) { cnt_flash++; if(cnt_flash < 660) { P3 = 0xff; //数码管灭 } else { if(cnt_flash == 1333) //数码管亮 1333=4000/3 即1秒闪3次 { cnt_flash = 0; } if(cnt_ctr == 25) { cnt_ctr = 0; P3 = 0xff; P3 = ctr[v]; switch(cntP3_4) { case 1: P30 = 1; P31 = 1; P2 = num[disEW[v]]; break; case 2: P30 = 1; P31 = 1; P2 = num[disEW[v]]; break; case 3: P32 = 1; P33 = 1; P0 = num[disSN[v]];; break; case 4: P32 = 1; P33 = 1; P0 = num[disSN[v]]; break; } if(v++ == 1) { v = 0; } } }
}
//T0中断 void t0(void) interrupt 1 { cnt_ctr++; if(cntP3_4 == 0) { display(); //正常显示秒数 } if(cntP3_4 != 0) { dspFlash(); //闪烁显示秒数 } if(cnt_num == 4000) { cnt_num = 0; if(scdEW-- == 0) { cntEW++; //东西向秒数减至0,标志位加1 } if(scdSN-- == 0) { cntSN++; //南北向秒数减至0,标志位加1 } } switch(cntEW) { case 1: scdEW = yellowEW; //东西向黄灯亮,显示黄灯秒数 P13 = 1; P14 = 0; P15 = 1; cntEW++; //避免程序到此阻塞,故将其至为2 break; case 3: //避免cntEW为2 scdEW = greenSN + yellowSN + 1; //东西向红灯亮,显示红灯秒数 P13 = 1; P14 = 1; P15 = 0; cntEW++; //避免程序到此阻塞,故将其至为4 break; case 5: //避免cntEW为4 scdEW = greenEW; //东西向绿灯亮,显示绿灯秒数 P13 = 0; P14 = 1; P15 = 1; cntEW = 0; break; } switch(cntSN) { case 1: scdSN = greenSN; //南北向绿灯亮,显示绿灯秒数 P10 = 0; P11 = 1; P12 = 1; cntSN++; //避免程序到此阻塞,故将其至为2 break; case 3: //避免cntSN为2 scdSN = yellowSN; //南北向黄灯亮,显示黄灯秒数 P10 = 1; P11 = 0; P12 = 1; cntSN++; //避免程序到此阻塞,故将其至为4 break; case 5: //避免cntSN为4 scdSN = greenEW + yellowEW + 1; //南北向红灯亮,显示红灯秒数 P10 = 1; P11 = 1; P12 = 0; cntSN = 0; break; }
disEW[0] = scdEW/10; disEW[1] = scdEW%10; disSN[0] = scdSN/10; disSN[1] = scdSN%10; }
//主函数 void main(void) { TMOD = 0x02; //设置定时器0为工作方式2 TH0 = 0x06; TL0 = 0x06; //初始化8位定时器 (256 - 6)\*40000 = 1s EA = 1; //总中断允许 ET0 = 1; //T0中断允许 TR0 = 1; //打开T0中断
P1 = 0xf3; //东西向绿灯,南北向红灯 P34 = 1; scdEW = greenEW; //设置东西向显示秒数 scdSN = greenEW + yellowEW + 1; //设置南北向显示秒数 while(1) { } }
|