久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 8197|回復(fù): 8
收起左側(cè)

51單片機(jī)超聲波測(cè)距Proteus仿真程序

  [復(fù)制鏈接]
ID:621299 發(fā)表于 2019-10-10 20:34 | 顯示全部樓層 |閱讀模式
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
02、檢測(cè)狀態(tài).jpg 03、報(bào)警值設(shè)置狀態(tài).jpg

單片機(jī)源程序如下:
  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;            // 數(shù)據(jù)寄存器
  6. sfr ISP_ADDRH = 0xe3;            // 地址寄存器高八位
  7. sfr ISP_ADDRL = 0xe4;            // 地址寄存器低八位
  8. sfr ISP_CMD   = 0xe5;            // 命令寄存器
  9. sfr ISP_TRIG  = 0xe6;            // 命令觸發(fā)寄存器
  10. sfr ISP_CONTR = 0xe7;            // 命令寄存器


  11. sbit LcdRs_P   = P2^7;        // 1602液晶的RS管腳      
  12. sbit LcdRw_P   = P2^6;        // 1602液晶的RW管腳
  13. sbit LcdEn_P   = P2^5;        // 1602液晶的EN管腳
  14. sbit Trig_P    = P2^2;        // 超聲波模塊的Trig管腳
  15. sbit Echo_P    = P2^3;        // 超聲波模塊的Echo管腳
  16. sbit KeySet_P  = P3^2;        // “設(shè)置”按鍵的管腳
  17. sbit KeyDown_P = P3^3;        // “減”按鍵的管腳
  18. sbit KeyUp_P   = P3^4;        // “加”按鍵的管腳
  19. sbit Buzzer_P  = P2^1;        // 蜂鳴器的管腳
  20. sbit Led_P     = P2^0;        // LED報(bào)警燈的管腳


  21. uint gAlarm;                            // 報(bào)警距離變量



  22. /*********************************************************/
  23. // 單片機(jī)內(nèi)部EEPROM不使能
  24. /*********************************************************/
  25. void ISP_Disable()
  26. {
  27.     ISP_CONTR = 0;
  28.     ISP_ADDRH = 0;
  29.     ISP_ADDRL = 0;
  30. }


  31. /*********************************************************/
  32. // 從單片機(jī)內(nèi)部EEPROM讀一個(gè)字節(jié),從0x2000地址開(kāi)始
  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.     // 對(duì)STC89C51系列來(lái)說(shuō),每次要寫入0x46,再寫入0xB9,ISP/IAP才會(huì)生效
  42.     ISP_TRIG  = 0x46;      
  43.     ISP_TRIG  = 0xB9;
  44.     _nop_();
  45.     ISP_Disable();
  46.     return (ISP_DATA);
  47. }


  48. /*********************************************************/
  49. // 往單片機(jī)內(nèi)部EEPROM寫一個(gè)字節(jié),從0x2000地址開(kāi)始
  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. // 擦除單片機(jī)內(nèi)部EEPROM的一個(gè)扇區(qū)
  65. // 寫8個(gè)扇區(qū)中隨便一個(gè)的地址,便擦除該扇區(qū),寫入前要先擦除
  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. // 毫秒級(jí)的延時(shí)函數(shù),time是要延時(shí)的毫秒數(shù)
  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液晶寫命令函數(shù),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液晶寫數(shù)據(jù)函數(shù),dat就是要寫入的數(shù)據(jù)
  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. // 1602液晶初始化函數(shù)
  117. /*********************************************************/
  118. void LcdInit()
  119. {
  120.     LcdWriteCmd(0x38);        // 16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)口
  121.     LcdWriteCmd(0x0C);        // 開(kāi)顯示,不顯示光標(biāo)
  122.     LcdWriteCmd(0x06);        // 地址加1,當(dāng)寫入數(shù)據(jù)后光標(biāo)右移
  123.     LcdWriteCmd(0x01);        // 清屏
  124. }


  125. /*********************************************************/
  126. // 液晶光標(biāo)定位函數(shù)
  127. /*********************************************************/
  128. void LcdGotoXY(uchar line,uchar column)
  129. {
  130.     // 第一行
  131.     if(line==0)        
  132.         LcdWriteCmd(0x80+column);
  133.     // 第二行
  134.     if(line==1)        
  135.         LcdWriteCmd(0x80+0x40+column);
  136. }



  137. /*********************************************************/
  138. // 液晶輸出字符串函數(shù)
  139. /*********************************************************/
  140. void LcdPrintStr(uchar *str)
  141. {
  142.     while(*str!='\0')
  143.             LcdWriteData(*str++);
  144. }


  145. /*********************************************************/
  146. // 液晶輸出數(shù)字
  147. /*********************************************************/
  148. void LcdPrintNum(uint num)
  149. {
  150.     LcdWriteData(num/100+0x30);                // 百位
  151.     LcdWriteData(num%100/10+0x30);        // 十位
  152.     LcdWriteData(num%10+0x30);                // 個(gè)位
  153. }


  154. /*********************************************************/
  155. // 計(jì)算測(cè)到的距離
  156. /*********************************************************/
  157. uint GetDistance(void)
  158. {
  159.     uint ss;                    // 用于記錄測(cè)得的距離

  160.     TH0=0;
  161.     TL0=0;

  162.     Trig_P=1;                    // 給超聲波模塊一個(gè)開(kāi)始脈沖
  163.     DelayMs(1);
  164.     Trig_P=0;

  165.     while(!Echo_P);        // 等待超聲波模塊的返回脈沖
  166.     TR0=1;                        // 啟動(dòng)定時(shí)器,開(kāi)始計(jì)時(shí)
  167.     while(Echo_P);        // 等待超聲波模塊的返回脈沖結(jié)束
  168.     TR0=0;                        // 停止定時(shí)器,停止計(jì)時(shí)

  169.     ss=((TH0*256+TL0)*0.034)/2;        // 距離cm=(時(shí)間us * 速度cm/us)/2

  170.     return ss;
  171. }


  172. /*********************************************************/
  173. // 按鍵掃描
  174. /*********************************************************/
  175. void KeyScanf()
  176. {
  177.     uchar i;
  178.     uchar dat1,dat2;

  179.     if(KeySet_P==0)                    // 判斷是否有按鍵按下
  180.     {
  181.         DelayMs(10);                                // 消除按鍵按下的抖動(dòng)
  182.         while(!KeySet_P);                        // 等待按鍵釋放
  183.         DelayMs(10);                                // 消除按鍵松開(kāi)的抖動(dòng)
  184.         
  185.         LcdGotoXY(1,2);                            // 液晶第二行刷新顯示
  186.         LcdPrintStr("alarm=   cm");
  187.         LcdGotoXY(1,8);                            // 顯示當(dāng)前的報(bào)警值
  188.         LcdPrintNum(gAlarm);               

  189.         i=1;

  190.         while(i)
  191.         {                              
  192.             if(KeyDown_P==0)        // 報(bào)警值減的處理
  193.             {
  194.                 DelayMs(300);
  195.                 if(gAlarm>2)
  196.                     gAlarm--;
  197.                 LcdGotoXY(1,8);
  198.                 LcdPrintNum(gAlarm);   
  199.             }

  200.             if(KeyUp_P==0)            // 報(bào)警值加的處理
  201.             {
  202.                 DelayMs(300);
  203.                 if(gAlarm<400)
  204.                     gAlarm++;
  205.                 LcdGotoXY(1,8);
  206.                 LcdPrintNum(gAlarm);
  207.             }
  208.             
  209.             if(KeySet_P==0)            // 再次按下設(shè)置鍵的判斷
  210.             {
  211.                 DelayMs(10);                          // 消除按鍵按下的抖動(dòng)
  212.                 while(!KeySet_P);                    // 等待按鍵釋放
  213.                 DelayMs(10);                          // 消除按鍵松開(kāi)的抖動(dòng)

  214.                 LcdGotoXY(1,0);                        // 液晶恢復(fù)測(cè)量時(shí)的內(nèi)容顯示
  215.                 LcdPrintStr("     S=   cm    ");

  216.                 i=0;
  217.             }               
  218.         }
  219.         
  220.         dat1=gAlarm/100;
  221.         dat2=gAlarm%100;
  222.         Sector_Erase(0x2000);
  223.         EEPROM_Write(0x2000,dat1);
  224.         EEPROM_Write(0x2001,dat2);
  225.     }   
  226. }


  227. /*********************************************************/
  228. // 報(bào)警判斷
  229. /*********************************************************/
  230. void AlarmJudge(uint ss)
  231. {
  232.     uchar i;
  233.     float alr1,alr2,alr3,alr4;

  234.     alr1=gAlarm/4.00*1;
  235.     alr2=gAlarm/4.00*2;
  236.     alr3=gAlarm/4.00*3;
  237.     alr4=gAlarm/4.00*4;


  238.     // 報(bào)警頻率最快
  239.     if(ss<alr1)            
  240.     {
  241.         for(i=0;i<10;i++)
  242.         {
  243.             Led_P=0;
  244.             Buzzer_P=0;
  245.             DelayMs(50);
  246.             Led_P=1;
  247.             Buzzer_P=1;
  248.             DelayMs(50);
  249.             KeyScanf();
  250.         }
  251.     }
  252.     // 報(bào)警頻率第二快
  253.     else if(ss<alr2)        
  254.     {
  255.         for(i=0;i<5;i++)
  256.         {
  257.             Led_P=0;
  258.             Buzzer_P=0;
  259.             DelayMs(100);
  260.             Led_P=1;
  261.             Buzzer_P=1;
  262.             DelayMs(100);
  263.             KeyScanf();
  264.         }   
  265.     }
  266.     // 報(bào)警頻率第三快
  267.     else if(ss<alr3)     
  268.     {
  269.         for(i=0;i<2;i++)
  270.         {
  271.             Led_P=0;
  272.             Buzzer_P=0;
  273.             DelayMs(200);
  274.             Led_P=1;
  275.             Buzzer_P=1;
  276.             DelayMs(200);
  277.             KeyScanf();
  278.         }   
  279.     }
  280.     // 報(bào)警頻率最慢
  281.     else if(ss<alr4)   
  282.     {
  283.         for(i=0;i<2;i++)
  284.         {
  285.             Led_P=0;
  286.             Buzzer_P=0;
  287.             DelayMs(300);
  288.             Led_P=1;
  289.             Buzzer_P=1;
  290.             DelayMs(300);
  291.             KeyScanf();
  292.         }   
  293.     }
  294.     // 不報(bào)警
  295.     else
  296.     {
  297.         Led_P=1;
  298.         Buzzer_P=1;
  299.         for(i=0;i<100;i++)
  300.         {
  301.             KeyScanf();
  302.             DelayMs(10);
  303.         }   
  304.     }
  305. }


  306. /*********************************************************/
  307. // 主函數(shù)
  308. /*********************************************************/
  309. void main()
  310. {
  311.     uchar dat1,dat2;
  312.     uint dist;
  313.    
  314.     Trig_P=0;
  315.    
  316.     LcdInit();                                                // 執(zhí)行液晶初始化
  317.     TMOD = 0x01;                                            // 選擇定時(shí)器0,并且確定是工作方式1(為了超聲波模塊測(cè)量距離計(jì)時(shí)用的)

  318.     LcdGotoXY(0,0);                                    // 定位到第0行第0列
  319.     LcdPrintStr(" HC-SR04 System ");    // 第0行顯示“HC-SR04 System”
  320.     LcdGotoXY(1,0);                                    // 定位到第1行第0列
  321.     LcdPrintStr("     S=   cm    ");    // 第1行顯示“S=   cm”

  322.     dat1=EEPROM_Read(0x2000);                    // 從EEPROM讀取報(bào)警值
  323.     dat2=EEPROM_Read(0x2001);
  324.     gAlarm=dat1*100+dat2;

  325.     if((gAlarm==0)||(gAlarm>400))            // 如果讀取到的報(bào)警值異常(等于0或大于400則認(rèn)為異常)
  326.     {
  327.         gAlarm=25;                                            // 重新賦值報(bào)警值為25
  328.     }

  329.     while(1)
  330.     {
  331.         dist=GetDistance();                            // 通過(guò)超聲波模塊獲取距離

  332.         LcdGotoXY(1,7);                                // 定位到第1行第7列
  333.         LcdPrintNum(dist);                            // 將獲取到的距離在液晶上面顯示

  334.         AlarmJudge(dist);                                // 判斷一下是否需要報(bào)警,是的話則報(bào)警   
  335.     }
  336. }
