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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2594|回復: 2
打印 上一主題 下一主題
收起左側

基于51單片機多路超聲波顯示源程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:699194 發表于 2020-4-29 00:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本人測試成功,程序絕對可用的

單片機源程序如下:
  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   = P2^7;                // 1602液晶的RS管腳      
  12. sbit LcdRw_P   = P2^6;                // 1602液晶的RW管腳
  13. sbit LcdEn_P   = P2^5;                // 1602液晶的EN管腳
  14. sbit Trig1_P   = P2^3;                // 超聲波模塊1的Trig管腳
  15. sbit Echo1_P   = P2^4;                // 超聲波模塊1的Echo管腳
  16. sbit Trig2_P   = P1^5;                // 超聲波模塊2的Trig管腳
  17. sbit Echo2_P   = P1^6;                // 超聲波模塊2的Echo管腳
  18. sbit KeySet_P  = P1^0;                // 設置按鍵的管腳
  19. sbit KeyDown_P = P1^1;                // 減按鍵的管腳
  20. sbit KeyUp_P   = P1^2;                // 加按鍵的管腳
  21. sbit Buzzer_P  = P2^0;                // 蜂鳴器的管腳
  22. sbit Led1_P    = P2^2;                // 傳感器1報警燈
  23. sbit Led2_P    = P3^3;                // 傳感器2報警燈

  24. uint gAlarm;                                                        // 報警距離變量



  25. /*********************************************************/
  26. // 單片機內部EEPROM不使能
  27. /*********************************************************/
  28. void ISP_Disable()
  29. {
  30.         ISP_CONTR = 0;
  31.         ISP_ADDRH = 0;
  32.         ISP_ADDRL = 0;
  33. }


  34. /*********************************************************/
  35. // 從單片機內部EEPROM讀一個字節,從0x2000地址開始
  36. /*********************************************************/
  37. unsigned char EEPROM_Read(unsigned int add)
  38. {
  39.         ISP_DATA  = 0x00;
  40.         ISP_CONTR = 0x83;
  41.         ISP_CMD   = 0x01;
  42.         ISP_ADDRH = (unsigned char)(add>>8);
  43.         ISP_ADDRL = (unsigned char)(add&0xff);
  44.         // 對STC89C51系列來說,每次要寫入0x46,再寫入0xB9,ISP/IAP才會生效
  45.         ISP_TRIG  = 0x46;          
  46.         ISP_TRIG  = 0xB9;
  47.         _nop_();
  48.         ISP_Disable();
  49.         return (ISP_DATA);
  50. }


  51. /*********************************************************/
  52. // 往單片機內部EEPROM寫一個字節,從0x2000地址開始
  53. /*********************************************************/
  54. void EEPROM_Write(unsigned int add,unsigned char ch)
  55. {
  56.         ISP_CONTR = 0x83;
  57.         ISP_CMD   = 0x02;
  58.         ISP_ADDRH = (unsigned char)(add>>8);
  59.         ISP_ADDRL = (unsigned char)(add&0xff);
  60.         ISP_DATA  = ch;
  61.         ISP_TRIG  = 0x46;
  62.         ISP_TRIG  = 0xB9;
  63.         _nop_();
  64.         ISP_Disable();
  65. }


  66. /*********************************************************/
  67. // 擦除單片機內部EEPROM的一個扇區
  68. // 寫8個扇區中隨便一個的地址,便擦除該扇區,寫入前要先擦除
  69. /*********************************************************/
  70. void Sector_Erase(unsigned int add)          
  71. {
  72.         ISP_CONTR = 0x83;
  73.         ISP_CMD   = 0x03;
  74.         ISP_ADDRH = (unsigned char)(add>>8);
  75.         ISP_ADDRL = (unsigned char)(add&0xff);
  76.         ISP_TRIG  = 0x46;
  77.         ISP_TRIG  = 0xB9;
  78.         _nop_();
  79.         ISP_Disable();
  80. }



  81. /*********************************************************/
  82. // 毫秒級的延時函數,time是要延時的毫秒數
  83. /*********************************************************/
  84. void DelayMs(uint time)
  85. {
  86.         uint i,j;
  87.         for(i=0;i<time;i++)
  88.                 for(j=0;j<112;j++);
  89. }


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


  104. /*********************************************************/
  105. // 1602液晶寫數據函數,dat就是要寫入的數據
  106. /*********************************************************/
  107. void LcdWriteData(uchar dat)
  108. {
  109.         LcdRs_P = 1;
  110.         LcdRw_P = 0;
  111.         LcdEn_P = 0;
  112.         P0=dat;
  113.         DelayMs(2);
  114.         LcdEn_P = 1;   
  115.         DelayMs(2);
  116.         LcdEn_P = 0;
  117. }


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



  130. /*********************************************************/
  131. // 液晶輸出字符串函數
  132. /*********************************************************/
  133. void LcdPrintStr(uchar *str)
  134. {
  135.         while(*str!='\0')
  136.                         LcdWriteData(*str++);
  137. }


  138. /*********************************************************/
  139. // 液晶輸出數字
  140. /*********************************************************/
  141. void LcdPrintNum(uint num)
  142. {
  143.         LcdWriteData(num/100+0x30);                                // 百位
  144.         LcdWriteData(num%100/10+0x30);                // 十位
  145.         LcdWriteData(num%10+0x30);                                // 個位
  146. }


  147. /*********************************************************/
  148. // 1602液晶功能初始化
  149. /*********************************************************/
  150. void LcdInit()
  151. {
  152.         LcdWriteCmd(0x38);        // 16*2顯示,5*7點陣,8位數據口
  153.         LcdWriteCmd(0x0C);        // 開顯示,不顯示光標
  154.         LcdWriteCmd(0x06);        // 地址加1,當寫入數據后光標右移
  155.         LcdWriteCmd(0x01);        // 清屏
  156. }



  157. /*********************************************************/
  158. // 1602液晶顯示內容初始化
  159. /*********************************************************/
  160. void LcdShowInit()
  161. {
  162.         LcdGotoXY(0,0);                                                                    // 定位到第0行第0列
  163.         LcdPrintStr("  dist1=   cm   ");        // 第0行顯示“  dist1=   cm   ”
  164.         LcdGotoXY(1,0);                                                                    // 定位到第1行第0列
  165.         LcdPrintStr("  dist2=   cm   ");        // 第1行顯示“  dist2=   cm   ”
  166. }


  167. /*********************************************************/
  168. // 計算傳感器1測量到的距離
  169. /*********************************************************/
  170. uint GetDistance1(void)
  171. {
  172.         uint ss;                                        // 用于記錄測得的距離

  173.         TH0=0;
  174.         TL0=0;

  175.         Trig1_P=1;                                // 給超聲波模塊1一個開始脈沖
  176.         DelayMs(1);
  177.         Trig1_P=0;

  178.         while(!Echo1_P);        // 等待超聲波模塊1的返回脈沖
  179.         TR0=1;                                                // 啟動定時器,開始計時
  180.         while(Echo1_P);                // 等待超聲波模塊1的返回脈沖結束
  181.         TR0=0;                                                // 停止定時器,停止計時

  182.         ss=((TH0*256+TL0)*0.034)/2;                // 距離cm=(時間us * 速度cm/us)/2
  183.         return ss;
  184. }


  185. /*********************************************************/
  186. // 計算傳感器2測量到的距離
  187. /*********************************************************/
  188. uint GetDistance2(void)
  189. {
  190.         uint ss;                                        // 用于記錄測得的距離

  191.         TH0=0;
  192.         TL0=0;

  193.         Trig2_P=1;                                // 給超聲波模塊2一個開始脈沖
  194.         DelayMs(1);
  195.         Trig2_P=0;

  196.         while(!Echo2_P);        // 等待超聲波模塊2的返回脈沖
  197.         TR0=1;                                                // 啟動定時器,開始計時
  198.         while(Echo2_P);                // 等待超聲波模塊2的返回脈沖結束
  199.         TR0=0;                                                // 停止定時器,停止計時

  200.         ss=((TH0*256+TL0)*0.034)/2;                // 距離cm=(時間us * 速度cm/us)/2
  201.         return ss;
  202. }


  203. /*********************************************************/
  204. // 按鍵掃描
  205. /*********************************************************/
  206. void KeyScanf()
  207. {
  208.         if(KeySet_P==0)                                        // 判斷是否有按鍵按下
  209.         {
  210.                 LcdGotoXY(0,0);                                                                    // 光標定位
  211.                 LcdPrintStr("   Alarm Set    ");        // 第0行顯示“   Alarm Set    ”
  212.                 LcdGotoXY(1,0);                                                                                // 光標定位
  213.                 LcdPrintStr("  alarm=   cm   ");        // 第1行顯示“  alarm=   cm   ”
  214.                 LcdGotoXY(1,8);                                                                                // 光標定位
  215.                 LcdPrintNum(gAlarm);                                                        // 顯示當前的報警值

  216.                 DelayMs(10);                                                                                        // 消除按鍵按下的抖動
  217.                 while(!KeySet_P);                                                                        // 等待按鍵釋放
  218.                 DelayMs(10);                                                                                        // 消除按鍵松開的抖動               

  219.                 while(1)
  220.                 {               
  221.                         /* 報警值減的處理 */
  222.                         if(KeyDown_P==0)                                       
  223.                         {
  224.                                 if(gAlarm>2)                                                // 報警值大于2才能減1
  225.                                         gAlarm--;                                                        // 報警值減1
  226.                                 LcdGotoXY(1,8);                                        // 光標定位
  227.                                 LcdPrintNum(gAlarm);                // 刷新修改后的報警值
  228.                                 DelayMs(300);                                                // 延時
  229.                         }

  230.                         /* 報警值加的處理 */
  231.                         if(KeyUp_P==0)                                       
  232.                         {
  233.                                 if(gAlarm<400)                                        // 報警值小于400才能加1
  234.                                         gAlarm++;                                                        // 報警值加1
  235.                                 LcdGotoXY(1,8);                                        // 光標定位
  236.                                 LcdPrintNum(gAlarm);                // 刷新修改后的報警值
  237.                                 DelayMs(300);                                                // 延時
  238.                         }
  239.                        
  240.                         /* 退出報警值設置 */
  241.                         if(KeySet_P==0)                                       
  242.                         {
  243.                                 break;                                                                        // 退出while循環
  244.                         }       
  245.                 }
  246.                
  247.                 LcdShowInit();                                                        // 液晶恢復測量到測量界面
  248.                 DelayMs(10);                                                          // 消除按鍵按下的抖動
  249.                 while(!KeySet_P);                                                // 等待按鍵釋放
  250.                 DelayMs(10);                                                          // 消除按鍵松開的抖動               

  251.                 Sector_Erase(0x2000);                                // 保存報警距離
  252.                 EEPROM_Write(0x2000,gAlarm/100);
  253.                 EEPROM_Write(0x2001,gAlarm%100);               
  254.         }       
  255. }


  256. /*********************************************************/
  257. // 傳感器1報警判斷
  258. /*********************************************************/
  259. void AlarmJudge1(uint ss)
  260. {
  261.         if(ss<gAlarm)                // LED燈判斷
  262.         {
  263.                 Led1_P=0;
  264.         }
  265.         else
  266.         {
  267.                 Led1_P=1;
  268.         }
  269.        
  270.         if((Led1_P==0)||(Led2_P==0))        // 蜂鳴器判斷
  271.         {
  272.                 Buzzer_P=0;
  273.         }
  274.         else
  275.         {
  276.                 Buzzer_P=1;
  277.         }
  278. }


  279. /*********************************************************/
  280. // 傳感器2報警判斷
  281. /*********************************************************/
  282. void AlarmJudge2(uint ss)
  283. {
  284.         if(ss<gAlarm)                // LED燈判斷
  285.         {
  286.                 Led2_P=0;
  287.         }
  288.         else
  289.         {
  290.                 Led2_P=1;
  291.         }
  292.        
  293.         if((Led1_P==0)||(Led2_P==0))        // 蜂鳴器判斷
  294.         {
  295.                 Buzzer_P=0;
  296.         }
  297.         else
  298.         {
  299.                 Buzzer_P=1;
  300.         }
  301. }


  302. /*********************************************************/
  303. // 報警值初始化
  304. /*********************************************************/
  305. void AlarmInit()
  306. {
  307.         gAlarm=EEPROM_Read(0x2000)*100+EEPROM_Read(0x2001);                // 從EEPROM讀取報警值

  308.         if((gAlarm==0)||(gAlarm>400))                        // 如果讀取到的報警值異常(等于0或大于400則認為異常)
  309.         {
  310.                 gAlarm=25;                                                                                        // 重新賦值報警值為25
  311.         }
  312. }



  313. /*********************************************************/
  314. // 主函數
  315. /*********************************************************/
  316. void main()
  317. {
  318.         uchar i;                                                                        // 循環變量
  319.         uint dist;                                                                // 保存測量結果

  320.         LcdInit();                                                                // 液晶功能初始化
  321.         LcdShowInit();                                                // 液晶顯示內容初始化
  322.         AlarmInit();                                                        // 報警值初始化
  323.        
  324.         TMOD = 0x01;                                                        // 選擇定時器0,并且確定是工作方式1(為了超聲波模塊測量距離計時用的)

  325.         Trig1_P=0;                                                                // 初始化觸發引腳為低電平
  326.         Trig2_P=0;

  327.         while(1)
  328.         {
  329.                 /*傳感器1*/
  330.                 dist=GetDistance1();                // 讀取超聲波模塊1測量到的距離
  331.                 LcdGotoXY(0,8);                            // 光標定位
  332.                 LcdPrintNum(dist);                        // 顯示傳感器1測量到的距離
  333.                 AlarmJudge1(dist);                        // 判斷傳感器1的測量距離是否需要報警
  334.                
  335.                 /*延時并掃描按鍵*/
  336.                 for(i=0;i<20;i++)
  337.                 {
  338.                         KeyScanf();
  339.                         DelayMs(10);
  340.                 }
  341.                
  342.                 /*傳感器2*/
  343.                 dist=GetDistance2();                // 讀取超聲波模塊2測量到的距離
  344.                 LcdGotoXY(1,8);                            // 光標定位
  345.                 LcdPrintNum(dist);                        // 顯示傳感器2測量到的距離
  346.                 AlarmJudge2(dist);                        // 判斷傳感器2的測量距離是否需要報警
  347.                
  348.                 /*延時并掃描按鍵*/
  349.                 for(i=0;i<20;i++)
  350.                 {
  351.                         KeyScanf();
  352.                         DelayMs(10);
  353.                 }
  354.         }
  355. }
