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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機超聲波程序(帶詳細注釋)Proteus仿真圖

[復制鏈接]
跳轉到指定樓層
樓主
這是我之前做的基于STM32的超聲波測距系統,
附件里面包含了keil仿真代碼以及Proteus仿真工程
請大家多多指教



單片機源程序如下:
  1. //頭文件包含
  2. #include <reg52.h>                //提供單片機寄存器地址
  3. #include <intrins.h>        //提供_nop_()函數

  4. unsigned int code duan_ma[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,                //0~9
  5.                                                                  0x77,0x7c,0x39,0x5e,0x79,0x71};        //A~F
  6. unsigned int dis_buf[4];                        //顯示緩存的數組
  7. unsigned int S = 0;                                        //距離緩存變量
  8. unsigned long time = 0;                                //時間緩存變量
  9. unsigned int S_H = 400, S_L = 10;        //S_H:報警上限值,默認400cm,S_L:報警下限值,默認10cm

  10. //引腳定義
  11. sbit BEEP = P3^7;                //蜂鳴器控制端口,低電平有效,無源蜂鳴器
  12.                                                                  
  13. #define digDuan                P0                //數碼管段控制端口,高電平有效
  14. sbit digWei1 = P2^4;                //第1位數碼管控制端口,低電平有效
  15. sbit digWei2 = P2^5;                //第2位數碼管控制端口,低電平有效
  16. sbit digWei3 = P2^6;                //第3位數碼管控制端口,低電平有效
  17. sbit digWei4 = P2^7;                //第4位數碼管控制端口,低電平有效                                                                 
  18.        
  19. sbit KEY1 = P1^0;                        //設置鍵
  20. sbit KEY2 = P1^1;                        //加鍵
  21. sbit KEY3 = P1^2;                        //減鍵                                                                 
  22.                        
  23. sbit Ttig = P1^3;                //觸發信號控制端口
  24. sbit Echo = P1^4;                //回響信號接收端口
  25.                                                                  
  26. /* 定時器0和1初始化,定時1ms */
  27. void InitTimer0(void)
  28. {
  29.   TMOD = 0x11;        //配置定時器0為工作方式1,定時器1位工作方式1
  30.         TH0 = 0;
  31.   TL0 = 0;
  32.         TH1 = 0x0EC;        //定時5ms
  33.   TL1 = 0x78;
  34.         EA = 1;                        //打開總中斷
  35.         ET1 = 1;                //打開定時器0中斷
  36.         TR1 = 1;                //打開定時器1
  37.   TR0 = 0;                //打開定時器0
  38. }

  39. /*
  40. * 數碼管掃描
  41. * *dat:以數組的方式傳值,使用的時候直接填入數組名即可
  42. */  
  43. void dig_scan(unsigned int *dat)
  44. {
  45.         static unsigned char i = 0;        //循環變量

  46.         /* 數碼管掃描處理 */
  47.         digDuan = 0x00;                //消隱
  48.         digWei1 = 1;                       
  49.         digWei2 = 1;                        
  50.         digWei3 = 1;
  51.         digWei4 = 1;
  52.         switch(i)
  53.         {
  54.                 case 0:
  55.                 {
  56.                         digWei1 = 0;                        //選通第1位數碼管
  57.                         digDuan = dat[0];                //顯示第1位數碼管的內容
  58.                         break;
  59.                 }
  60.                 case 1:
  61.                 {
  62.                         digWei2 = 0;                        //選通第2位數碼管
  63.                         digDuan = dat[1];                //顯示第2位數碼管的內容
  64.                         break;
  65.                 }
  66.                 case 2:
  67.                 {
  68.                         digWei3 = 0;                                //選通第3位數碼管
  69.                         digDuan = dat[2] + 0x80;        //顯示第3位數碼管的內容,順便也顯示小數點
  70.                         break;
  71.                 }
  72.                 case 3:
  73.                 {
  74.                         digWei4 = 0;                        //選通第4位數碼管
  75.                          digDuan = dat[3];                //顯示第4位數碼管的內容
  76.                         break;       
  77.                 }
  78.                 default: break;
  79.         }
  80.         ++i;                //數碼管位選變量循環
  81.         if(i >= 4)
  82.                 i = 0;                               
  83. }

  84. /* 按鍵延時函數,單位:ms */
  85. static void key_delayms(unsigned int ms)
  86. {
  87.         unsigned char a,b,c;
  88.         while(--ms)
  89.         {
  90.             for(c=1;c>0;c--)
  91.                 for(b=142;b>0;b--)
  92.                     for(a=2;a>0;a--);
  93.         }
  94. }
  95. /* 按鍵掃描 */
  96. unsigned char key_scan(void)
  97. {
  98.         if(KEY1 == 0)                        //如果按鍵1按下
  99.         {
  100.                 key_delayms(10);        //延時10ms,去除按鍵抖動
  101.                 if(KEY1 == 0)                //再判斷一次按鍵按下
  102.                 {
  103.                         return 1;                 //輸出鍵值1
  104.                 }       
  105.         }
  106.         if(KEY2 == 0)                //如果按鍵2按下
  107.         {
  108.                 key_delayms(10);        //延時10ms,去除按鍵抖動
  109.                 if(KEY2 == 0)                //再判斷一次按鍵按下
  110.                 {
  111.                         return 2;                 //輸出鍵值2
  112.                 }
  113.         }
  114.         if(KEY3 == 0)                //如果按鍵3按下
  115.         {
  116.                 key_delayms(10);        //延時10ms,去除按鍵抖動
  117.                 if(KEY3 == 0)                //再判斷一次按鍵按下
  118.                 {
  119.                         return 3;                 //輸出鍵值3
  120.                 }
  121.         }

  122.         return 0;                                //如果沒有按鍵按下,則輸出0
  123. }

  124. /* 啟動超聲波程序 */
  125. void StartModule(void)
  126. {
  127.         Ttig = 1;                        //啟動一次模塊
  128.         _nop_();                        //延時一段時間,至少10us以上
  129.         _nop_();                        
  130.         _nop_();
  131.         _nop_();
  132.         _nop_();
  133.         _nop_();
  134.         _nop_();
  135.         _nop_();
  136.         _nop_();
  137.         _nop_();
  138.         _nop_();
  139.         _nop_();
  140.         _nop_();
  141.         _nop_();
  142.         _nop_();
  143.         _nop_();
  144.         _nop_();
  145.         _nop_();
  146.         _nop_();
  147.         _nop_();
  148.         _nop_();
  149.         Ttig = 0;
  150. }

  151. /* 延時,單位:ms */
  152. void delayms(unsigned int ms)
  153. {
  154.         unsigned char a,b,c;

  155.         while(--ms)
  156.         {
  157.             for(c=1;c>0;c--)
  158.                 for(b=142;b>0;b--)
  159.                     for(a=2;a>0;a--);       
  160.         }
  161. }



  162. /* 計算測距 */
  163. void count(void)
  164. {
  165.         StartModule();        //啟動一次超聲波
  166.         while(!Echo);                //等待超聲波模塊輸出IO拉高
  167.         TR0 = 1;                        //開啟定時器計時
  168.         while(Echo);                //等待超聲波模塊輸出IO拉低
  169.         TR0 = 0;                         //關閉定時器計時
  170.        
  171.         /* 計算距離 */
  172.         time = TH0 * 256 + TL0;        //得到的時間,專業寫法應該是這樣:time = TH0 << 8 | TL0
  173.         TH0 = 0;                                //定時計數器清零       
  174.         TL0 = 0;
  175.        
  176.         S = (time * 1.7) / 100; //算出來是M                               
  177. }
  178. /* 顯示距離 */
  179. void dis_distance(void)
  180. {
  181.         dis_buf[3] = 0x00;
  182.         dis_buf[2] = duan_ma[S / 100 %10];         //取出百位數,并在數碼管的第3位顯示,從右往左數
  183.         dis_buf[1] = duan_ma[S / 10 %10];        //取出十位數,并在數碼管的第2位顯示,從右往左數
  184.         dis_buf[0] = duan_ma[S % 10];                 //取出個位數,并在數碼管的第1位顯示,從右往左數       
  185. }
  186. /* 設置報警功能 */
  187. void key_fuction(void)
  188. {
  189.         unsigned char mode_flag = 1;        //模式切換標記位,1:設置上限值,2:設置下限值,3:退出

  190.         while(1)
  191.         {
  192.                 if(key_scan() == 1)       
  193.                 {
  194.                         BEEP = 0;                        //按鍵提示音
  195.                         delayms(50);
  196.                         BEEP = 1;
  197.                         delayms(1000);
  198.                         ++mode_flag;
  199.                         if(mode_flag >= 3)        //如果滿3了,則退出
  200.                                 break;               
  201.                 }
  202.                 if(key_scan() == 2)                //如果加鍵按下
  203.                 {
  204.                         BEEP = 0;                        //按鍵提示音
  205.                         delayms(50);
  206.                         BEEP = 1;
  207.                         delayms(1000);
  208.                         if(mode_flag == 1)        //設置上限值
  209.                         {
  210.                                 ++S_H;
  211.                                 if(S_H > 400)
  212.                                         S_H = 2;       
  213.                         }
  214.                         if(mode_flag == 2)        //設置下限值
  215.                         {
  216.                                 ++S_L;
  217.                                 if(S_L > 400)
  218.                                         S_L = 2;       
  219.                         }
  220.                 }
  221.                 if(key_scan() == 3)                //如果減鍵按下
  222.                 {
  223.                         BEEP = 0;                        //按鍵提示音
  224.                         delayms(50);
  225.                         BEEP = 1;
  226.                         delayms(1000);
  227.                         if(mode_flag == 1)        //設置上限值
  228.                         {
  229.                                 --S_H;
  230.                                 if(S_H < 2)
  231.                                         S_H = 400;       
  232.                         }
  233.                         if(mode_flag == 2)        //設置下限值
  234.                         {
  235.                                 --S_L;
  236.                                 if(S_L < 2)
  237.                                         S_L = 400;       
  238.                         }
  239.                 }

  240.                 /* 報警設置顯示 */
  241.                 if(mode_flag == 1)         //顯示設置上限值內容
  242.                 {
  243.                         dis_buf[3] = 0x76;                                                //第4位數碼管顯示字母 H
  244.                         dis_buf[2] = duan_ma[S_H / 100 % 10];         //顯示百位數
  245.                         dis_buf[1] = duan_ma[S_H / 10 % 10];        //顯示十位數
  246.                         dis_buf[0] = duan_ma[S_H % 10];                        //顯示個位數
  247.                 }
  248.                 if(mode_flag == 2)                 //顯示設置下限值內容
  249.                 {
  250.                         dis_buf[3] = 0x38;        //第4位數碼管顯示字母 L
  251.                         dis_buf[2] = duan_ma[S_L / 100 % 10];         //顯示百位數
  252.                         dis_buf[1] = duan_ma[S_L / 10 % 10];        //顯示十位數
  253.                         dis_buf[0] = duan_ma[S_L % 10];                        //顯示個位數
  254.                 }               
  255.         }
  256. }

  257. /* 主函數 */
  258. void main(void)
  259. {
  260.         digDuan = 0x40;                //顯示"----"
  261.         digWei1 = 0;
  262.         digWei2 = 0;
  263.         digWei3 = 0;
  264.         digWei4 = 0;
  265.         delayms(1000);                //延時大約1s
  266.         InitTimer0();                //定時器0初始化

  267.         while(1)
  268.         {
  269.                 count();                                        //計算距離
  270.                 if(S>=S_H || S<=S_L)                //如果超出設定的范圍,則顯示"---"
  271.                 {
  272.                         dis_buf[3] = 0x00;
  273.                         dis_buf[2] = 0x40;                 //顯示"---"
  274.                         dis_buf[1] = 0x40;
  275.                         dis_buf[0] = 0x40;       
  276.                         BEEP = 0;                        //蜂鳴器鳴叫
  277.                         delayms(1000);
  278.                 }
  279.                 else
  280.                 {
  281.                         BEEP = 1;                        //關閉蜂鳴器
  282.                         dis_distance();                //顯示距離
  283.                 }

  284.                 if(key_scan() == 1)                //如果按下設置鍵,則進入設置報警功能
  285.                 {
  286.                         BEEP = 0;                        //按鍵提示音
  287.                         delayms(50);
  288.                         BEEP = 1;
  289.                         delayms(100);
  290.                          key_fuction();                //進入設置報警功能
  291.                 }                       
  292.         }
  293. }


  294. /* 定時器0中斷服務函數,5ms進一次本中斷,用于數碼管掃描 */
  295. void Timer1Interrupt(void) interrupt 3
  296. {
  297.                 TH1 = 0x0EC;                //定時5ms,重新賦值
  298.     TL1 = 0x78;

  299.                 dig_scan(dis_buf);        //數碼管顯示距離
  300. }


