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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

超聲波測距模塊和語音模塊同時使用,但是2個單片機定時器問題解決不了,求大神指教

[復制鏈接]
跳轉到指定樓層
樓主
ID:291819 發表于 2018-9-19 21:34 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include <REG52.h>       //調用51單片機的頭文件
  2. #include <intrins.h>
  3. #include <math.h>
  4. #include <string.h>
  5. //---------------------------------------
  6. //1602液晶相關I/O設置
  7. sbit E=P0^5;               //1602液晶的E腳接在P2.3口上
  8. sbit RW=P0^6;              //1602液晶的RW腳接在P2.4口上
  9. sbit RS=P0^7;              //1602液晶的RS腳接在P2.5口上
  10. //---------------------------------------
  11. //---------------------------------------
  12. //HC-SR04相關I/O設置
  13. sbit TIRG=P3^4;                   //定義IO口,具體可以去查看原理圖
  14. sbit ECHO=P3^2;                   //定義IO口,具體可以去查看原理圖        
  15. //---------------------------------------
  16. sbit mang= P0^7;
  17. unsigned long BJS=50;//報警距離50CM
  18. //unsigned char disbuff[4]           ={0,0,0,0};
  19. //unsigned char disbuff_BJ[4]        ={0,0,0,0};//報警信息
  20. unsigned int  time=0;
  21. bit      flag =0;
  22. unsigned char k;
  23. //名稱:1602液晶用延時函數
  24. void Delay1602(unsigned int t)
  25. {
  26.      unsigned int k;      //定義一個16位寄存器用來做延時用
  27.      for(k=0;k<t;k++);    //延時
  28. }

  29. //名稱:1602液晶忙檢測函數
  30. void LCD1602_busy(void)
  31. {
  32.      mang=1;              //將P0.7置1,為讀狀態做準備
  33.      RS=0;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
  34.      RW=1;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
  35.      E=1;                 //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
  36.      while(mang==1);      //由P0.7讀入1,表示1602液晶忙,需要等待
  37.      E=0;                 //讀完以后,恢復E的電平
  38. }

  39. //名稱:1600寫命令函數
  40. void LCD1602_Write_com(unsigned char combuf)
  41. {
  42.      RS=0;                //選擇指令寄存器
  43.      RW=0;                //選擇寫狀態
  44.      P2=combuf;           //將命令字通過P0口送至DB
  45.      E=1;                 //E高電平將命令字寫入1602液晶
  46.      E=0;                 //寫完以后,恢復E的電平
  47. }

  48. //名稱:1602寫命令函數(帶忙檢測)
  49. void LCD1602_Write_com_busy(unsigned char combuf)
  50. {
  51.      LCD1602_busy();            //調用忙檢測函數
  52.      LCD1602_Write_com(combuf); //調用忙檢測函數
  53. }

  54. //名稱:1602寫數據函數(帶忙檢測)
  55. void LCD1602_Write_data_busy(unsigned char databuf)
  56. {
  57.      LCD1602_busy();      //調用忙檢測函數
  58.      RS=1;                //選擇數據寄存器
  59.      RW=0;                //選擇寫狀態
  60.      P2=databuf;          //將命令字通過P0口送至DB
  61.      E=1;                 //E高電平將命令字寫入1602液晶
  62.      E=0;                 //寫完以后,恢復E的電平
  63. }

  64. //名稱:1602液晶顯示地址寫函數
  65. void LCD1602_Write_address(unsigned char x,unsigned char y)
  66. {
  67.      x&=0x0f;             //列地址限制在0-15間
  68.      y&=0x01;             //行地址限制在0-1間
  69.      if(y==0)             //如果是第一行
  70.          LCD1602_Write_com_busy(x|0x80);        //將列地址寫入
  71.      else                 //如果是第二行
  72.          LCD1602_Write_com_busy((x+0x40)|0x80); //將列地址寫入
  73. }


  74. //名稱:1602液晶初始化函數
  75. void LCD1602_init(void)
  76. {
  77.      Delay1602(1500);               //調用延時函數
  78.      LCD1602_Write_com(0x38);       //8位數據總線,兩行顯示模式,5*7點陣顯示
  79.      Delay1602(500);                //調用延時函數
  80.      LCD1602_Write_com(0x38);       //8位數據總線,兩行顯示模式,5*7點陣顯示
  81.      Delay1602(500);                //調用延時函數
  82.      LCD1602_Write_com(0x38);       //8位數據總線,兩行顯示模式,5*7點陣顯示
  83.      LCD1602_Write_com_busy(0x38);  //8位數據總線,兩行顯示模式,5*7點陣顯示
  84.      LCD1602_Write_com_busy(0x08);  //顯示功能關,無光標
  85.      LCD1602_Write_com_busy(0x01);  //清屏
  86.      LCD1602_Write_com_busy(0x06);  //寫入新的數據后,光標右移,顯示屏不移動
  87.      LCD1602_Write_com_busy(0x0C);  //顯示功能開,無光標
  88. }
  89. void chuankou()
  90. {
  91.           //    串口的初始化
  92.          TL1 = 0xFA;        // 在11.0592MHz 下,設置波特率9600bps,工作方式2
  93.          TH1 = 0xFA;              
  94.         TMOD|=0x21;
  95.                 TMOD = 0x21;
  96.                SCON = 0x50;       // 串口工作方式1,允許接收
  97.          PCON = 0x80;
  98.          EA  = 0;
  99.          REN = 1;
  100.          TI = 0;            //發送中斷標志位置零
  101.          RI = 0;            //接收中斷標志位置零
  102.          TR1 = 1;           //定時器1 用作波特率發生

  103. }


  104. //名稱:1602液晶指定地址顯示函數
  105. void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
  106. {
  107.      LCD1602_Write_address(x,y);    //先將地址信息寫入
  108.      LCD1602_Write_data_busy(buf);  //再寫入要顯示的數據
  109. }

  110. //名稱:定時器0中斷服務程序
  111. void Timer0(void) interrupt 1
  112. {                       
  113.    //
  114.         flag=0;
  115.                  
  116.    //******************************************
  117. }

  118. void yuyin()
  119. {
  120.          //需要發送的文本
  121.                  char code text[] =  {"觀看時間太長了!"};
  122.                  unsigned  char  headOfFrame[5];
  123.          unsigned  char  length;  
  124.                  unsigned  char  ecc  = 0;                          //定義校驗字節
  125.              unsigned  int i=0;
  126.                  length =sizeof(text);                         //需要發送文本的長度
  127.                  chuankou();
  128.         //發送過程/           
  129.                  headOfFrame[0] = 0xFD ;                         //構造幀頭FD
  130.                  headOfFrame[1] = 0x00 ;                         //構造數據區長度的高字節
  131.                  headOfFrame[2] = length + 3;                 //構造數據區長度的低字節
  132.                  headOfFrame[3] = 0x01 ;                         //構造命令字:合成播放命令
  133.        //帶背景音樂                  
  134.             // headOfFrame[4] = 0x21 ;                         //構造命令參數:編碼格式為GBK

  135.       //不帶背景音樂                  
  136.                 headOfFrame[4] = 0x01 ;                         //構造命令參數:編碼格式為GBK

  137.                  for(i = 0; i<5; i++)                                   //依次發送構造好的5個幀頭字節
  138.              {  
  139.                  ecc=ecc^(headOfFrame[i]);                 //對發送的字節進行異或校驗        
  140.                  SBUF = headOfFrame[i];
  141.                  while (TI== 0) {;}                           //等待發送中斷標志位置位
  142.                  TI = 0;                                                 //發送中斷標志位清零
  143.              }

  144.                     for(i = 0; i<length; i++)                   //依次發送待合成的文本數據
  145.              {  
  146.                  ecc=ecc^(text[i]);                                 //對發送的字節進行異或校驗        
  147.                  SBUF = text[i];
  148.                  while (TI== 0) {;}
  149.                  TI = 0;                                 
  150.              }
  151.                    SBUF=ecc;                                                        //最后發送校驗字節
  152.                    while (TI== 0) {;}
  153.                 TI=0;         
  154.                   while(1);
  155. }

  156. void main(void)            //主函數,單片機開機后就是從這個函數開始運行
  157. {
  158.         long S;
  159.         unsigned int i;
  160.         unsigned int  Timeout;
  161.     LCD1602_init();        //調用1602液晶初始化函數
  162.         //***定時器Timer0初始化***
  163.    TMOD&=0xF0;                    //將TMOD的低4位定時器0控制部分清零
  164.    TMOD|=0x01;                    //設置定時器0為方式1
  165.    TMOD=0x01;
  166.    TL0=0;                              //設置定時器0初值低8位
  167.    TH0=0;                              //設置定時器0初值高8位
  168.    TR0=0;                         //停止定時器0
  169.    ET0=1;                         //Timer0中斷允許
  170.    //**********************
  171.    //***開全局中斷設置****
  172.    //定時器Timer0設置了中斷允許,此處要開全局中斷
  173.    EA=1;                          //開全局中斷
  174.   // ES=1;
  175.    //*********************
  176.         while(1)
  177.         {               
  178.                 TIRG=1;                                             //發一個脈沖觸發信號
  179.                   i=4;                                             //維持約17US,符合不低于10US的要求
  180.       while(i>0)                                  //維持約17US,符合不低于10US的要求
  181.               i--;                                     //維持約17US,符合不低于10US的要求               
  182.                   TIRG=0;                                             //撤銷觸發信號
  183.                 TR0=0;                                                //關閉定時器
  184.                 TL0=0;                             //設置定時器0初值低8位為0
  185.              TH0=0;                              //設置定時器0初值高8位為0
  186.                 k=0;                         //清除溢出標志
  187.                 flag=0;
  188.                 Timeout=0;
  189.            while((ECHO==0)&&((Timeout++)<50000));                                //等待回響高電平               
  190.            TR0=1;                                            //回響高電平來后啟動定時器
  191.                 Timeout=0;
  192.            while((ECHO==1)&&((Timeout++)<50000));                                //等待回響高電平結束后
  193.            TR0=0;                                                //關閉定時器
  194.       S=((TH0*256+TL0)*1.7)/100;
  195.           if(S<=50)
  196.           {
  197.                  yuyin();
  198.           }        
  199.                 if(flag==1||S>400)                //超出測量范圍顯示“-”
  200.                 {                                                         
  201.                            LCD1602_Disp(0, 0, '-');                                  //顯示百位-
  202.                            LCD1602_Disp(1, 0, '-');                                  //顯示十位-
  203.                            LCD1602_Disp(2, 0, '-');                                  //顯示個位-
  204.                            LCD1602_Disp(3, 0, 'C');                                  //顯示C
  205.                            LCD1602_Disp(4, 0, 'M');                                //顯示M
  206.                 }
  207.                 else                                                                  
  208.                 {         
  209.                         if(S<=50){
  210.                         //yuyin();               
  211.                         LCD1602_Disp(0, 0, S%1000/100+'0');                  //顯示百位
  212.                            LCD1602_Disp(1, 0, S%1000%100/10+'0');  //顯示十位
  213.                            LCD1602_Disp(2, 0, S%1000%100%10+'0');        //顯示個位
  214.                            LCD1602_Disp(3, 0, 'C');                                          //顯示C
  215.                            LCD1602_Disp(4, 0, 'M');                                        //顯示M
  216.                     
  217.                         }
  218.                 }
  219.                 i=18000;                                          //維持約77400US,符合不低于60MS的要求
  220.       while(i>0)                                  //維持約77400US,符合不低于60MS的要求
  221.               i--;                                     //維持約77400US,符合不低于60MS的要求

  222.         }
  223. }

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