復制代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂3 踩
回復

使用道具 舉報

沙發
ID:632112 發表于 2020-5-20 09:33 | 只看該作者
正在找呢,謝謝樓主
回復

使用道具 舉報

板凳
ID:761098 發表于 2020-5-28 09:18 | 只看該作者
樓主 有沒有測量的數據?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产精品精华素 | 国产精品高潮呻吟久久 | 精品一区二区在线看 | 免费看的av| 91社影院在线观看 | 91精品国产综合久久久久久蜜臀 | 国产a视频 | 麻豆精品国产91久久久久久 | 亚洲欧美一区二区三区视频 | 亚洲成人精品一区 | 国产欧美精品在线观看 | 欧美国产一区二区 | 99久久精品免费看国产高清 | 午夜爱爱毛片xxxx视频免费看 | 国产精品一区在线观看 | 日韩成人在线观看 | 午夜视频在线观看视频 | 国产一区二区 | 日本一区二区高清视频 | 欧美久久天堂 | 日韩在线中文 | 欧美影院 | 国产91在线播放精品91 | 欧美精品v国产精品v日韩精品 | 欧美一级在线观看 | 国产一区二区在线免费观看 | 亚洲综合在线播放 | 日韩免费 | 国产一级在线观看 | 精品视频一区二区三区 | 久久999 | h网站在线观看 | 久久不卡区 | 日韩免费毛片视频 | 国产女人第一次做爰毛片 | 少妇精品久久久久久久久久 | 亚洲免费精品一区 | 在线国产一区二区 | 91视频一88av| 四虎成人精品永久免费av九九 | 粉嫩一区二区三区四区公司1 |