蓝桥杯13届第2场(51单片机)

简介: 蓝桥杯13届第2场(51单片机)

题目是超声波测量可能大家比较陌生,这也是省赛第一次出,如果知道这个模块的话还是比较简单的(跟其他模块也差不多)然后下面 就贴代码了 。想要源码的工程文件可以去博主的资源中下载(免费)点点关注就行。

一.先看主函数

1. #include "config.h"
2. #include "iic.h"
3. void main()
4. {  
5.   Init_System();//初始化
6.  while(1){
7.  if(flag_v) //电压采集标志位
8.  { 
9. 
10.      flag_v=0;
11.      sum_v= read_adc()*1.96;  //电压采集
12.     if(sum_v>(param_min*10)&&sum_v<(param_max*10)) //电压在参数之间
13.          flag_wave=1; //启用超声波功能
14.     else flag_wave=0;
15. 
16. 
17.     if(flag_wave) 
18.     { 
19. 
20.       wave= wave_recv();  //测距
21.       if(wave<=20)dac_out(1*51); 
22.       else if(wave>=20&&wave<=80)dac_out((wave*0.067-0.034)*51);
23.       else dac_out(255);
24.     }
25.     else dac_out(0);
26. 
27. 
28.   }
29. 
30.   scan_kbd();//扫描键盘
31.   key_real(); //按键功能
32.   SMG_show();  //数码管赋值
33. 
34. 
35. }
36. }

二.配置文件

