📄 complete.lst
字号:
227 {
228 1 if(RI)
229 1 {
230 2 RI=0; //清除接收中断.
231 2 rs485_data=SBUF; //暂存接收到的数据.
232 2 if(rs485_status==0x00) //如果RS485接收中断程序处于状态0
233 2 {
234 3 if(rs485_data==meter_address_return[m_meteraddrc])
235 3 {
236 4 m_meteraddrc++; //如果对应位置的地址数据一致,则更新数据段地址计数器
237 4 }
238 3 else
239 3 {
240 4 m_meteraddrc=0x00; //准备重新接收数据帧地址信息
241 4 }
C51 COMPILER V6.12 COMPLETE 01/19/2007 19:57:22 PAGE 5
242 3 if(m_meteraddrc==2) //判断地址表中的2个字节是否结束
243 3 {
244 4 m_meteraddrc=0x00;
245 4 rs485_status=0x01; //更新RS485接收中断程序的状态
246 4 }
247 3 }
248 2 else if(rs485_status==0x01) //如果接收中断程序状态处于1,则接收发送方的地址
249 2 {
250 3
251 3 m_sendaddrcode=rs485_data; //保存发送方的地址
252 3 rs485_status=0x02; //更新RS485接收中断程序的状态
253 3 }
254 2 else if(rs485_status==0x02) //如果接收中断程序状态处于2,则接收接收方的地址.
255 2 {
256 3 m_receiveaddrcode=rs485_data;//保存接收方的地址.
257 3 m_meterdatac=0x00; //复位数据段计数器.
258 3 rs485_status=0x03; //更新RS485接收中断程序的状态
259 3 }
260 2
261 2 else if(rs485_status==0x03) //如果接收中断程序处于3,则接收数据信息.
262 2 {
263 3 m_meterdatbuf[m_meterdatac]=rs485_data; //保存接收的数据信息
264 3 m_meterdatac++; //更新数据计数器
265 3 if(m_meterdatac==8) //判断数据段是否接收完?
266 3 {
267 4 m_metersyscheck= 0xac+0xca+m_sendaddrcode+m_receiveaddrcode; //初始化和校验变量
268 4 rs485_status=0x04; //更新RS485接收中断程序的状态
269 4 }
270 3 }
271 2
272 2 else if(rs485_status==0x04) //如果接收中断程序处于4,则接收累加和校验信息
273 2 {
274 3 m_metercheck=rs485_data; //保存接收到的累加和校验信息.
275 3 for(m_meterdatac=0;m_meterdatac<8;m_meterdatac++)//累加数据段.
276 3 {
277 4 m_metersyscheck+=m_meterdatbuf[m_meterdatac];
278 4 }
279 3
280 3
281 3
282 3 rs485_status=0x05; //更新RS485接收中断程序的状态
283 3
284 3 }
285 2 else if(rs485_status==0x05) //如果RS485接收中断程序处于状态5,则接收结束符.
286 2 {
287 3
288 3 re_de1=0; //设置RS485进入发送状态.设置MAX485(3)接收
289 3 re_de2=0; //设置MAX485(2)接收
290 3 re_de3=1; //设置MAX485(1)发送.
291 3
292 3 m_meteraddrc=0x00; //重新接收数据帧中的地址信息
293 3 rs485_status=0x00; //复位RS485接收中断程序状态标志.
294 3 if(m_metersyscheck==m_metercheck ) //如果正确接收到数据,发出dd.
295 3 {
296 4
297 4 switch(m_meterdatbuf[0])
298 4 {
299 5 case 0x30:send_ultrasonic();break; //如果是30H,发送超声信息。
300 5
301 5 case 0x40:send_mapan(); break; //如果是50H,发送码盘信息。
302 5 case 0x50:send_compass(); break; //如果是60H,发送罗盘信息。
303 5 default : send_frameagain(); //请求重发。
C51 COMPILER V6.12 COMPLETE 01/19/2007 19:57:22 PAGE 6
304 5 }
305 4 }
306 3 else
307 3 {
308 4 send_frameagain();
309 4 }
310 3 m_metersyscheck=0x00;
311 3 m_metercheck=0x00;
312 3 }
313 2 }
314 1
315 1
316 1 }
317
318
319
320
321 /*主程序*/
322 void main(void)
323 {
324 1 TMOD=0x11; //16位定时器T0,16位定时器T1工作方式皆方式1.
325 1
326 1
327 1 TCON=0x01; //设置TCON,INT1为低电平有效,INT0为下降沿有效.IT0=1
328 1 d=0;
329 1 EA=1;
330 1 PX0=1; //设置INT0中断优先级高
331 1 PT0=1; //定时器中1的中断优先级高
332 1 PS=0; //串口的优先级低,
333 1 P0_7=1; //CD4520先清零
334 1 P0_7=0; //让CD4520工作.
335 1 tmp1=0; //赋初值.
336 1 tmp2=0; //赋初值.
337 1 count1=0; //左车轮计数是否溢出先清零。
338 1 count2=0; //右车轮计数是否溢出先清零。
339 1
340 1 T2CON=0x30;
341 1 RCAP2H=0xff; //用T2做波特率发生器.9600 置初值.
342 1 RCAP2L=0xdc;
343 1 PCON&=0x0f; //波特率不加倍.
344 1 SCON=0x70; //设置串行口工作方式为方式1
345 1 ES=1; //串行中断允许
346 1 TR2=1; //定时器T1启动
347 1 re_de1=1; //设置MAX485进入接收状态,设置MAX485(3)发送.
348 1 re_de2=0;
349 1 re_de3=0; //设置MAX485(1)接收.
350 1
351 1 while(1)
352 1 {
353 2
354 2 int i;
355 2 for(i=0;i<8;i++) //清超声波组
356 2 {
357 3 array1[i]=0;
358 3 }
359 2 for(i=0;i<5;i++) //清红外线组
360 2 {
361 3 z[i]=0;
362 3 }
363 2 for(i=0;i<2;i++) //清码盘组
364 2 {
365 3 array3[i]=0;
C51 COMPILER V6.12 COMPLETE 01/19/2007 19:57:22 PAGE 7
366 3 }
367 2 for(i=0;i<=7;i++)
368 2 {
369 3 select=i;
370 3 IE = 0x82;
371 3 P0_0=flag0;P0_1=flag1;P0_2=flag2;P0_3=1; //选中第i路.分别为0.1.2.3.4.5.6.7路.
372 3 TH0=0xca;
373 3 TL0=0x00;
374 3 TH1=0xFe;TL1=0x33; //发送20个脉冲=0.5ms,用T1计时0.5ms.
375 3 TF1=0; //打开定时器T0,15ms
376 3 TF0=0;
377 3 TR1=1;TR0=1; //同时启动T0,T1
378 3 do{}while(TF1==0); //等0.5ms时间结束.
379 3 P0_3=0; //关闭555
380 3 TR1=0;TH1=0xfc;TL1=0x66; //延时1ms,盲区26cm
381 3 TF1=0;
382 3 TR1=1;
383 3 do{}while(TF1==0); //等待结束.
384 3 a=0;
385 3 IE0=0; //开中断前,清中断
386 3 EX0=1; //允许外部中断int0
387 3 do{}while(a==0);
388 3 array1[i]=count;
389 3
390 3 }
391 2 e1=1; //对P1口的高三位置位
392 2 e2=1;
393 2 e3=1;
394 2 IE1=0; //开中断前先清外部中断1,
395 2 EX1=1; //设置外部中断1允许.
396 2 delayms(1);
397 2
398 2 array2[0]=z0; //把第0路红外线信号赋入array2[0].
399 2 array2[1]=z1; //把第1路红外线信号赋入array2[1]
400 2 array2[2]=z2; //把第2路红外线信号赋入array2[2]
401 2 array2[3]=z3; //把第3路红外线信号赋入array2[3]
402 2 array2[4]=z4; //把第4路红外线信号赋入array2[4]
403 2
404 2 for(i=0;i<8;i++) //对超声波和红外线进行综合处理.
405 2 {
406 3 if(i<3)
407 3 {
408 4 if(z[i]==1)
409 4 {
410 5 array1[i]=-1; //说明在盲区内有障碍物的存在.
411 5 }
412 4 }
413 3 else if(i==3)
414 3 {
415 4 if(z[2]==1) //说明在盲区内有障碍物的存在.
416 4 {
417 5 array1[3]=-1;
418 5 }
419 4 }
420 3 else if(3<i<=5) //说明在盲区内有障碍物的存在.
421 3 {
422 4 if(z[3]==1)
423 4 {
424 5 array1[i]=-1;
425 5 }
426 4 }
427 3 else if(5<i<=7) //说明在盲区内有障碍物的存在.
C51 COMPILER V6.12 COMPLETE 01/19/2007 19:57:22 PAGE 8
428 3 {
429 4 if(z[4]==1)
430 4 {
431 5 array1[6]==-1;
*** WARNING C275 IN LINE 431 OF .\COMPLETE.C: expression with possibly no effect
432 5 array1[7]=-1;
433 5 }
434 4 }
435 3
436 3 }
437 2
438 2
439 2
440 2
441 2 dis1=tmp1; //记录tmp1的上一次的值.
442 2 dis2=tmp2; //记录tmp2的上一次的值.
443 2 tmp1=P2;
444 2 tmp1=tmp1&0x0f; //左车轮取P2低4位,
445 2 tmp2=P2;
446 2 tmp2>>=4; //取得的P2口数据右移4位,以便下一步取值。
447 2 tmp2=tmp2&0x0f; //右车轮取P2高4位。
448 2 if(tmp1<dis1)
449 2 {
450 3 ++count3;
451 3 }
452 2 if(tmp2<dis2)
453 2 {
454 3 ++count4;
455 3 }
456 2 array3[0]=road(count3,tmp1);
457 2 array3[1]=road(count4,tmp2);
458 2 /* for(i=0;i<8;i++) //以下程序用于输出测的值,经过实验,在KEIL中用PRINTF不能输出,可
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -