藍橋杯單片機練習_第九屆彩燈控制器

1、題目要求數組

2、程序源碼緩存

 

 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 }
相關文章
相關標籤/搜索