1. #include "config.h"
2. #include "intrins.h"
3. unsigned char key_num=16;
4. unsigned char segbuff[8]={0};
5. unsigned int count_v=0;//电压采集计数
6. bit flag_v=0 ;//电压可以采集标志
7. unsigned int sum_v=0; //采集的电压数据
8. unsigned int param_max=30; //参数电压上限
9. unsigned int param_min=15;  //参数电压下限
10. unsigned int min_old=15;    //设置的参数下限
11. unsigned int max_old=30;    //设置的参数上限
12. unsigned int wave=10;     //超声波距离
13. unsigned char mod1=0; //界面切换
14. unsigned char mod2=0;  //模式切换
15. bit flag_wave=0;//超声波可以采集标志
16. unsigned int count_w=0;
17. unsigned char segtab[]={0xc0, //0
18. 0xf9, //1
19. 0xa4, //2
20. 0xb0, //3
21. 0x99, //4
22. 0x92, //5
23. 0x82, //6
24. 0xf8, //7
25. 0x80, //8
26. 0x90, //9
27. 0xff, //Ϩİ -10
28. 0xc1,  //U     -11
29. 0xc0&0x7f,0xf9&0x7f,0xa4&0x7f,0xb0&0x7f,0x99&0x7f,0x92&0x7f,
30. 0x82&0x7f,0xf8&0x7f,0x80&0x7f,0x90&0x7f,0x8c,0xc7,0x88
31. };
32. 
33. 
34. void Timer0Init(void)   //12??@12.000MHz
35. {
36.   //12T  12ms
37.   AUXR &= 0x7F;   
38.   TMOD &= 0xF0;   
39.   TL0 = 0xF4;   
40.   TH0 = 0xFF;
41.   TF0 = 0;    
42.   TR0 = 1;    
43. }
44. 
45. unsigned char wave_recv()
46. {
47.   unsigned char ucdist,num=10;
48.   TX=0;
49.   TL0=0xf4;
50.   TH0=0xff;
51.   TR0=1;
52.   //发送40Khz频率
53.   while(num--)
54.   {
55.     while(!TF0);
56.     TX^=1;
57.     TF0=0;
58.   }
59.   TR0=0;
60.   TL0=0;
61.   TH0=0;
62.   TR0=1;
63.   while(RX&&!TF0);
64.   TR0=0;
65.   if(TF0) //定时器溢出
66.   {
67.     TF0=0;
68.     ucdist=255;
69.   }
70.   else  //测距成功
71.     ucdist=((TH0<<8)+TL0)*0.017;
72.   return ucdist;
73. }
74. 
75. void time0 (void)   //1??@12.000MHz
76. { 
77. 
78.   //1T 1ms
79.   AUXR &= 0xBF;   
80.   TMOD &= 0x0F; 
81.   TL1 = 0x18; 
82.   TH1 = 0xFC;   
83.   TF1 = 0;    
84.   TR1 = 1;    
85.   EA = 1;
86.   ET1= 1;
87. }
88. 
89. 
90. void Timer0() interrupt 3
91. {
92. 
93.   TL1 = 0x18;   
94.   TH1 = 0xFC; 
95. segs();  //刷新数码管
96.   count_v++;  //采集电压计数
97.   count_w++;
98.   if(count_v==300) 0.3s采集一次
99.   {
100.    count_v=0;
101.     flag_v=1;  //可以采集
102.  }
103.  led_work();  //led灯
104. 
105. 
106. }
107. void segs()
108. {
109. 
110.  static unsigned char wei=0;
111.  P2=P2&0x1f|0xe0;
112.  P0=0xff;
113. 
114.  P2=P2&0x1f|0xc0;
115.  P0=1<<wei;
116.  P2=P2&0x1f|0xe0;
117.  P0=segtab[segbuff[wei]];
118.  if(++wei==8)wei=0;
119. 
120. }
121. 
122. void scan_kbd()  
123. {
124. static unsigned char state=0;
125.   unsigned char key_press;
126.  switch(state)
127.  {
128.    case state_0:
129.      kbd_io=0x0f;
130.    key_press=kbd_io;
131.    if(key_press!=kbd_maskrow)
132.      state=state_1;
133.    break;
134. 
135.    case state_1:
136.      key_press=kbd_io;
137.    if(key_press!=kbd_maskrow)
138.    {
139.      if((kbd_io&0x08)==0)key_num=0;  //S4
140.      if((kbd_io&0x04)==0)key_num=1;  //S5
141.      if((kbd_io&0x02)==0)key_num=2;  //S6
142.      if((kbd_io&0x01)==0)key_num=3;   //S7
143.     state=state_2;
144. 
145. 
146.    }
147.    else state=state_0;
148.    break;
149. 
150. 
151.    case state_2:
152. 
153.    kbd_io=0x0f;
154.    key_press=kbd_io;
155.    if(key_press==kbd_maskrow)state=state_0;
156. 
157.    break;
158. 
159.    default :break;
160. 
161.  }
162. 
163. 
164. }
165. void key_real()
166. {
167. switch(key_num)
168.  {
169. 
170.   case 0:
171.    mod1++;  //界面切换
172.    if(mod1==3)mod1=0;
173.   if(mod1==0)
174.   {     param_min=min_old;
175.         param_max=max_old;
176.   }
177.   if(mod1==1)
178.   {   
179.     min_old=param_min;
180.     max_old=param_max;
181. 
182.   }
183. 
184.   break;
185. 
186.   case 1:   //模式切换
187.     mod2++;
188.    if(mod2==2)mod2=0;
189.    break;
190. 
191.   case 2:
192.       if(mod1==2)
193.       {
194.       if(mod2)
195.       { 
196.          min_old+=5;
197.         if(min_old>50)min_old=0;
198.       }
199.        else
200.        {   
201.            max_old+=5;
202.          if(max_old>50)max_old=0;
203.        }
204.       }
205.       break;
206. 
207. 
208.   case 3:
209.      if(mod1==2)
210.       {
211.       if(mod2)
212.       {  
213.         if(min_old==0)min_old=50;
214.          else min_old-=5;
215. 
216. 
217.       }
218.        else
219.        {   
220.           if(max_old==0)max_old=50;
221.          else  max_old-=5;
222. 
223. 
224.        }
225.       }
226.       break;
227. 
228.   default :break;
229. 
230. 
231. 
232. 
233.  }
234.  key_num=16;
235. 
236. }
237. void SMG_show()
238. {
239. 
240. switch(mod1)
241.  { 
242.    //显示电压界面
243.    case 0: segbuff[0]=11;
244.            segbuff[1]=10;
245.            segbuff[2]=10;
246.            segbuff[3]=10;
247.            segbuff[4]=10;
248.            segbuff[5]=sum_v/100+12;
249.            segbuff[6]=sum_v/10%10;
250.            segbuff[7]=sum_v%10;
251.            break;
252.    //显示参数界面
253.    case 2:
254.            segbuff[0]=22;
255.            segbuff[1]=10;
256.            segbuff[2]=10;
257.            segbuff[3]=max_old/10;
258.            segbuff[4]=max_old%10;
259.            segbuff[5]=10;
260.            segbuff[6]=min_old/10;
261.            segbuff[7]=min_old%10;
262.            break;
263.    //显示超声波界面
264.    case 1:  
265.            segbuff[0]=23;
266.            segbuff[1]=10;
267.            segbuff[2]=10;
268.            segbuff[3]=10;
269.            segbuff[4]=10;
270.            if(flag_wave)
271.            {
272.            if(wave>99)
273.            segbuff[5]=wave/100;
274.            else  segbuff[5]=10;
275.            segbuff[6]=wave/10%10;
276.            segbuff[7]=wave%10;
277.            }
278.            else
279.            {
280.            segbuff[5]=24;
281.            segbuff[6]=24;
282.            segbuff[7]=24;
283.            }
284.        break;
285. 
286.  }
287. 
288. 
289. 
290. 
291. 
292. }
293. void led_work()
294. { 
295.  unsigned char old=P0;
296.  P2=P2&0x1f|0x00;
297.  P0=0xff;
298. if(mod1==0)
299.  {
300.   P2=P2&0x1f|0x80;
301.    P0=0xfe;
302.  }
303. else if(mod1==1)
304.  {
305.      P2=P2&0x1f|0x80;
306.        P0=0xfd;
307.  }
308. else if(mod1==2)
309.  {
310.     P2=P2&0x1f|0x80;
311.    P0=0xfb;
312. 
313. 
314.  }
315.  P2=P2&0x1f;
316.  P0=old;
317. 
318. }
319. 
320. //初始化
321. void Init_System()
322. {
323.   P2=P2&0x1f|0x80;
324.  P0=0xff;
325.  P2=P2&0x1f|0xa0;
326.  P0=0xaf;
327.  time0();
328. Timer0Init();
329. 
330. }
331. 
332.

