其他分享
首页 > 其他分享> > 蓝桥杯单片机练习_第九届彩灯控制器

蓝桥杯单片机练习_第九届彩灯控制器

作者:互联网

一、题目要求

二、程序源码

  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 uint 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 Bilik_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 ()
 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     if( Led_Time[0]>=4 && Led_Time[1]>=4 && Led_Time[2]>=4 && Led_Time[3]>=4 );//判断读取到的间隔是否小于预设值 小于则为失败
 58     else
 59     {
 60         Led_Time[0]=4;
 61         Led_Time[1]=4;
 62         Led_Time[2]=4;
 63         Led_Time[3]=4;        
 64     }
 65     while(1)
 66     {
 67         if(KEY_Flag)
 68         {
 69             KEY_Flag=0;
 70             KEY_Dispose();//处理按键事件
 71             if(!SET_Flag && (Trg & KEY_S4 || Cont & KEY_S4))//普通状态显示亮度
 72             {
 73                 Smg_Buf[6]=11;
 74                 Smg_Buf[7]=Rank;
 75             }
 76             else if (!SET_Flag)
 77             {
 78                 Smg_Buf[6]=10;
 79                 Smg_Buf[7]=10;
 80             }    
 81         }
 82         if(ADC_Flag)//亮度判断
 83         {
 84             ADC_Flag=0;
 85             ADC_Val=Read_ADC(0x03);
 86             if(ADC_Val<=69)
 87                 Rank=1;
 88                 else if (ADC_Val>69&&ADC_Val<=131)
 89                     Rank=2;
 90                     else if (ADC_Val>131&&ADC_Val<=193)
 91                         Rank=3;        
 92                             else if (ADC_Val>193&&ADC_Val<=255)
 93                                 Rank=4;
 94         }
 95     }
 96 }
 97 
 98 void Timer0Init(void)        //1ms@11.0592MHz
 99 {
100     AUXR |= 0x80;        
101     TMOD &= 0xF0;        
102     TL0 = 0xCD;    
103     TH0 = 0xD4;        
104     TF0 = 0;        
105     TR0 = 1;        
106     ET0 = 1;
107     EA  = 1;
108 }
109 
110 void TIME0() interrupt 1
111 {
112     static uint LedCount =0;
113     static uchar KeyCount =0;
114     static uchar SmgCount =0;
115     static uchar SmgLen=0;
116     static uchar AdcCount=0;
117     static uint BilikCount=0;
118     static uchar i =0;
119     static uchar PWM;
120     static uchar  Run_Mode =1;
121     
122     if(++KeyCount>10)
123     {
124         KeyCount=0;
125         KEY_Flag=1;
126     }
127     
128     if(++AdcCount>100)
129     {
130         AdcCount=0;
131         ADC_Flag=1;
132     }
133 
134     if(SET_Flag)//设置下闪烁所选位
135     {        
136         if( ++BilikCount>800)
137         {
138             BilikCount=0;
139           Bilik_Flag=~Bilik_Flag;//不可手动清0
140         }
141     }
142         if(++SmgCount>1)
143         {
144             SmgCount=0;
145             P0=~smg_dis[Smg_Buf[SmgLen]];P2=0xe0;P2=0x00;
146             P0=1<<SmgLen;P2=0xc0;P2=0x00;
147             if(++SmgLen>7)SmgLen=0;
148         }
149         /*****************/
150             PWM++;
151             if(PWM <= PWM_Val[Rank])
152             {
153                 switch(Run_Mode)//模式
154                 {
155                     case 1 :P0=~LED_MODE1[i]; break;
156                     case 2 :P0=~LED_MODE2[i]; break;
157                     case 3 :P0=~LED_MODE3[i]; break;
158                     case 4 :P0=~LED_MODE4[i]; break;
159                 }
160                 P2=0x80;P2=0x00;
161             }
162             else if(PWM < PWM_MAX&&PWM>PWM_Val[Rank])//pwm周期小于20ms 视觉残留
163             {
164                 P0=~0x00;
165                 P2=0x80;P2=0x00;
166             }
167             else
168             {
169                 PWM=0;
170             }
171         /*****************/
172     if(!LED_Switch)//暂停时 不影响亮度
173     {
174         ++LedCount;
175         if(LedCount > Led_Time[Run_Mode-1]*100)
176         {
177             LedCount=0;
178             ++i;
179             if( i > LED_Max[Run_Mode-1])
180             {                
181                 i=0;
182                 Run_Mode++;//模式切换
183                 if(Run_Mode==5)Run_Mode=1;
184             }    
185         }
186     }
187 }
188 
189 void KeyRead (void)
190 {
191     uchar ReadData = KEYCOM ^ 0xff;
192     Trg = ReadData & (ReadData ^ Cont);
193     Cont = ReadData;
194 }
195 
196 void KEY_Dispose (void)
197 {
198     static uchar SET_MODE=0,mode1=0;
199     KeyRead();
200     if( Trg & KEY_S7 )
201     {
202         LED_Switch=~LED_Switch;
203     }
204     if( Trg & KEY_S6 )
205     {
206         if(!SET_Flag)
207         {
208             SET_MODE=0;
209             SET_Flag=1;
210             mode1=0;
211         }
212             else
213                 SET_MODE++;
214                 if(SET_MODE>=2)//退出设置 清空显示缓存 便于亮度显示 向EEPROM写入间隔
215                 {
216                     SET_MODE=0;
217                     SET_Flag=0;
218                     Smg_Buf[0]=10;
219                     Smg_Buf[1]=10;
220                     Smg_Buf[2]=10;
221                     Smg_Buf[3]=10;
222                     Smg_Buf[4]=10;
223                     Smg_Buf[5]=10;
224                     Smg_Buf[6]=10;
225                     Smg_Buf[7]=10;
226                     Write_AT24(0x01,Led_Time[0]);//写入间隔
227                     Delay2ms();//必须延时
228                     Write_AT24(0x02,Led_Time[1]);
229                     Delay2ms();
230                     Write_AT24(0x03,Led_Time[2]);
231                     Delay2ms();
232                     Write_AT24(0x04,Led_Time[3]);
233                     Delay2ms();
234                 }
235     }
236     if(SET_Flag)//设置模式
237     {
238         if(SET_MODE==0)
239         {
240             mode1=KEY_Resize(mode1,3,0);
241             Set_Show(mode1);
242             if(Bilik_Flag)//闪烁模式位
243             {
244                 Smg_Buf[1]=10;
245             }
246         }
247         else
248         {
249             Led_Time[mode1]=KEY_Resize(Led_Time[mode1],12,4);
250             Set_Show(mode1);
251             if(Bilik_Flag)//闪烁轮转间隔
252             {
253                 Smg_Buf[4]=10;
254                 Smg_Buf[5]=10;
255                 Smg_Buf[6]=10;
256                 Smg_Buf[7]=10;
257             }
258         }
259     }
260 }
261 
262 uchar KEY_Resize (uchar sum,uchar Max,uchar Min)
263 {
264     char Temp;//无字符型uchar <0时会超过取值范围
265     Temp=sum;
266     if(Trg & KEY_S5)
267     {
268         if( ++Temp > Max ) Temp=Max;
269     }
270     if(Trg & KEY_S4)
271     {
272         if( --Temp < Min ) Temp=Min;
273     }
274     return Temp;
275 }
276 
277 void UartInit(void)        //9600bps@11.0592MHz 
278 {
279     SCON = 0x50;        
280     AUXR |= 0x01;        
281     AUXR |= 0x04;        
282     T2L = 0xE0;        
283     T2H = 0xFE;        
284     AUXR |= 0x10;    
285     TI=1;
286 }
287 
288 void Set_Show (uchar mode)
289 {
290     Smg_Buf[0]=11;
291     Smg_Buf[1]=mode+1;
292     Smg_Buf[2]=11;
293     Smg_Buf[3]=10;
294     if(Led_Time[mode]<10)//当轮转时间小于1000时 即<10 不显示千位
295         Smg_Buf[4]=10;
296         else
297             Smg_Buf[4]=Led_Time[mode]/10;//1000位
298     Smg_Buf[5]=Led_Time[mode]%10;//100位
299     Smg_Buf[6]=0;
300     Smg_Buf[7]=0;//个位与十位一直为0
301 }
302 
303 uchar Read_ADC (uchar add)//读取adc
304 {
305     uchar Temp;
306     IIC_Start();
307     IIC_SendByte(0x90);
308     IIC_WaitAck();
309     IIC_SendByte(add);
310     IIC_WaitAck();
311     IIC_Start();
312     IIC_SendByte(0x91);
313     IIC_WaitAck();
314     Temp=IIC_RecByte();
315     IIC_WaitAck();
316     IIC_Stop();
317     return Temp;
318 }
319 
320 void Write_AT24 (uchar add,uchar dat)
321 {
322     IIC_Start();
323     IIC_SendByte(0xa0);
324     IIC_WaitAck();
325     IIC_SendByte(add);
326     IIC_WaitAck();
327     IIC_SendByte(dat);
328     IIC_WaitAck();
329     IIC_Stop();
330 }
331 
332 uchar Read_AT24 (uchar add)
333 {
334     uchar Temp;
335     IIC_Start();
336     IIC_SendByte(0xa0);
337     IIC_WaitAck();
338     IIC_SendByte(add);
339     IIC_WaitAck();
340     IIC_Start();
341     IIC_SendByte(0xa1);
342     IIC_WaitAck();
343     Temp=IIC_RecByte();
344     IIC_WaitAck();
345     IIC_Stop();    
346     return Temp;
347 }
348 
349 void Delay2ms()        //@11.0592MHz
350 {
351     unsigned char i, j;
352 
353     _nop_();
354     _nop_();
355     i = 22;
356     j = 128;
357     do
358     {
359         while (--j);
360     } while (--i);
361 }

 

标签:10,Led,KEY,蓝桥,单片机,Flag,彩灯,Smg,Buf
来源: https://www.cnblogs.com/nsss/p/10536841.html