使用道具 舉報

沙發
ID:291819 發表于 2018-9-19 21:37 | 只看該作者
超聲波測距功能與語音模塊單獨分開都能實現功能,放在一起就什么功能不能實現,我知道用到了倆個定時器,但就是這倆個定時器程序不太會
回復

使用道具 舉報

板凳
ID:303383 發表于 2018-9-20 09:18 | 只看該作者
提示: 作者被禁止或刪除 內容自動屏蔽
回復

使用道具 舉報

地板
ID:387733 發表于 2018-9-20 17:21 | 只看該作者
函數“chuankou()”中 EA=0; 把全局中斷關閉了,這樣調用一次以后,就不會再有中斷了,這里沒必要關閉全局中斷的。
把 EA=0;去掉應該就可以了。
回復

使用道具 舉報

5#
ID:291819 發表于 2018-9-27 16:19 | 只看該作者
sxhwdz 發表于 2018-9-20 17:21
函數“chuankou()”中 EA=0; 把全局中斷關閉了,這樣調用一次以后,就不會再有中斷了,這里沒必要關閉全 ...

把EA=0去掉也不行
回復

使用道具 舉報

6#
ID:291819 發表于 2018-9-27 16:20 | 只看該作者
小貓貓愛吃魚 發表于 2018-9-20 09:18
你好!兩次定時器的使用出現了沖突,要重新寫一部分程序了。。。