三.H操作

1. #ifndef _CONFIG_H
2. #define _CONFIG_H
3. #include <STC15F2K60S2.H>
4. #define kbd_io P3
5. #define state_0 0
6. #define state_1 1
7. #define state_2 2
8. #define kbd_maskrow 0x0f
9. sbit TX=P1^0;
10. sbit RX=P1^1;
11. extern unsigned int wave;
12. extern unsigned int sum_v;
13. extern bit flag_v;
14. extern bit flag_wave;
15. extern unsigned int param_max; //֧ѹʏО
16. extern unsigned int param_min;
17. extern  bit flag_w;
18. void segs();
19. void SMG_show();
20. void scan_kbd();
21. void segs();
22. unsigned char wave_recv();
23. void time0();
24. void led_work();
25. void key_real();
26. void Init_System();
27. void Timer0Init(void);
28. #endif

其他IIC.c

1. /* #   I2C代码片段说明
2.  1.  本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
3.  2.  参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
4.    中对单片机时钟频率的要求,进行代码调试和修改。
5. */
6. #include <STC15F2K60S2.H>
7. #include <intrins.h>
8. #define DELAY_TIME 5
9. sbit SCL =P2^0;
10. sbit SDA=P2^1;
11. 
12. //
13. static void I2C_Delay(unsigned char n)
14. {
15. do
16.     {
17. nop_();   
18.     }
19. while(n--);       
20. }
21. 
22. //
23. void I2C_Start(void)
24. {
25.     SDA = 1;
26.     SCL = 1;
27.   I2C_Delay(DELAY_TIME);
28.     SDA = 0;
29.   I2C_Delay(DELAY_TIME);
30.     SCL = 0;    
31. }
32. 
33. //
34. void I2C_Stop(void)
35. {
36.     SDA = 0;
37.     SCL = 1;
38.   I2C_Delay(DELAY_TIME);
39.     SDA = 1;
40.   I2C_Delay(DELAY_TIME);
41. }
42. 
43. //
44. void I2C_SendByte(unsigned char byt)
45. {
46. unsigned char i;
47. 
48. for(i=0; i<8; i++){
49.         SCL = 0;
50.     I2C_Delay(DELAY_TIME);
51. if(byt & 0x80){
52.             SDA = 1;
53.         }
54. else{
55.             SDA = 0;
56.         }
57.     I2C_Delay(DELAY_TIME);
58.         SCL = 1;
59.         byt <<= 1;
60.     I2C_Delay(DELAY_TIME);
61.     }
62. 
63.     SCL = 0;  
64. }
65. 
66. //
67. unsigned char I2C_ReceiveByte(void)
68. {
69.   unsigned char da;
70.   unsigned char i;
71.   for(i=0;i<8;i++){   
72.     SCL = 1;
73.     I2C_Delay(DELAY_TIME);
74.     da <<= 1;
75.     if(SDA) 
76.       da |= 0x01;
77.     SCL = 0;
78.     I2C_Delay(DELAY_TIME);
79.   }
80.   return da;    
81. }
82. 
83. //
84. unsigned char I2C_WaitAck(void)
85. {
86.   unsigned char ackbit;
87. 
88.     SCL = 1;
89.   I2C_Delay(DELAY_TIME);
90.     ackbit = SDA; 
91.     SCL = 0;
92.   I2C_Delay(DELAY_TIME);
93. 
94.   return ackbit;
95. }
96. 
97. //
98. void I2C_SendAck(unsigned char ackbit)
99. {
100.     SCL = 0;
101.     SDA = ackbit; 
102.   I2C_Delay(DELAY_TIME);
103.     SCL = 1;
104.  I2C_Delay(DELAY_TIME);
105.     SCL = 0; 
106.  SDA = 1;
107.  I2C_Delay(DELAY_TIME);
108. }
109. void dac_out(unsigned int dat)
110. {
111. I2C_Start();
112.  I2C_SendByte(0x90);
113.  I2C_WaitAck();
114.  I2C_SendByte(0x40);
115.  I2C_WaitAck();
116. I2C_SendByte(dat);
117.  I2C_WaitAck();
118.  I2C_Stop();
119. 
120. }
121. unsigned int read_adc()   
122. {
123.  unsigned int  dat;
124. I2C_Start();
125.  I2C_SendByte(0x90);
126.  I2C_WaitAck();
127.  I2C_SendByte(0x03);
128.  I2C_WaitAck();
129.  I2C_Stop();
130. 
131.  I2C_Start();
132. I2C_SendByte(0x91);
133.  I2C_WaitAck();
134.  dat=I2C_ReceiveByte();
135.  I2C_SendAck(1);
136.  I2C_Stop();
137.  return dat;
138. 
139. }