復制代碼

Proteus8.17仿真程序: 單片機超聲波.zip (149.3 KB, 下載次數: 0)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:102963 發表于 2025-1-6 12:18 | 只看該作者
這是51單片機,不是STM32單片機。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一在线 | 午夜精品一区 | 国产精品久久久久一区二区三区 | 久久久久久综合 | 久久精品欧美一区二区三区麻豆 | 欧美性久久久 | 91久久久久 | 99久久99| 综合久久综合久久 | 国产伊人精品 | 精品欧美一区二区久久久伦 | 一级看片免费视频 | 亚洲理论在线观看电影 | 亚洲午夜精品一区二区三区他趣 | 精品人伦一区二区三区蜜桃网站 | 国产精品久久一区二区三区 | 国产成人精品一区二区三区在线观看 | 久久综合久久综合久久综合 | 91福利影院| 亚洲高清视频在线观看 | 久久夜色精品国产 | 日韩二三区 | 日韩欧美视频在线 | 国产午夜久久久 | 久久久精品综合 | 成人影院一区二区三区 | 久久久久久高潮国产精品视 | 精品国产乱码久久久久久a丨 | 免费视频一区二区三区在线观看 | 综合国产| 亚洲在线免费观看 | 欧美一区二区三区高清视频 | 99热这里都是精品 | 久久久精品 | 欧美二区在线 | 欧美中文字幕一区 | 一级二级三级在线观看 | 91久久国产综合久久 | 91久久北条麻妃一区二区三区 | 午夜免费福利片 | 精品毛片|