找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2055|回复: 0
打印 上一主题 下一主题
收起左侧

单片机小车超声波防撞倒车雷达系统Proteus仿真程序

[复制链接]
跳转到指定楼层
楼主
防倒车雷达系统自己的一点思考
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char        // 以后unsigned char就可以用uchar代替
  4. #define uint  unsigned int        // 以后unsigned int 就可以用uint 代替

  5. sfr ISP_DATA  = 0xe2;                        // 数据寄存器
  6. sfr ISP_ADDRH = 0xe3;                        // 地址寄存器高八位
  7. sfr ISP_ADDRL = 0xe4;                        // 地址寄存器低八位
  8. sfr ISP_CMD   = 0xe5;                        // 命令寄存器
  9. sfr ISP_TRIG  = 0xe6;                        // 命令触发寄存器
  10. sfr ISP_CONTR = 0xe7;                        // 命令寄存器

  11. sbit LcdRs_P   = P1^1;                // 1602液晶的RS管脚      
  12. sbit LcdRw_P   = P1^2;                // 1602液晶的RW管脚
  13. sbit LcdEn_P   = P1^3;                // 1602液晶的EN管脚

  14. sbit Trig1_P   = P3^2;                // 超声波模块1的Trig管脚
  15. sbit Echo1_P   = P3^3;                // 超声波模块1的Echo管脚

  16. sbit KeySet_P  = P2^2;                // 设置按键的管脚
  17. sbit KeyDown_P = P2^1;                // 减按键的管脚
  18. sbit KeyUp_P   = P2^0;                // 加按键的管脚

  19. sbit Buzzer_P  = P2^3;                // 蜂鸣器的管脚
  20. sbit Led1_P    = P3^4;                // 传感器1报警灯

  21. uint gAlarm;                                                        // 报警距离变量



  22. /*********************************************************/
  23. // 单片机内部EEPROM不使能
  24. /*********************************************************/
  25. void ISP_Disable()
  26. {
  27.         ISP_CONTR = 0;
  28.         ISP_ADDRH = 0;
  29.         ISP_ADDRL = 0;
  30. }


  31. /*********************************************************/
  32. // 从单片机内部EEPROM读一个字节,从0x2000地址开始
  33. /*********************************************************/
  34. unsigned char EEPROM_Read(unsigned int add)
  35. {
  36.         ISP_DATA  = 0x00;
  37.         ISP_CONTR = 0x83;
  38.         ISP_CMD   = 0x01;
  39.         ISP_ADDRH = (unsigned char)(add>>8);
  40.         ISP_ADDRL = (unsigned char)(add&0xff);
  41.         // 对STC89C51系列来说,每次要写入0x46,再写入0xB9,ISP/IAP才会生效
  42.         ISP_TRIG  = 0x46;          
  43.         ISP_TRIG  = 0xB9;
  44.         _nop_();
  45.         ISP_Disable();
  46.         return (ISP_DATA);
  47. }


  48. /*********************************************************/
  49. // 往单片机内部EEPROM写一个字节,从0x2000地址开始
  50. /*********************************************************/
  51. void EEPROM_Write(unsigned int add,unsigned char ch)
  52. {
  53.         ISP_CONTR = 0x83;
  54.         ISP_CMD   = 0x02;
  55.         ISP_ADDRH = (unsigned char)(add>>8);
  56.         ISP_ADDRL = (unsigned char)(add&0xff);
  57.         ISP_DATA  = ch;
  58.         ISP_TRIG  = 0x46;
  59.         ISP_TRIG  = 0xB9;
  60.         _nop_();
  61.         ISP_Disable();
  62. }


  63. /*********************************************************/
  64. // 擦除单片机内部EEPROM的一个扇区
  65. // 写8个扇区中随便一个的地址,便擦除该扇区,写入前要先擦除
  66. /*********************************************************/
  67. void Sector_Erase(unsigned int add)          
  68. {
  69.         ISP_CONTR = 0x83;
  70.         ISP_CMD   = 0x03;
  71.         ISP_ADDRH = (unsigned char)(add>>8);
  72.         ISP_ADDRL = (unsigned char)(add&0xff);
  73.         ISP_TRIG  = 0x46;
  74.         ISP_TRIG  = 0xB9;
  75.         _nop_();
  76.         ISP_Disable();
  77. }



  78. /*********************************************************/
  79. // 毫秒级的延时函数,time是要延时的毫秒数
  80. /*********************************************************/
  81. void DelayMs(uint time)
  82. {
  83.         uint i,j;
  84.         for(i=0;i<time;i++)
  85.                 for(j=0;j<112;j++);
  86. }


  87. /*********************************************************/
  88. // 1602液晶写命令函数,cmd就是要写入的命令
  89. /*********************************************************/
  90. void LcdWriteCmd(uchar cmd)
  91. {
  92.         LcdRs_P = 0;
  93.         LcdRw_P = 0;
  94.         LcdEn_P = 0;
  95.         P0=cmd;
  96.         DelayMs(2);
  97.         LcdEn_P = 1;   
  98.         DelayMs(2);
  99.         LcdEn_P = 0;       
  100. }


  101. /*********************************************************/
  102. // 1602液晶写数据函数,dat就是要写入的数据
  103. /*********************************************************/
  104. void LcdWriteData(uchar dat)
  105. {
  106.         LcdRs_P = 1;
  107.         LcdRw_P = 0;
  108.         LcdEn_P = 0;
  109.         P0=dat;
  110.         DelayMs(2);
  111.         LcdEn_P = 1;   
  112.         DelayMs(2);
  113.         LcdEn_P = 0;
  114. }


  115. /*********************************************************/
  116. // 液晶光标定位函数
  117. /*********************************************************/
  118. void LcdGotoXY(uchar line,uchar column)
  119. {
  120.         // 第一行
  121.         if(line==0)        
  122.                 LcdWriteCmd(0x80+column);
  123.         // 第二行
  124.         if(line==1)        
  125.                 LcdWriteCmd(0x80+0x40+column);
  126. }



  127. /*********************************************************/
  128. // 液晶输出字符串函数
  129. /*********************************************************/
  130. void LcdPrintStr(uchar *str)
  131. {
  132.         while(*str!='\0')
  133.                         LcdWriteData(*str++);
  134. }


  135. /*********************************************************/
  136. // 液晶输出数字
  137. /*********************************************************/
  138. void LcdPrintNum(uint num)
  139. {
  140.         LcdWriteData(num/100+0x30);                                // 百位
  141.         LcdWriteData(num%100/10+0x30);                // 十位
  142.         LcdWriteData(num%10+0x30);                                // 个位
  143. }


  144. /*********************************************************/
  145. // 1602液晶功能初始化
  146. /*********************************************************/
  147. void LcdInit()
  148. {
  149.         LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口
  150.         LcdWriteCmd(0x0C);        // 开显示,不显示光标
  151.         LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移
  152.         LcdWriteCmd(0x01);        // 清屏
  153. }



  154. /*********************************************************/
  155. // 1602液晶显示内容初始化
  156. /*********************************************************/
  157. void LcdShowInit()
  158. {
  159.         LcdGotoXY(0,0);                                                                    // 定位到第0行第0列
  160.         LcdPrintStr("D:    cm jianghe");        // 第0行显示"D:         "
  161. }


  162. /*********************************************************/
  163. // 计算传感器1测量到的距离
  164. /*********************************************************/

  165. uint GetDistance1(void)
  166. {
  167.         uint ss;                                        // 用于记录测得的距离

  168.         TH0=0;
  169.         TL0=0;

  170.         Trig1_P=1;                                // 给超声波模块1一个开始脉冲
  171.         DelayMs(1);
  172.         Trig1_P=0;

  173.         while(!Echo1_P);        // 等待超声波模块1的返回脉冲
  174.         TR0=1;                                                // 启动定时器,开始计时
  175.         while(Echo1_P);                // 等待超声波模块1的返回脉冲结束
  176.         TR0=0;                                                // 停止定时器,停止计时

  177.         ss=((TH0*256+TL0)*0.034)/2;                // 距离cm=(时间us * 速度cm/us)/2
  178.         return ss;
  179. }

  180. /*********************************************************/
  181. // 按键扫描
  182. /*********************************************************/
  183. void KeyScanf()
  184. {
  185.         if(KeySet_P==0)                                        // 判断是否有按键按下
  186.         {
  187.                 LcdGotoXY(0,0);                                                                    // 光标定位
  188.                 LcdPrintStr(" Alarm Set 1037 ");        // 第0行显示“   Alarm Set    ”
  189.                 LcdGotoXY(1,0);                                                                                // 光标定位
  190.                 LcdPrintStr(" alarm =     cm ");        // 第1行显示“  alarm=   cm   ”
  191.                 LcdGotoXY(1,9);                                                                                // 光标定位
  192.                 LcdPrintNum(gAlarm);                                                        // 显示当前的报警值

  193.                 DelayMs(10);                                                                                        // 消除按键按下的抖动
  194.                 while(!KeySet_P);                                                                        // 等待按键释放
  195.                 DelayMs(10);                                                                                        // 消除按键松开的抖动               

  196.                 while(1)
  197.                 {               
  198.                         /* 报警值减的处理 */
  199.                         if(KeyDown_P==0)                                       
  200.                         {
  201.                                 if(gAlarm>2)                                                // 报警值大于2才能减1
  202.                                         gAlarm--;                                                        // 报警值减1
  203.                                 LcdGotoXY(1,9);                                        // 光标定位
  204.                                 LcdPrintNum(gAlarm);                // 刷新修改后的报警值
  205.                                 DelayMs(300);                                                // 延时
  206.                         }

  207.                         /* 报警值加的处理 */
  208.                         if(KeyUp_P==0)                                       
  209.                         {
  210.                                 if(gAlarm<400)                                        // 报警值小于400才能加1
  211.                                         gAlarm++;                                                        // 报警值加1
  212.                                 LcdGotoXY(1,9);                                        // 光标定位
  213.                                 LcdPrintNum(gAlarm);                // 刷新修改后的报警值
  214.                                 DelayMs(300);                                                // 延时
  215.                         }
  216.                        
  217.                         /* 退出报警值设置 */
  218.                         if(KeySet_P==0)                                       
  219.                         {
  220.                                 break;                                                                        // 退出while循环
  221.                         }       
  222.                 }
  223.                
  224.                 LcdShowInit();                                                        // 液晶恢复测量到测量界面
  225.                 DelayMs(10);                                                          // 消除按键按下的抖动
  226.                 while(!KeySet_P);                                                // 等待按键释放
  227.                 DelayMs(10);                                                          // 消除按键松开的抖动               

  228.                 Sector_Erase(0x2000);                                // 保存报警距离
  229.                 EEPROM_Write(0x2000,gAlarm/100);
  230.                 EEPROM_Write(0x2001,gAlarm%100);               
  231.         }       
  232. }


  233. /*********************************************************/
  234. // 传感器1报警判断
  235. /*********************************************************/
  236. void AlarmJudge1(uint ss)
  237. {
  238.        
  239.         if(ss<gAlarm)                // LED灯判断
  240.         {
  241.                 Led1_P=0;
  242.                 Buzzer_P=1;
  243.                 DelayMs(100);
  244.                 Buzzer_P=0;
  245.                 //DelayMs(100);
  246.         }
  247.         else
  248.         {
  249.                 Led1_P=1;
  250.                 Buzzer_P=0;
  251.         }


  252. }

  253. /*********************************************************/
  254. // 报警值初始化
  255. /*********************************************************/
  256. void AlarmInit()
  257. {
  258.         gAlarm=EEPROM_Read(0x2000)*100+EEPROM_Read(0x2001);                // 从EEPROM读取报警值

  259.         if((gAlarm==0)||(gAlarm>400))                        // 如果读取到的报警值异常(等于0或大于400则认为异常)
  260.         {
  261.                 gAlarm=15;                                                                                        // 重新赋值报警值为15
  262.         }
  263. }


  264. /*********************************************************/
  265. // 主函数
  266. /*********************************************************/
  267. void main()
  268. {
  269.         uchar i;                                                                        // 循环变量
  270.         uint dist;                                                                // 保存测量结果

  271.         LcdInit();                                                                // 液晶功能初始化
  272.         LcdShowInit();                                                // 液晶显示内容初始化
  273.         AlarmInit();                                                        // 报警值初始化
  274.        
  275.         TMOD = 0x01;                                                        // 选择定时器0,并且确定是工作方式1(为了超声波模块测量距离计时用的)

  276.         Trig1_P=0;                                                                // 初始化触发引脚为低电平

  277.         while(1)
  278.         {
  279.                 /*传感器1*/
  280.                 dist=GetDistance1();                // 读取超声波模块1测量到的距离
  281.                 LcdGotoXY(0,3);                            // 光标定位
  282.                 LcdPrintNum(dist);                        // 显示传感器1测量到的距离
  283.                 AlarmJudge1(dist);                        // 判断传感器1的测量距离是否需要报警
  284.                
  285.                 /*延时并扫描按键*/
  286.                 for(i=0;i<15;i++)
  287.                 {
  288.                         KeyScanf();
  289.                         DelayMs(10);
  290.                 }

  291.                
  292.         }
  293. }
复制代码

仿真代码资料51hei附件下载:
倒车雷达系统设计.zip (593.56 KB, 下载次数: 74)


评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表