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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

超聲波測距儀原理圖和單片機程序

[復制鏈接]
跳轉到指定樓層
樓主


原理圖下載:
PDF格式 模塊超聲波測距儀.pdf (123.7 KB, 下載次數: 11)

  1. #include <reg51.h>         
  2. #define uchar unsigned char  
  3. #define uint  unsigned int  
  4. #include <intrins.h>

  5. //數碼管段選定義      0     1    2    3    4    5 6  7   8    9
  6. uchar code smg_du[]={0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,0x20,0xa0,
  7.         0x60,0x25,0x39,0x26,0x31,0x71,0xff};  //斷碼

  8. uchar dis_smg[8]   ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
  9. //數碼管位選定義
  10. sbit smg_we1 = P3^4;     //數碼管位選定義
  11. sbit smg_we2 = P3^5;
  12. sbit smg_we3 = P3^6;
  13. sbit smg_we4 = P3^7;
  14. uint code wendu_buchang1[46] = {       //溫度補償表格
  15. 331,332,333,333,334,334,335,336,336,337, // 0-9度
  16. 337,338,339,339,340,341,341,342,342,343, //10-19度
  17. 343,344,345,345,346,346,347,348,348,349, //20-29度
  18. 349,350,351,351,352,352,353,354,354,355, //30-39度
  19. 355,356,357,357,358,358      //40-45度
  20. };

  21. sbit dq   = P2^4; //18b20 IO口的定義
  22. uint temperature ;  //

  23. sbit c_send   = P3^2;  //超聲波發射
  24. sbit c_recive = P3^3;  //超聲波接收
  25. sbit beep = P2^3;   //蜂鳴器IO口定義
  26. uchar smg_i = 3;    //顯示數碼管的個位數
  27. bit flag_300ms ;
  28. long distance;         //距離
  29. uint set_d;             //距離
  30. uchar flag_csb_juli;    //超聲波超出量程
  31. uint  flag_time0;       //用來保存定時器0的時候的
  32. uchar menu_1;           //菜單設計的變量
  33. /*sfr WDT_CONTR=0xe1;*/   //看門狗(watch-dog-Timer)控制器

  34. /***********************小延時函數*****************************/
  35. void delay_uint(uint q)
  36. {
  37. while(q--);
  38. }

  39. /***********************1ms延時函數*****************************/
  40. void delay_1ms(uint q)
  41. {
  42. uint i,j;
  43. for(i=0;i<q;i++)
  44.   for(j=0;j<120;j++);
  45. }
  46. /***********************處理距離函數****************************/
  47. void smg_display()
  48. {
  49. dis_smg[0] = smg_du[distance % 10];
  50. dis_smg[1] = smg_du[distance / 10 % 10];
  51. dis_smg[2] = smg_du[distance / 100 % 10] & 0xdf; ;
  52. }
  53. /********************獨立按鍵程序*****************/
  54. uchar key_can;  //按鍵值
  55. void key()  //獨立按鍵程序
  56. {
  57. static uchar key_new;
  58. key_can = 20;                   //按鍵值還原
  59. P2 |= 0x07;
  60. if((P2 & 0x07) != 0x07)  //按鍵按下
  61. {
  62.   delay_1ms(1);       //按鍵消抖動
  63.   if(((P2 & 0x07) != 0x07) && (key_new == 1))
  64.   {      //確認是按鍵按下
  65.    key_new = 0;
  66.    switch(P2 & 0x07)
  67.    {
  68.     case 0x06: key_can = 3; break;    //得到k2鍵值
  69.     case 0x05: key_can = 2; break;    //得到k3鍵值
  70.     case 0x03: key_can = 1; break;    //得到k4鍵值
  71.    }
  72.   }   
  73. }
  74. else
  75.   key_new = 1;
  76. }
  77. /****************按鍵處理顯示函數***************/
  78. void key_with()
  79. {
  80. if(key_can == 1)  //設置鍵
  81. {
  82.   menu_1 ++;
  83.   if(menu_1 >= 3)
  84.   {
  85.    menu_1 = 0;
  86.    smg_i = 3;  //只顯示3位數碼管
  87.   }
  88.   if(menu_1 == 1)
  89.   {
  90.    smg_i = 4;    //只顯示4位數碼管
  91.   }
  92. }
  93. if(menu_1 == 1)   //設置報警
  94. {
  95.   if(key_can == 2)
  96.   {
  97.    set_d ++ ;  //加1
  98.    if(set_d > 400)
  99.     set_d = 400;
  100.   }
  101.   if(key_can == 3)
  102.   {
  103.    set_d -- ;  //減1
  104.    if(set_d <= 1)
  105.     set_d = 1;
  106.   }
  107.   dis_smg[0] = smg_du[set_d % 10];            //取小數顯示
  108.   dis_smg[1] = smg_du[set_d / 10 % 10] ;         //取個位顯示
  109.   dis_smg[2] = smg_du[set_d / 100 % 10] & 0xdf ; //取十位顯示
  110.   dis_smg[3] = 0x60;         //a
  111. }
  112. }  
  113. /***********************18b20初始化函數*****************************/
  114. void init_18b20()
  115. {
  116. bit q;
  117. dq = 1;    //把總線拿高
  118. delay_uint(1);     //15us
  119. dq = 0;    //給復位脈沖
  120. delay_uint(80);  //750us
  121. dq = 1;    //把總線拿高 等待
  122. delay_uint(10);  //110us
  123. q = dq;    //讀取18b20初始化信號
  124. delay_uint(20);  //200us
  125. dq = 1;    //把總線拿高 釋放總線
  126. }
  127. /*************寫18b20內的數據***************/
  128. void write_18b20(uchar dat)
  129. {
  130. uchar i;
  131. for(i=0;i<8;i++)
  132. {      //寫數據是低位開始
  133.   dq = 0;    //把總線拿低寫時間隙開始
  134.   dq = dat & 0x01; //向18b20總線寫數據了
  135.   delay_uint(5);  // 60us
  136.   dq = 1;    //釋放總線
  137.   dat >>= 1;
  138. }
  139. }
  140. /*************讀取18b20內的數據***************/
  141. uchar read_18b20()
  142. {
  143. uchar i,value;
  144. for(i=0;i<8;i++)
  145. {
  146.   dq = 0;    //把總線拿低讀時間隙開始
  147.   value >>= 1;  //讀數據是低位開始
  148.   dq = 1;    //釋放總線
  149.   if(dq == 1)   //開始讀寫數據
  150.    value |= 0x80;
  151.   delay_uint(5);  //60us 讀一個時間隙最少要保持60us的時間
  152. }
  153. return value;   //返回數據
  154. }
  155. /*************讀取溫度的值 讀出來的是小數***************/
  156. uint read_temp()
  157. {
  158. uint value;
  159. uchar low;      //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序
  160. init_18b20();     //初始化18b20
  161. write_18b20(0xcc);    //跳過64位ROM
  162. write_18b20(0x44);    //啟動一次溫度轉換命令
  163. delay_uint(50);     //500us
  164. init_18b20();     //初始化18b20

  165. write_18b20(0xcc);    //跳過64位ROM
  166. write_18b20(0xbe);    //發出讀取暫存器命令

  167. EA = 0;
  168. low = read_18b20();    //讀溫度低字節
  169. value = read_18b20();  //讀溫度高字節
  170. EA = 1;
  171. value <<= 8;     //把溫度的高位左移8位
  172. value |= low;     //把讀出的溫度低位放到value的低八位中
  173. value *= 0.0625;        //轉換到溫度值
  174. return value;     //返回讀出的溫度
  175. }

  176. /****************報警函數***************/
  177. void clock_h_l()
  178. {
  179. static uchar value;
  180. if(distance <= set_d)
  181. {
  182.   value ++;  //消除實際距離在設定距離左右變化時的干擾
  183.   if(value >= 2)
  184.   {
  185.    beep = ~beep;    //蜂鳴器報警
  186.   }
  187. }
  188. else
  189. {
  190.   value = 0;
  191.   beep = 1;  //取消報警
  192. }
  193. }
  194. /***********************數碼位選函數*****************************/
  195. void smg_we_switch(uchar i)
  196. {
  197. switch(i)
  198. {
  199.   case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  200.   case 1: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  201.   case 2: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  202.   case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  203. }
  204. }
  205. /***********************數碼顯示函數*****************************/
  206. void display()
  207. {
  208. static uchar i;   
  209. i++;
  210. if(i >= smg_i)
  211.   i = 0;
  212. smg_we_switch(i);   //位選
  213. P1 = dis_smg[i];   //段選         
  214. }
  215. /******************小延時函數*****************/
  216. void delay()
  217. {
  218. _nop_();              //執行一條_nop_()指令就是1us
  219. _nop_();
  220. _nop_();
  221. _nop_();
  222. _nop_();
  223. _nop_();
  224. _nop_();
  225. _nop_();
  226. _nop_();  
  227. _nop_();
  228. }

  229. /*********************超聲波測距程序*****************************/
  230. void send_wave()
  231. {
  232. c_send = 1;             //10us的高電平觸發
  233. delay();
  234. c_send = 0;  
  235. TH0 = 0;            //給定時器0清零
  236. TL0 = 0;
  237. TR0 = 0;      //關定時器0定時
  238. while(c_recive);    //當c_recive為1等待
  239. TR0=1;
  240. while(!c_recive)        //當c_recive為0等待
  241. {
  242.   flag_time0 = TH0 * 256 + TL0;
  243.   if((flag_time0 > 40000))      //當超聲波超過測量范圍時,顯示3個888
  244.   {
  245.    TR0 = 0;
  246.    flag_csb_juli = 2;
  247.    distance = 888;
  248.    break ;  
  249.   }
  250.   else
  251.   {
  252.    flag_csb_juli = 1;
  253.   }
  254. }
  255. if(flag_csb_juli == 1)
  256. {
  257.   TR0=0;        //關定時器0定時
  258.   distance =flag_time0;    //讀出定時器0的時間
  259.   if(temperature <= 45)
  260.    distance *= wendu_buchang1[temperature] / 2.0 * 0.0001;               // 0.017 = 340M / 2 = 170M = 0.017M 算出來是米
  261.   else
  262.    distance *= 358 / 2.0 * 0.0001;         // 0.017 = 340M / 2 = 170M = 0.017M 算出來是米
  263.   if((distance > 500))     //距離 = 速度 * 時間
  264.   {
  265.    distance = 888;     //如果大于5.0m就超出超聲波的量程
  266.   }
  267. }  
  268. }

  269. /*********************定時器0、定時器1初始化******************/
  270. void time_init()   
  271. {
  272. EA  = 1;     //開總中斷
  273. TMOD = 0X11;   //定時器0、定時器1工作方式1
  274. ET0 = 0;    //關定時器0中斷
  275. TR0 = 1;    //允許定時器0定時
  276. ET1 = 1;    //開定時器1中斷
  277. TR1 = 1;    //允許定時器1定時
  278. }

  279. /***************主函數*****************/
  280. void main()
  281. {
  282. beep = 0;   //開機叫一聲   
  283. delay_1ms(150);
  284. P0 = P1 = P2 = P3 = 0xff;    //初始化單片機IO口為高電平
  285. time_init(); //定時器初始化程序
  286.     init_18b20();

  287. /*send_wave();
  288. smg_display(); //處理距離顯示函數
  289. /*time_init(); //定時器初始化程序
  290. send_wave(); //測距離函數
  291. send_wave();*/ //測距離函數
  292. do
  293. {   
  294.   if(flag_300ms == 0)
  295.   {  
  296.    flag_300ms = 0;
  297.    clock_h_l();    //報警函數
  298.    temperature = read_temp(); //先讀出溫度的值
  299.    if(beep == 1)
  300.     send_wave(); //測距離函數
  301.    if(menu_1 == 0)
  302.     smg_display();  //處理距離顯示函數
  303.    if(menu_1 == 2)   //顯示溫度   
  304.    {
  305.     dis_smg[0] = 0xf0;  
  306.     dis_smg[1] = smg_du[temperature % 10];             //取溫度的個位顯示
  307.     dis_smg[2] = smg_du[temperature / 10 % 10] ;    //取溫度的十位顯示  
  308.     dis_smg[3] = 0xFF;
  309.     smg_display();
  310.    }
  311.   }
  312.   key();      //按鍵函數
  313.   if(key_can < 10)
  314.   {
  315.    key_with();    //按鍵處理函數
  316.   }
  317. }while(1);
  318. }
  319. /*********************定時器1中斷服務程序************************/
  320. void time1_int() interrupt 3
  321. {
  322. static uchar value;    //定時2ms中斷一次
  323. TH1 = 0xf8;
  324. TL1 = 0x30;     //2ms
  325. display();  //數碼管顯示函數
  326. value++;
  327. if(value >= 150)
  328. {
  329.   value = 0;
  330.   flag_300ms = 1;
  331. }
  332. }