是不是需要寫這倆個定時器的中斷優先級程序
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧美日韩精品久久亚洲区 | 美女天堂在线 | 欧美午夜在线 | av在线免费观看网址 | 欧美二区三区 | 亚洲二区精品 | 久久久不卡网国产精品一区 | 91精品一区 | 亚洲综合大片69999 | 精品99爱视频在线观看 | 91亚洲欧美 | 毛片毛片毛片毛片毛片 | 免费久久精品 | 欧美中文在线 | 日韩在线免费视频 | 天天干狠狠操 | 久久99精品久久 | 国产在线精品一区二区 | 国产成人精品免高潮在线观看 | 欧美a√ | 古典武侠第一页久久777 | 亚洲精品久久国产高清情趣图文 | www.男人天堂.com | 一区视频 | av香港经典三级级 在线 | 国产精品免费观看 | 午夜视频一区二区 | 午夜国产精品视频 | 欧美xxxⅹ性欧美大片 | 欧美一区二区三区在线 | 亚洲国产日韩一区 | 欧美日韩亚洲视频 | 欧美激情一区二区三区 | 免费99精品国产自在在线 | 少妇一级淫片aaaaaaaaa | 日本免费黄色一级片 | 在线欧美一区 | 一区二区三区视频在线观看 | 国产探花在线精品一区二区 | 日韩视频免费 | 日韩在线不卡 |