IIC.H

1. #ifndef _I2C_H
2. #define _I2C_H
3. 
4. void I2C_Start(void);
5. void I2C_Stop(void);
6. void I2C_SendByte(unsigned char byt) ;
7. unsigned char I2C_ReceiveByte(void);
8. unsigned char I2C_WaitAck(void);
9. void I2C_SendAck(unsigned char ackbit);
10. void dac_out(unsigned int dat);
11. unsigned int read_adc();
12. 
13. #endif 
14. 
15. 
16. 
17. 
18. 
19. 
20.
目录
相关文章
|
5月前
蓝桥杯之单片机学习(终)——关于之前文章的错误及更正(附:第十四届蓝桥杯单片机赛题)
蓝桥杯之单片机学习(终)——关于之前文章的错误及更正(附:第十四届蓝桥杯单片机赛题)
单片机-蓝桥杯 用光敏电阻测量光照强度并显示在数码管上。
单片机-蓝桥杯 用光敏电阻测量光照强度并显示在数码管上。
247 1
蓝桥杯第11届国赛单片机组
蓝桥杯第11届国赛单片机组
122 0
13届蓝桥杯(单片机)
13届蓝桥杯(单片机)
109 0
蓝桥杯第12届第2场51单片机
蓝桥杯第12届第2场51单片机
139 0
蓝桥杯第六届省赛(单片机)--深度解析
蓝桥杯第六届省赛(单片机)--深度解析
176 0
|
芯片
蓝桥杯STC15单片机流水灯
蓝桥杯STC15单片机流水灯
268 0
|
算法 程序员
蓝桥杯单片机快速得奖方法(分享一些实用技巧)
蓝桥杯单片机快速得奖方法(分享一些实用技巧)
361 0
蓝桥杯单片机技巧之数码管小数点显示及串口中断代码生成
蓝桥杯单片机技巧之数码管小数点显示及串口中断代码生成
334 0
蓝桥杯单片机国二经验分享
蓝桥杯单片机国二经验分享
228 0
下一篇
DataWorks