一.任务
用MCU(型号不限)做一个倒车报警系统。
二.要求
1.基本要求
(1)测量距离,并用数码管显示。
(2)设置3盏LED灯表示,设置如下:
a)大于3m,点亮第1盏LED,不闪烁;
b)大于1m,小于3m,保持第一盏LED不闪烁,同时点亮第2盏LED闪烁,时间间隔为600ms;
c)小于1m,3盏LED以200ms闪烁,同时驱动蜂鸣器发声。
(3)距离小于1m,按下按钮后蜂鸣器停止,3盏LED灯闪烁3次后停止,时间间隔为1000ms。
(4) 循环(1)(2)(3),程序无跑丢;
(5) 最终成品,不能在开发板上实现。
2.发挥部分
(1)通过串口与按下按钮,把当前距离,以文本的形式传递给PC或手机;(用了Esp8266_01s模块)
(2)使用画图工具,来制作电路板。
解:
注意:代码中的esp8266_01s已经提前用串口助手配置好了wifi名字和密码,wifi应用模式为ap模式或ap+station模式都可以。ESP8266_01S的VCC接3.3V,GND与单片机共地,CH_PD端接3.3V(高电平使能),RXD接单片机的TXD,TXD接单片机的RXD。
下载链接:https://download.csdn.net/download/chenger_32123/10577310 里面包含keil工程和代码、Altium Designer软件画的原理图和PCB,可以直接做单层板。
软件:keil 4、stc-isp
1.原理图(ESP8266_01S没有在里面)
2.层次图
3.代码
/*******main.h****/
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/*******main.h****/ #ifndef MAIN_H #define MAIN_H #ifndef _uchar_ #define _uchar_ typedef unsigned char uchar; #endif #ifndef _uint_ #define _uint_ typedef unsigned int uint; #endif sbit yiwei=P2^0; sbit erwei=P2^1; sbit sanwei=P2^2; sbit siwei=P2^3; sbit green_led=P1^0; sbit yellow_led=P1^1; sbit red_led=P1^2; sbit fengmingqi=P1^3; sbit K1=P1^6; sbit K2=P1^7; code uchar duan[12] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xff}; // 0 1 2 3 4 5 6 7 8 9 点 关闭 void display(int); void delay100us(); void delay1s(void); void delay600ms(void); void delay200ms(void); void comint(); uchar read_key(); void key_pro(uchar); void timer_0(void); #endif
/**main.c**/
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311/**main.c**/ /******************************************* //晶振:12MHz 1T模式:1个时钟周期做一个机器周期 //串口波特率:2400bps@12MHz *******************************************/ #include<reg51.h> #include<intrins.h> #include"main.h" #include"hc_sr04_p.h" uchar i=0; uchar key_press; uchar key_value; bit key_re; bit en_flag; bit k1_flag; bit k2_flag; bit flag_1; int temp_distance; uchar str_1[]="AT+CIPMUX=1rn"; //ESP8266_01S启动多连接 uchar str_2[]="AT+CIPSERVER=1,8080rn"; //开启server模式,端口为8080 uchar str_3[]="AT+CIPSEND=0,10rn"; //向连接序号为0的客户,发送长度为10个字节数据 uchar str[]="X.XXX米 "; uchar *p; /********************************************************/ /*延时函数,延时1S*/ /********************************************************/ void delay1s(void) //误差 0us { unsigned char a,b,c; for(c=46;c>0;c--) for(b=152;b>0;b--) for(a=70;a>0;a--); _nop_(); //if Keil,require use intrins.h } /********************************************************/ /*延时函数,延时600mS*/ /********************************************************/ void delay600ms(void) //误差 0us { unsigned char a,b,c; for(c=55;c>0;c--) for(b=82;b>0;b--) for(a=65;a>0;a--); } /********************************************************/ /*延时函数,延时200mS*/ /********************************************************/ void delay200ms(void) //误差 0us { unsigned char a,b,c; for(c=67;c>0;c--) for(b=142;b>0;b--) for(a=9;a>0;a--); } /********************************************************/ /*延时函数*/ //100微秒 /********************************************************/ void delay100us() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } /********************************************************/ /*主函数*/ /********************************************************/ void main() { P0=0xff; P1=0xff; P2=0xbf; TMOD=0x21; //定时器1为波特率发生器,定时器0为计时器 SCON=0x50; PCON=0x00; //波特率不倍增 TH1=0xF3; //波特率为2400 TL1=0xF3; PS=1; //串口中断优先级最高 ES=1; //串口中断打开 TH0=(65536-20000)/256; TL0=(65536-20000)%256; EA=1; //开总中断 // ET1=1; //允许定时器1中断 ET0=1; //允许定时器0中断 TR0=1; //启动定时器0 TR1=1; delay600ms(); //延时 p=&str_1; SBUF=*p; delay600ms(); p=&str_2; SBUF=*p; delay200ms(); while(1) { while(temp_distance >= 3000) //距离大于等于3米 { fengmingqi=1; green_led=0; yellow_led=1; red_led=1; } while(temp_distance <3000 && temp_distance >= 1000) //距离小于3米而大于等于1米 { fengmingqi=1; green_led=0; yellow_led=~yellow_led; red_led=1; delay600ms(); } while(temp_distance < 1000) //距离小于1米 { green_led=1; yellow_led=1; red_led=1; en_flag=1; while(temp_distance < 1000) { fengmingqi=0; green_led=~green_led; yellow_led=~yellow_led; red_led=~red_led; delay200ms(); if(k1_flag) { uchar b; fengmingqi=1; for(b=0;b<6;b++) { green_led=~green_led; yellow_led=~yellow_led; red_led=~red_led; delay1s(); } k1_flag=0; } } en_flag=0; } } } /********************************************************/ /*定时器0中断函数*/ /********************************************************/ void timer_0(void) interrupt 1 { uchar a; TH0=(65536-20000)/256; TL0=(65536-20000)%256; a=read_key(); if(a != 0xc0) { key_pro(a); } i++; if(i==7) { if(k2_flag) { p=&str; SBUF=*p; } if(flag_1) { flag_1=0; p=&str; SBUF=*p; } } if(i >= 16) { TR0=0; ET0=0; i=0; temp_distance=read_hcsr04p(); TH0=(65536-20000)/256; TL0=(65536-20000)%256; ET0=1; TR0=1; if(k2_flag) { str[0]=temp_distance/1000 + '0'; str[2]=temp_distance%1000/100 + '0'; str[3]=temp_distance%1000%100/10 + '0'; str[4]=temp_distance%1000%100%10 + '0'; p=&str_3; SBUF=*p; //发送给串口 } } display(temp_distance); } /********************************************************/ /*串口中断函数*/ /********************************************************/ void comint() interrupt 4 { if(RI) RI=0; if(TI) { TI=0; p++; if(*p != '') SBUF=*p; } } /********************************************************/ /*读取键值函数*/ /********************************************************/ uchar read_key() { uchar key_temp; key_temp = (P1&0xc0); if(key_temp != 0xc0) //有按键按下 key_press++; else key_press = 0; //抖动 if(key_press == 2) { key_press = 0; key_re = 1; switch(key_temp) { case 0x80: key_value = 1; //按下了k1 break; case 0x40: key_value = 2; //按下了k2 break; } } //连续两次检测到按键被按下,并且该按键已经释放 if((key_re == 1) && (key_temp == 0xc0)) { key_re = 0; return key_value; } return 0xc0; //无按键按下或被按下的按键未被释放 } /********************************************************/ /*键值处理函数*/ /********************************************************/ void key_pro(uchar key_temp) { switch(key_temp) { case 1: if(en_flag) { k1_flag=1; } break; case 2: k2_flag=~k2_flag; if(~k2_flag) flag_1=1; break; } } /********************************************************/ /*数码管显示*/ /********************************************************/ void display(int a) { yiwei=0; P0=duan[a/1000]; delay100us(); P0=duan[10]; //显示数码管的dp点 delay100us(); P0=0xff; //关闭,消隐 yiwei=1; erwei=0; P0=duan[a%1000/100]; delay100us(); P0=0xff; //关闭,消隐 erwei=1; sanwei=0; P0=duan[a%1000%100/10]; delay100us(); P0=0xff; //关闭,消隐 sanwei=1; siwei=0; P0=duan[a%1000%100%10]; delay100us(); P0=0xff; //关闭,消隐 siwei=1; }
/*****HC_SR04_P.H*****/
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/*****HC_SR04_P.H*****/ #ifndef HC_SR04_P_H #define HC_SR04_P_H #ifndef _uchar_ #define _uchar_ typedef unsigned char uchar; #endif #ifndef _uint_ #define _uint_ typedef unsigned int uint; #endif sbit Trig=P2^6; //发送端 sbit Echo=P2^7; //接收端 int read_hcsr04p(); void send_high(); #endif /*****HC_SR04_P.c*****/ /* 单片机:stc90c51 晶振:12MHZ 功能: */ #include <reg51.h> #include<intrins.h> #include"HC_SR04_P.h" int read_hcsr04p() { int distance; uint t; TMOD=0x21; TH0=0; TL0=0; send_high(); while(Echo==0); TR0=1; while((Echo==1) && (TF0==0)); TR0=0; if(TF0==1) { TF0=0; distance=9999; return distance; } else { t = TH0; t <<= 8; t |= TL0; distance = (int)(t*0.17+0.5); //计算距离,单位mm } //音速0.34mm/uS return distance; } void send_high() { Trig = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //输出40微秒的高电平,触发测距 Trig = 0; }
最后
以上就是清脆大树最近收集整理的关于51单片机学习--倒车报警、超声波测距的全部内容,更多相关51单片机学习--倒车报警、超声波测距内容请搜索靠谱客的其他文章。
发表评论 取消回复