蓝桥杯单片机练习_第九届彩灯控制器
一、题目要求
二、程序源码
1 #include "stc15.h" 2 #include "iic.h" 3 #include <stdio.h> 4 5 #define uchar unsigned char 6 #define uint unsigned int 7 8 #define KEYCOM P3 //按键IO 9 #define KEY_S7 0x01 10 #define KEY_S6 0x02 11 #define KEY_S5 0x04 12 #define KEY_S4 0x08 13 #define PWM_MAX 19 //pwm周期 <20 14 15 uchar code smg_dis[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40}; 16 uchar code LED_Max[]= {7,7,3,3}; //模式轮转时 数组最大下标 17 uchar code LED_MODE1[]= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 18 uchar code LED_MODE2[]= {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; 19 uchar code LED_MODE3[]= {0x81,0x42,0x24,0x18}; 20 uchar code LED_MODE4[]= {0x18,0x24,0x42,0x81}; 21 uchar code PWM_Val[]= {0,5,10,15,20}; //亮度调节PWM值 22 23 uchar Smg_Buf[8]= {10,10,10,10,10,10,10,10}; 24 uchar Led_Time[4]= {4,4,4,4}; //轮转时间 25 26 bit LED_Switch=0;//led轮转开关 27 bit KEY_Flag=0; 28 bit ADC_Flag=0; 29 bit SET_Flag=0; 30 bit Blink_Flag=0;//0.8s闪烁 31 32 uchar Trg, Cont; //键值 33 uchar Rank=1;//光照等级 34 35 void Delay2ms();//写入延时 36 void UartInit(void); 37 void Timer0Init(void) ; 38 void KeyRead (); 39 void KEY_Dispose (void);//按键处理 40 void Set_Show (uchar mode); 41 void Write_AT24 (uchar add,uchar dat); 42 uchar Read_AT24 (uchar add); 43 uchar Read_ADC (uchar add);//读取adc 44 uchar KEY_Resize (uchar sum,uchar Max,uchar Min);//按键调整数值 45 46 void main (void) 47 { 48 uchar ADC_Val; 49 P0=0x00;P2=0xa0;P2=0x00; 50 P0=0xff,P2=0x80,P2=0x00; 51 UartInit(); 52 Timer0Init(); 53 Led_Time[0]=Read_AT24(0x01); 54 Led_Time[1]=Read_AT24(0x02); 55 Led_Time[2]=Read_AT24(0x03); 56 Led_Time[3]=Read_AT24(0x04); 57 58 if( Led_Time[0]>=4 && Led_Time[1]>=4 && Led_Time[2]>=4 && Led_Time[3]>=4 && 59 Led_Time[0]<=12 && Led_Time[1]<=12 && Led_Time[2]<=12 && Led_Time[3]<=12 60 );//判断读取到的间隔是否在规定范围 61 else //不在范围重新赋值 62 { 63 Led_Time[0]=4; 64 Led_Time[1]=4; 65 Led_Time[2]=4; 66 Led_Time[3]=4; 67 } 68 while(1) 69 { 70 if(KEY_Flag) 71 { 72 KEY_Flag=0; 73 KEY_Dispose();//处理按键事件 74 if(!SET_Flag && (Trg & KEY_S4 || Cont & KEY_S4))//普通状态显示亮度 75 { 76 Smg_Buf[6]=11; 77 Smg_Buf[7]=Rank; 78 } 79 else if (!SET_Flag) 80 { 81 Smg_Buf[6]=10; 82 Smg_Buf[7]=10; 83 } 84 } 85 if(ADC_Flag)//亮度判断 86 { 87 ADC_Flag=0; 88 ADC_Val=Read_ADC(0x03); 89 if(ADC_Val<=69) 90 Rank=1; 91 else if (ADC_Val>69&&ADC_Val<=131) 92 Rank=2; 93 else if (ADC_Val>131&&ADC_Val<=193) 94 Rank=3; 95 else if (ADC_Val>193&&ADC_Val<=255) 96 Rank=4; 97 } 98 } 99 } 100 101 void Timer0Init(void) //1ms@11.0592MHz 102 { 103 AUXR |= 0x80; 104 TMOD &= 0xF0; 105 TL0 = 0xCD; 106 TH0 = 0xD4; 107 TF0 = 0; 108 TR0 = 1; 109 ET0 = 1; 110 EA = 1; 111 } 112 113 void TIME0() interrupt 1 114 { 115 static uint LedCount =0; 116 static uchar KeyCount =0; 117 static uchar SmgCount =0; 118 static uchar SmgLen=0; 119 static uchar AdcCount=0; 120 static uint BlinkCount=0; 121 static uchar i =0; 122 static uchar PWM; 123 static uchar Run_Mode =1; 124 125 if(++KeyCount>10) 126 { 127 KeyCount=0; 128 KEY_Flag=1; 129 } 130 131 if(++AdcCount>100) 132 { 133 AdcCount=0; 134 ADC_Flag=1; 135 } 136 137 if(SET_Flag)//设置下闪烁所选位 138 { 139 if( ++BlinkCount>800) 140 { 141 BlinkCount=0; 142 Blink_Flag=~Blink_Flag;//不可手动清0 143 } 144 } 145 if(++SmgCount>1) 146 { 147 SmgCount=0; 148 P0=~smg_dis[Smg_Buf[SmgLen]];P2=0xe0;P2=0x00; 149 P0=1<<SmgLen;P2=0xc0;P2=0x00; 150 if(++SmgLen>7)SmgLen=0; 151 } 152 /*****************/ 153 PWM++; 154 if(PWM <= PWM_Val[Rank]) 155 { 156 switch(Run_Mode)//模式 157 { 158 case 1 : 159 P0=~LED_MODE1[i]; 160 break; 161 case 2 : 162 P0=~LED_MODE2[i]; 163 break; 164 case 3 : 165 P0=~LED_MODE3[i]; 166 break; 167 case 4 : 168 P0=~LED_MODE4[i]; 169 break; 170 } 171 P2=0x80;P2=0x00; 172 } 173 else if(PWM < PWM_MAX&&PWM>PWM_Val[Rank])//pwm周期小于20ms 视觉残留 174 { 175 P0=~0x00;P2=0x80;P2=0x00; 176 } 177 else 178 { 179 PWM=0; 180 } 181 /*****************/ 182 if(!LED_Switch)//暂停时 不影响亮度 183 { 184 ++LedCount; 185 if(LedCount > Led_Time[Run_Mode-1]*100) 186 { 187 LedCount=0; 188 ++i; 189 if( i > LED_Max[Run_Mode-1]) 190 { 191 i=0; 192 Run_Mode++;//模式切换 193 if(Run_Mode==5)Run_Mode=1; 194 } 195 } 196 } 197 } 198 199 void KeyRead (void) 200 { 201 uchar ReadData = KEYCOM ^ 0xff; 202 Trg = ReadData & (ReadData ^ Cont); 203 Cont = ReadData; 204 } 205 206 void KEY_Dispose (void) 207 { 208 static uchar SET_MODE=0,mode1=0; 209 KeyRead(); 210 if( Trg & KEY_S7 ) 211 { 212 LED_Switch=~LED_Switch; 213 } 214 if( Trg & KEY_S6 ) 215 { 216 if(!SET_Flag) 217 { 218 SET_MODE=0; 219 SET_Flag=1; 220 mode1=0; 221 } 222 else 223 SET_MODE++; 224 if(SET_MODE>=2)//退出设置 清空显示缓存 便于亮度显示 向EEPROM写入间隔 225 { 226 SET_MODE=0; 227 SET_Flag=0; 228 Smg_Buf[0]=10; 229 Smg_Buf[1]=10; 230 Smg_Buf[2]=10; 231 Smg_Buf[3]=10; 232 Smg_Buf[4]=10; 233 Smg_Buf[5]=10; 234 Smg_Buf[6]=10; 235 Smg_Buf[7]=10; 236 Write_AT24(0x01,Led_Time[0]);//写入间隔 237 Delay2ms();//必须延时 238 Write_AT24(0x02,Led_Time[1]); 239 Delay2ms(); 240 Write_AT24(0x03,Led_Time[2]); 241 Delay2ms(); 242 Write_AT24(0x04,Led_Time[3]); 243 Delay2ms(); 244 } 245 } 246 if(SET_Flag)//设置模式 247 { 248 if(SET_MODE==0) 249 { 250 mode1=KEY_Resize(mode1,3,0); 251 Set_Show(mode1); 252 if(Blink_Flag)//闪烁模式位 253 { 254 Smg_Buf[1]=10; 255 } 256 } 257 else 258 { 259 Led_Time[mode1]=KEY_Resize(Led_Time[mode1],12,4); 260 Set_Show(mode1); 261 if(Blink_Flag)//闪烁轮转间隔 262 { 263 Smg_Buf[4]=10; 264 Smg_Buf[5]=10; 265 Smg_Buf[6]=10; 266 Smg_Buf[7]=10; 267 } 268 } 269 } 270 } 271 272 uchar KEY_Resize (uchar sum,uchar Max,uchar Min) 273 { 274 char Temp;//无字符型uchar <0时会超过取值范围 275 Temp=sum; 276 if(Trg & KEY_S5) 277 { 278 if( ++Temp > Max ) Temp=Max; 279 } 280 if(Trg & KEY_S4) 281 { 282 if( --Temp < Min ) Temp=Min; 283 } 284 return Temp; 285 } 286 287 void UartInit(void) //9600bps@11.0592MHz 288 { 289 SCON = 0x50; 290 AUXR |= 0x01; 291 AUXR |= 0x04; 292 T2L = 0xE0; 293 T2H = 0xFE; 294 AUXR |= 0x10; 295 TI=1; 296 } 297 298 void Set_Show (uchar mode) 299 { 300 Smg_Buf[0]=11; 301 Smg_Buf[1]=mode+1; 302 Smg_Buf[2]=11; 303 Smg_Buf[3]=10; 304 if(Led_Time[mode]<10)//当轮转时间小于1000时 即<10 不显示千位 305 Smg_Buf[4]=10; 306 else 307 Smg_Buf[4]=Led_Time[mode]/10;//1000位 308 Smg_Buf[5]=Led_Time[mode]%10;//100位 309 Smg_Buf[6]=0; 310 Smg_Buf[7]=0;//个位与十位一直为0 311 } 312 313 uchar Read_ADC (uchar add)//读取adc 314 { 315 uchar Temp; 316 IIC_Start(); 317 IIC_SendByte(0x90); 318 IIC_WaitAck(); 319 IIC_SendByte(add); 320 IIC_WaitAck(); 321 IIC_Start(); 322 IIC_SendByte(0x91); 323 IIC_WaitAck(); 324 Temp=IIC_RecByte(); 325 IIC_WaitAck(); 326 IIC_Stop(); 327 return Temp; 328 } 329 330 void Write_AT24 (uchar add,uchar dat) 331 { 332 IIC_Start(); 333 IIC_SendByte(0xa0); 334 IIC_WaitAck(); 335 IIC_SendByte(add); 336 IIC_WaitAck(); 337 IIC_SendByte(dat); 338 IIC_WaitAck(); 339 IIC_Stop(); 340 } 341 342 uchar Read_AT24 (uchar add) 343 { 344 uchar Temp; 345 IIC_Start(); 346 IIC_SendByte(0xa0); 347 IIC_WaitAck(); 348 IIC_SendByte(add); 349 IIC_WaitAck(); 350 IIC_Start(); 351 IIC_SendByte(0xa1); 352 IIC_WaitAck(); 353 Temp=IIC_RecByte(); 354 IIC_WaitAck(); 355 IIC_Stop(); 356 return Temp; 357 } 358 359 void Delay2ms() //@11.0592MHz 360 { 361 unsigned char i, j; 362 363 _nop_(); 364 _nop_(); 365 i = 22; 366 j = 128; 367 do 368 { 369 while (--j); 370 } while (--i); 371 }