復(fù)制代碼

所有資料51hei提供下載:
09、仿真圖.rar (637.62 KB, 下載次數(shù): 324)
07、單片機(jī)程序(先解壓,后查看).rar (283.83 KB, 下載次數(shù): 287)
回復(fù)

使用道具 舉報(bào)

ID:710713 發(fā)表于 2020-3-30 12:17 | 顯示全部樓層
樓主,我想請(qǐng)問(wèn)下這個(gè)超聲波測(cè)距的設(shè)置參數(shù)是47厘米,那在哪個(gè)地方可以給他修改到100厘米呢?
回復(fù)

使用道具 舉報(bào)

ID:280540 發(fā)表于 2019-10-20 13:20 | 顯示全部樓層
為啥連接之后報(bào)警LED閃爍,但是1602顯示上邊一排黑格,沒(méi)有數(shù)
回復(fù)

使用道具 舉報(bào)

ID:630346 發(fā)表于 2019-10-26 19:46 來(lái)自觸屏版 | 顯示全部樓層
為啥沒(méi)有看到仿真圖
回復(fù)

使用道具 舉報(bào)

ID:340288 發(fā)表于 2020-2-16 15:02 | 顯示全部樓層
謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:499645 發(fā)表于 2020-3-6 15:40 | 顯示全部樓層
為啥沒(méi)有資料包呢,上哪里去看那個(gè)視頻呢
回復(fù)