復制代碼


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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91人人在线 | 亚洲综合视频一区 | 网站黄色在线免费观看 | 亚洲91| 黄色免费av | 欧美日韩亚 | 久久久久久久综合 | 午夜精品一区二区三区免费视频 | 日韩在线中文字幕 | 国产精品久久久久一区二区三区 | 亚洲精品一区二区三区四区高清 | 国产日韩一区二区三区 | 99久久夜色精品国产亚洲96 | 天天av天天好逼 | 一区二区三区视频在线免费观看 | 久色激情| 99久久精品免费视频 | 国产精品久久久久久久久久久久久 | 午夜丁香视频在线观看 | 国产精品久久久久久久久免费樱桃 | 欧美福利 | 国产精品久久久久aaaa樱花 | 91精品国产一区二区三区 | 久久精品欧美一区二区三区不卡 | 深夜福利影院 | 日韩三级在线 | 国产精品久久国产愉拍 | 久久精品亚洲精品国产欧美 | 免费在线观看成人av | 中文字幕在线观看精品 | 日本免费一区二区三区 | 久久久精品国产 | 日韩精品一区二区三区老鸭窝 | 国产剧情一区 | 欧美国产一区二区三区 | 国产精品久久久久久久久免费 | 免费观看黄色一级片 | 国产高清区 | 成人亚洲精品久久久久软件 | 亚洲一区二区成人 | 久久a久久 |