使用道具 舉報(bào)

ID:715369 發(fā)表于 2020-4-7 09:12 來(lái)自觸屏版 | 顯示全部樓層
增加有光敏電阻那一塊嗎?
回復(fù)

使用道具 舉報(bào)

ID:893935 發(fā)表于 2021-3-25 16:33 | 顯示全部樓層
為啥達(dá)到警報(bào)距離蜂鳴器不會(huì)響喃?
回復(fù)

使用道具 舉報(bào)

ID:922340 發(fā)表于 2021-5-16 23:54 | 顯示全部樓層
請(qǐng)問(wèn)如果想要不同的測(cè)量值怎么設(shè)置?這個(gè)系統(tǒng)的超聲波信號(hào)是哪里模擬出來(lái)的?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧美在线观看 | 韩国理论电影在线 | 久久久久se | 久久亚洲欧美日韩精品专区 | 久久99精品久久久97夜夜嗨 | 免费天天干 | 五月婷六月丁香 | 亚洲第一黄色网 | 一级免费看片 | 亚洲一区 中文字幕 | 久久成人免费 | 亚洲精品一区二区三区在线 | 黄视频网址| 国产成人一区二区三区久久久 | 中文字幕av一区二区三区 | 日韩一区二区视频 | 亚洲色欧美另类 | 不卡一区二区三区四区 | 国产99久久久国产精品 | 午夜网站视频 | 日韩久久综合网 | 天天爽天天操 | www.9191| 欧美色性| 色综合久久天天综合网 | 婷婷久久综合 | 亚洲另类视频 | 中文字幕欧美一区二区 | 成人午夜精品 | 中文字幕在线视频网站 | 久久国产精品99久久久大便 | 一区二区三区韩国 | 亚洲欧美激情四射 | 欧美黄色网 | 日本三级全黄三级三级三级口周 | 91精品中文字幕一区二区三区 | 国产成人一区二区三区精 | 国产乱码精品一区二区三区中文 | 日韩欧美一级 | xx视频在线观看 | 精品综合|