找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3975|回復: 11
收起左側(cè)

關于單片機溫度采集串口中斷的問題?

[復制鏈接]
ID:284106 發(fā)表于 2018-4-8 20:47 | 顯示全部樓層 |閱讀模式
在用STC89C52單片機做一個溫度采集功能。
功能是這樣的:
      1、工作頻率 11.0592
      2、P2.0,P2.1,P2.2,P2.3 普通IO口分別接了四個S18B20溫度傳感器,用來采集溫度。
      3、RX,TX分別和電腦的串口連好,實現(xiàn)和電腦通訊
      4、電腦串口定時發(fā)送定義好的查詢幀,單片機串口收到后,判斷幀的內(nèi)容,查詢溫度,并返回溫度數(shù)據(jù)。
      5、功能己經(jīng)實現(xiàn),這樣運行的也沒有問題。

現(xiàn)在的操作方式是被動操作,(也就是電腦發(fā)送一幀數(shù)據(jù),單片機查詢一次溫度,并返回)流程如下:
   1,電腦串口發(fā)送定義好的16字數(shù)據(jù) --->2、單片機串口收到數(shù)據(jù),根據(jù)數(shù)據(jù)的類型,查詢S18B20溫度傳感器溫度---->3,單片機將溫度數(shù)據(jù)再編碼成16個字節(jié)數(shù)據(jù)發(fā)送給電腦串口---->4,電腦串口收到數(shù)據(jù)后處理并顯示


存在一個問題是:
現(xiàn)在我想在單片機上裝一個顯示屏,讓單片機定時不斷查詢溫度并顯示在屏幕上。
但是單片機在進行S18B20查詢溫度是很講究時序的,在1602顯示屏上顯示文字,也是講究時序的。
問題:單片機正在對S18B20查詢溫度時(IO口電平拉高,或拉底),這時有串口數(shù)據(jù)來到,會中斷當前的操作,直到中斷函數(shù)執(zhí)行完畢。這時查詢S18B20的操作時序就不準確了,1602顯示屏也一樣。

問:有串口數(shù)據(jù)來到要接收,不能丟棄。對S18B20操作到一半時,也不能中斷,不然時序可能不準確。這樣怎么處理?有什么兩全其美的方法嗎?

電路圖:
2.jpg


單片機源碼
  1. #include  "config.h"
  2. #include<ds1.h>
  3. #include<ds2.h>
  4. #include<ds3.h>
  5. #include<ds4.h>

  6. void UART_init();
  7. void PutFrame(uchar *TXStr);
  8. void DataFrame_Put_init();
  9. void TEMP_init_var();

  10. uchar dataFrame[16];            //定義數(shù)據(jù)幀長度為16個字節(jié)
  11. uchar dataFrame_RI;             //數(shù)據(jù)幀是否己讀取標記

  12. uchar dataFrame_temp[16];            //數(shù)據(jù)幀臨時緩沖區(qū)16個字節(jié)
  13. uchar dataFrame_temp_count;     //定義數(shù)據(jù)幀己接收的字節(jié)數(shù)

  14. //定義發(fā)送數(shù)據(jù)緩沖區(qū)
  15. uchar DataFrame_Put[16]={DATAFRAME_HEAD,DEVICEID_1,DEVICEID_2,0,0,0,0,0,0,0,0,0,0,0,0,DATAFRAME_TAIL};

  16. INT32U led1_count;         //運行指示燈倒計時變量
  17. uchar led1_count2;         //運行指示燈倒計時變量2
  18. INT32U led2_count;         //收到心跳倒計時變量
  19. INT32U led3_count;         //有數(shù)據(jù)接收倒計時變量
  20. INT32U led4_count;                   //有數(shù)據(jù)發(fā)送倒計時變量
  21. #define LED1_COUNT 15000
  22. #define LED2_COUNT 125000
  23. #define LED3_COUNT 100
  24. #define LED4_COUNT 100


  25. //存儲溫度的高8位和底8位
  26. uchar ds_M;
  27. uchar ds_L;
  28. //溫度變量
  29. uchar symbol;    //符號位
  30. uchar hundreds;  //百位
  31. uchar decade;    //十位
  32. uchar unit;      //個位
  33. uchar decimal;   //小數(shù)1位

  34. void main()
  35. {
  36.         //串口初始化
  37.         UART_init();

  38.         while(1)
  39.         {
  40.                 //調(diào)試使用
  41.                 //uchar dataFrame[16] = {DATAFRAME_HEAD,DEVICEID_1,DEVICEID_2,0,0,1,1,0,0,0,0,0,0,0,0,DATAFRAME_TAIL};
  42.                 //dataFrame_RI = 1;          //執(zhí)行時間2.17微妙

  43.                 //如果己接收到一幀數(shù)據(jù)
  44.                 if(dataFrame_RI == 1)        // 執(zhí)行時間5.42微秒
  45.                 {      
  46.                         //收到心跳
  47.                     if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 1){
  48.                            //收到心跳
  49.                            DataFrame_Put[3] = 0;
  50.                            DataFrame_Put[4] = 0;
  51.                            DataFrame_Put[5] = 0;
  52.                            DataFrame_Put[6] = 1;
  53.                            PutFrame(&DataFrame_Put);
  54.                            led2_count = LED2_COUNT;
  55.                         }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 2){
  56.                           //收到查詢設備id
  57.                            DataFrame_Put[3] = 1;
  58.                            DataFrame_Put[4] = 0;
  59.                            DataFrame_Put[5] = 0;
  60.                            DataFrame_Put[6] = 2;
  61.                            DataFrame_Put[7] = DEVICEID_1;
  62.                            DataFrame_Put[8] = DEVICEID_2;
  63.                            DataFrame_Put[9] = 255;
  64.                            DataFrame_Put[10] = 255;
  65.                            DataFrame_Put[11] = 255;
  66.                            DataFrame_Put[12] = 255;
  67.                            DataFrame_Put[13] = 002;
  68.                            DataFrame_Put[14] = 001;
  69.                            PutFrame(&DataFrame_Put);
  70.                            led3_count = LED3_COUNT;
  71.                            led4_count = LED4_COUNT;
  72.                         }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 9){
  73.                            //收到更新用戶信息時間,返回
  74.                            DataFrame_Put[3] = 1;
  75.                            DataFrame_Put[4] = 0;
  76.                            DataFrame_Put[5] = 0;
  77.                            DataFrame_Put[6] = 9;
  78.                            PutFrame(&DataFrame_Put);
  79.                            led3_count = LED3_COUNT;
  80.                            led4_count = LED4_COUNT;
  81.                     }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 1){         // 執(zhí)行時間15.19 微秒
  82.                            //查詢溫度1:0 0 1 1
  83.                            TEMP_init_var();
  84.                            DS1_ReadWeather(&ds_M,&ds_L);
  85.                            Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
  86.                            DataFrame_Put[3] = 1;
  87.                            DataFrame_Put[4] = 0;
  88.                            DataFrame_Put[5] = 1;
  89.                            DataFrame_Put[6] = 1;
  90.                            DataFrame_Put[7] = symbol;
  91.                            DataFrame_Put[8] = hundreds;
  92.                            DataFrame_Put[9] = decade;
  93.                            DataFrame_Put[10] = unit;
  94.                            DataFrame_Put[11] = decimal;
  95.                            PutFrame(&DataFrame_Put);
  96.                            led3_count = LED3_COUNT;
  97.                            led4_count = LED4_COUNT;
  98.                         }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 2){
  99.                            //查詢溫度2:0 0 1 2
  100.                            TEMP_init_var();
  101.                            DS2_ReadWeather(&ds_M,&ds_L);
  102.                            Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
  103.                            DataFrame_Put[3] = 1;
  104.                            DataFrame_Put[4] = 0;
  105.                            DataFrame_Put[5] = 1;
  106.                            DataFrame_Put[6] = 2;
  107.                            DataFrame_Put[7] = symbol;
  108.                            DataFrame_Put[8] = hundreds;
  109.                            DataFrame_Put[9] = decade;
  110.                            DataFrame_Put[10] = unit;
  111.                            DataFrame_Put[11] = decimal;
  112.                            PutFrame(&DataFrame_Put);
  113.                            led3_count = LED3_COUNT;
  114.                            led4_count = LED4_COUNT;
  115.                     }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 3){         // 執(zhí)行時間15.19 微秒
  116.                            //查詢溫度3:0 0 1 3
  117.                            TEMP_init_var();
  118.                            DS3_ReadWeather(&ds_M,&ds_L);
  119.                            Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
  120.                            DataFrame_Put[3] = 1;
  121.                            DataFrame_Put[4] = 0;
  122.                            DataFrame_Put[5] = 1;
  123.                            DataFrame_Put[6] = 3;
  124.                            DataFrame_Put[7] = symbol;
  125.                            DataFrame_Put[8] = hundreds;
  126.                            DataFrame_Put[9] = decade;
  127.                            DataFrame_Put[10] = unit;
  128.                            DataFrame_Put[11] = decimal;
  129.                            PutFrame(&DataFrame_Put);
  130.                            led3_count = LED3_COUNT;
  131.                            led4_count = LED4_COUNT;
  132.                     }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 4){
  133.                            //查詢溫度4:0 0 1 4
  134.                            TEMP_init_var();
  135.                            DS4_ReadWeather(&ds_M,&ds_L);
  136.                            Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
  137.                            DataFrame_Put[3] = 1;
  138.                            DataFrame_Put[4] = 0;
  139.                            DataFrame_Put[5] = 1;
  140.                            DataFrame_Put[6] = 4;
  141.                            DataFrame_Put[7] = symbol;
  142.                            DataFrame_Put[8] = hundreds;
  143.                            DataFrame_Put[9] = decade;
  144.                            DataFrame_Put[10] = unit;
  145.                            DataFrame_Put[11] = decimal;
  146.                            PutFrame(&DataFrame_Put);
  147.                            led3_count = LED3_COUNT;
  148.                            led4_count = LED4_COUNT;
  149.                     }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 1){
  150.                            //查詢開關1
  151.                            DataFrame_Put[3] = 1;
  152.                            DataFrame_Put[4] = 0;
  153.                            DataFrame_Put[5] = 2;
  154.                            DataFrame_Put[6] = 1;
  155.                           if(SW1 == 0){
  156.                            DataFrame_Put[7] = 1;         
  157.                           }else{
  158.                            DataFrame_Put[7] = 2;
  159.                           }
  160.                           PutFrame(&DataFrame_Put);
  161.                           led3_count = LED3_COUNT;
  162.                           led4_count = LED4_COUNT;
  163.                    }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 2){
  164.                            //查詢開關2
  165.                            DataFrame_Put[3] = 1;
  166.                            DataFrame_Put[4] = 0;
  167.                            DataFrame_Put[5] = 2;
  168.                            DataFrame_Put[6] = 2;
  169.                           if(SW2 == 0){
  170.                            DataFrame_Put[7] = 1;         
  171.                           }else{
  172.                            DataFrame_Put[7] = 2;
  173.                           }
  174.                           PutFrame(&DataFrame_Put);
  175.                           led3_count = LED3_COUNT;
  176.                           led4_count = LED4_COUNT;
  177.                     }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 3){
  178.                            //查詢開關3
  179.                            DataFrame_Put[3] = 1;
  180.                            DataFrame_Put[4] = 0;
  181.                            DataFrame_Put[5] = 2;
  182.                            DataFrame_Put[6] = 3;
  183.                            if(SW3 == 0){
  184.                              DataFrame_Put[7] = 1;         
  185.                            }else{
  186.                              DataFrame_Put[7] = 2;
  187.                            }
  188.                            PutFrame(&DataFrame_Put);
  189.                            led3_count = LED3_COUNT;
  190.                            led4_count = LED4_COUNT;
  191.                         }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 4){
  192.                            //查詢開關3
  193.                            DataFrame_Put[3] = 1;
  194.                            DataFrame_Put[4] = 0;
  195.                            DataFrame_Put[5] = 2;
  196.                            DataFrame_Put[6] = 4;
  197.                            if(SW4 == 0){
  198.                              DataFrame_Put[7] = 1;         
  199.                            }else{
  200.                              DataFrame_Put[7] = 2;
  201.                            }
  202.                            PutFrame(&DataFrame_Put);
  203.                            led3_count = LED3_COUNT;
  204.                            led4_count = LED4_COUNT;
  205.                         }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 1){
  206.                            //設置開關1
  207.                            if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  208.                                  SW1 = 0;
  209.                            }
  210.                            else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  211.                                    SW1 = 1;
  212.                            }
  213.                            led3_count = LED3_COUNT;
  214.                 }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 2){
  215.                            //設置開關2
  216.                            if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  217.                                  SW2 = 0;
  218.                            }
  219.                            else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  220.                                    SW2 = 1;
  221.                            }
  222.                            led3_count = LED3_COUNT;
  223.                     }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 3){
  224.                            //設置開關3
  225.                            if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  226.                                  SW3 = 0;
  227.                            }
  228.                            else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  229.                                    SW3 = 1;
  230.                            }
  231.                            led3_count = LED3_COUNT;
  232.                     }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 4){
  233.                            //設置開關4
  234.                            if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  235.                                  SW4 = 0;
  236.                            }
  237.                            else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
  238.                                    SW4 = 1;
  239.                            }
  240.                            led3_count = LED3_COUNT;
  241.                         }
  242.                         dataFrame_RI = 0;     //置數(shù)據(jù)幀己讀取
  243.                         DataFrame_Put_init(); //初始化發(fā)送幀,為下一次發(fā)送數(shù)據(jù)做準備
  244.                 }

  245.                 //LED1運行指示燈閃爍,整個循環(huán)在沒有接收數(shù)據(jù)時,執(zhí)行一次約40us
  246.                 if(led1_count > 0){
  247.                   led1_count--;
  248.                 }else{
  249.                   if(led1_count2 == 0){
  250.                     led1_count2 = 1;
  251.                   }else{
  252.                     led1_count2 = 0;
  253.                   }
  254.                   led1_count = LED1_COUNT;
  255.                 }
  256.                 if(led1_count > 0){
  257.                   if(led1_count2 == 0){
  258.                           LED1 = 0;
  259.                   }else{
  260.                     LED1 = 1;
  261.                   }
  262.                   led1_count--;                                    
  263.                 }

  264.                 //收到心跳燈亮20秒
  265.                 if(led2_count > 0){
  266.                   LED2 = 0;
  267.                   led2_count--;
  268.                 }else{
  269.                   LED2 = 1;
  270.                 }

  271.                 //有數(shù)據(jù)接收閃一下
  272.                 if(led3_count > 0){
  273.                   LED3 = 0;
  274.                   led3_count--;
  275.                 }else{
  276.                   LED3 = 1;
  277.                 }

  278.                 //有數(shù)據(jù)發(fā)送閃一下
  279.                 if(led4_count > 0){
  280.                   LED4 = 0;
  281.                   led4_count--;
  282.                 }else{
  283.                   LED4 = 1;
  284.                 }

  285.         }

  286.         while(1);
  287. }

  288. //初始化輸出幀
  289. void DataFrame_Put_init(){
  290.    DataFrame_Put[3] = 0;
  291.    DataFrame_Put[4] = 0;
  292.    DataFrame_Put[5] = 0;
  293.    DataFrame_Put[6] = 0;
  294.    DataFrame_Put[7] = 0;
  295.    DataFrame_Put[8] = 0;
  296.    DataFrame_Put[9] = 0;
  297.    DataFrame_Put[10] = 0;
  298.    DataFrame_Put[11] = 0;
  299.    DataFrame_Put[12] = 0;
  300.    DataFrame_Put[13] = 0;
  301.    DataFrame_Put[14] = 0;
  302. }

  303. //初始化溫度值
  304. void TEMP_init_var(){
  305.     ds_M = 0;
  306.     ds_L = 0;
  307.         symbol = 0;     //符號位
  308.         hundreds = 0;   //百位
  309.         decade = 0;     //十位
  310.         unit = 0;       //個位
  311.         decimal = 0;    //小數(shù)1位
  312. }

  313. //初始化
  314. void UART_init()
  315. {
  316.         TMOD = 0x20;          //T1工作模式2  8位自動重裝
  317.         TH1 = 0xfd;
  318.         TL1 = 0xfd;         //比特率9600
  319.         TR1 = 1;                //啟動T1定時器
  320.         SM0 = 0;
  321.         SM1 = 1;                 //串口工作方式1 10位異步
  322.         REN = 1;                //串口允許接收
  323.         EA  = 1;                //開總中斷
  324.         ES  = 1;                //串口中斷打開
  325. }

  326. //串口發(fā)送一幀數(shù)據(jù)函數(shù),一幀16個字節(jié)
  327. void PutFrame(uchar *TXStr)  
  328. {   
  329.          uchar i = 0;
  330.          while(1){
  331.            SBUF=*TXStr;
  332.            while(TI == 0);  //對方接收后TI置1,停止等待
  333.            TI = 0;
  334.            i++;
  335.            if(i > 15){break;}
  336.            TXStr++;
  337.      }
  338. }

  339. void UART() interrupt 4
  340. {
  341.    if(RI)   //檢測是否接收完成
  342.    {
  343.      uchar temp = SBUF;
  344.          RI = 0;
  345.          // 如果接收的一幀,第一個字節(jié)不是包頭標志,則拋棄這個字節(jié)
  346.          if(dataFrame_temp_count == 0)
  347.          {
  348.             if(temp != DATAFRAME_HEAD)
  349.                         return;
  350.          }
  351.          //如果接收的一幀,最后一個字節(jié)不是包尾標志,則拋棄這幀數(shù)據(jù)
  352.          if(dataFrame_temp_count == 15)
  353.          {
  354.             if(temp != DATAFRAME_TAIL){
  355.                   dataFrame_temp_count = 0;
  356.                   return;
  357.                 }               
  358.          }
  359.      //將接收的一個字節(jié)裝入緩沖區(qū)
  360.      dataFrame_temp[dataFrame_temp_count] = temp;
  361.          dataFrame_temp_count++;

  362.          //如果一幀數(shù)據(jù)接收完
  363.          if(dataFrame_temp_count >= 16){
  364.             //如果上一幀還沒有讀取,則拋棄這一幀
  365.                 if(dataFrame_RI == 1){
  366.                         dataFrame_temp_count = 0;
  367.                         return;
  368.                 }

  369.                 //拷貝一幀數(shù)據(jù),并置這一幀數(shù)數(shù)沒有讀取
  370.                 dataFrame[0] = dataFrame_temp[0];
  371.                 dataFrame[1] = dataFrame_temp[1];
  372.                 dataFrame[2] = dataFrame_temp[2];
  373.                 dataFrame[3] = dataFrame_temp[3];
  374.                 dataFrame[4] = dataFrame_temp[4];
  375.                 dataFrame[5] = dataFrame_temp[5];
  376.                 dataFrame[6] = dataFrame_temp[6];
  377.                 dataFrame[7] = dataFrame_temp[7];
  378.                 dataFrame[8] = dataFrame_temp[8];
  379.                 dataFrame[9] = dataFrame_temp[9];
  380.                 dataFrame[10] = dataFrame_temp[10];
  381.                 dataFrame[11] = dataFrame_temp[11];
  382.                 dataFrame[12] = dataFrame_temp[12];
  383.                 dataFrame[13] = dataFrame_temp[13];
  384.                 dataFrame[14] = dataFrame_temp[14];
  385.                 dataFrame[15] = dataFrame_temp[15];
  386.                
  387.                 dataFrame_temp_count = 0;
  388.                 dataFrame_RI = 1;
  389.          }
  390.    }
  391. }
復制代碼

回復

使用道具 舉報

ID:213173 發(fā)表于 2018-4-8 21:23 | 顯示全部樓層
串口接收使用查詢法,放棄使用中斷法,這樣可以避免與其他應用程序發(fā)生沖突。
回復

使用道具 舉報

ID:111517 發(fā)表于 2018-4-8 22:40 | 顯示全部樓層
在進行DS18B20查詢之前把中斷給關掉不就好了嗎
回復

使用道具 舉報

ID:284106 發(fā)表于 2018-4-9 09:08 | 顯示全部樓層
滄浪 發(fā)表于 2018-4-8 22:40
在進行DS18B20查詢之前把中斷給關掉不就好了嗎

中斷關了,如果這時串口有數(shù)據(jù)來到,串口數(shù)據(jù)就會丟失。
回復

使用道具 舉報

ID:284106 發(fā)表于 2018-4-9 12:46 | 顯示全部樓層
wulin 發(fā)表于 2018-4-8 21:23
串口接收使用查詢法,放棄使用中斷法,這樣可以避免與其他應用程序發(fā)生沖突。

如果使用查詢法,單片機不能一直只查詢串口有沒有數(shù)據(jù)來到。同時還要l輪詢DS18B20的溫度數(shù)據(jù),查詢一個DS18B20 時間就早己超過1毫秒,如果查詢幾個,還執(zhí)行其他的操作,如1602顯示的話,就會更長。

9600波特率下,串口收取數(shù)據(jù),下一個字節(jié)數(shù)據(jù)接收完成前,約有1毫秒的時間,要把數(shù)據(jù)取走,不然串口就會丟棄接收的數(shù)據(jù)。這樣,在查詢其他器件時,串口還是會丟數(shù)據(jù)。

感覺查詢法似乎不行
回復

使用道具 舉報

ID:213173 發(fā)表于 2018-4-9 15:33 | 顯示全部樓層
本帖最后由 wulin 于 2018-4-9 16:50 編輯
duwen009 發(fā)表于 2018-4-9 12:46
如果使用查詢法,單片機不能一直只查詢串口有沒有數(shù)據(jù)來到。同時還要l輪詢DS18B20的溫度數(shù)據(jù),查詢一個DS ...

你如果無法協(xié)調(diào)使用時間片輪詢處理多任務管理,這通訊協(xié)議就要修改。上位機每發(fā)送一個字節(jié)需要等待下位機應答后才能發(fā)送下一個字節(jié)。你的程序?qū)懙煤軉,會占用MCU很多時間,DS18B20是單總線器件,不必開多個I/O口。串口中斷里也不要處理非必須的事務,信息保存后由主程序處理。
回復

使用道具 舉報

ID:284106 發(fā)表于 2018-4-9 19:50 | 顯示全部樓層
wulin 發(fā)表于 2018-4-9 15:33
你如果無法協(xié)調(diào)使用時間片輪詢處理多任務管理,這通訊協(xié)議就要修改。上位機每發(fā)送一個字節(jié)需要等待下位機 ...

新手,這是第一個51單片機程序,想在電腦上顯示采集的溫度,和控制繼電器開關,程序是很啰嗦。

我又想了一種方法,把這樣的通訊寫出來,串口收發(fā)數(shù)據(jù),同時操作其他的不影響。不知別人有沒有這么實現(xiàn)的。打了個草稿。用兩個51單片機來弄,相當于兩個進程在工作。兩個單片機傳數(shù)據(jù)用輪詢,不使用中斷,用邏輯來判斷。
發(fā)送端代碼寫出來了,接收端還沒有寫。還要再想想,大家一般是怎么弄的。寫的很費勁,要想很久。 3.jpg
通訊的方法打了個草稿。四根線實現(xiàn)單向通訊。八根線實現(xiàn)雙向通訊。
4.jpg


發(fā)送端代碼

  1. #include        "config.h"

  2. #define dataFrame_headFlag 254   //用于串口通信時,定義數(shù)據(jù)幀頭部的驗證標記
  3. #define dataFrame_tailFlag 255   //用于串口通信時,定義數(shù)據(jù)幀尾部的驗證標記

  4. #define deviceID_1Bit 0        //用于串口通信時,定義本地設備ID的第1位
  5. #define deviceID_2Bit 1        //用于串口通信時,定義本地設備ID的第2位

  6. //定義DS18B20查詢包,查詢控制位0,0,1,1
  7. uchar DataFrame_DS18B20[16]={dataFrame_headFlag,deviceID_1Bit,deviceID_2Bit,0,0,1,1,0,0,0,0,0,0,0,0,dataFrame_tailFlag};
  8. //定義心跳包
  9. uchar DataFrame_HeartBeat[16]={dataFrame_headFlag,deviceID_1Bit,deviceID_2Bit,0,0,0,1,0,0,0,0,0,0,0,0,dataFrame_tailFlag};


  10. uchar DWBusPutFrame_byte;                          //正在發(fā)送的byte
  11. uchar DWBusPutFrame_bitCount;                  //己發(fā)送bit計數(shù)
  12. uchar DWBusPutFrame_byteCount;                  //己發(fā)送的byte計數(shù)

  13. uchar DWBusPutFrame_buf[16];          //一幀數(shù)據(jù)緩沖區(qū),16個字節(jié)
  14. uchar DWBusPutFrame_buf_isPut = 0;    //緩沖區(qū)發(fā)送標志,0 不發(fā)送,1 發(fā)送

  15. uchar DWBusPutFrame_step;                          //步驟

  16. //發(fā)送數(shù)據(jù)
  17. void DWBusPutFrame()
  18. {
  19.   if(DWBusPutFrame_step == 0){
  20.            DWBusPutFrame_byte = DWBusPutFrame_buf[DWBusPutFrame_byteCount];
  21.          DWBusPutFrame_byteCount++;
  22.          DWBusPutFrame_step = 1;
  23.          if(DWBusPutFrame_byteCount >=16){
  24.                 DWBusPutFrame_byte = 0;
  25.             DWBusPutFrame_bitCount = 0;
  26.                 DWBusPutFrame_byteCount = 0;
  27.             DWBusPutFrame_step = 0;
  28.                 DWBusPutFrame_buf_isPut = 0;  //置不發(fā)送,因為數(shù)據(jù)己發(fā)送
  29.          }
  30.   }
  31.   if(DWBusPutFrame_step == 1){
  32.      if(DWBusPutFrame_bitCount == 0){  //發(fā)送開始位
  33.                    D1 = 0;_nop_();
  34.                 D2 = 0;_nop_();
  35.                 C1 = 0;_nop_();
  36.          }
  37.          if(DWBusPutFrame_bitCount > 0 && DWBusPutFrame_bitCount < 9){        //發(fā)送數(shù)據(jù)
  38.             if(DWBusPutFrame_byte & 0x80){
  39.                       D1 = 1;_nop_();
  40.                    D2 = 0;_nop_();
  41.                    C1 = 0;_nop_();
  42.             }else{
  43.                D1 = 0;_nop_();
  44.                    D2 = 1;_nop_();
  45.                    C1 = 0;_nop_();
  46.             }
  47.          }
  48.          if(DWBusPutFrame_bitCount >= 9){  //發(fā)送結(jié)束位
  49.                    D1 = 0;_nop_();
  50.                 D2 = 0;_nop_();
  51.                 C1 = 0;_nop_();
  52.          }
  53.          DWBusPutFrame_step = 2;
  54.   }
  55.   if(DWBusPutFrame_step == 2){  //接收端響應 1
  56.      if(C2 == 0){
  57.                    D1 = 1;_nop_();
  58.                 D2 = 1;_nop_();
  59.                 C1 = 1;_nop_();
  60.                 DWBusPutFrame_step = 3;         
  61.          }
  62.   }
  63.   if(DWBusPutFrame_step == 3){         //接收端響應 2
  64.            if(C2 == 1){
  65.                  DWBusPutFrame_bitCount++;     //完成1Bit發(fā)送
  66.                 if(DWBusPutFrame_bitCount > 1 && DWBusPutFrame_bitCount < 10){
  67.                    DWBusPutFrame_byte <<= 1;  //左移一位                  
  68.             }
  69.                 if(DWBusPutFrame_bitCount >= 10){
  70.                    DWBusPutFrame_byte = 0;
  71.             }
  72.                 DWBusPutFrame_step = 0;
  73.          }
  74.   }
  75. }

  76. int i = 0;
  77. void main()
  78. {
  79.         for(i = 0;i<16;i++){
  80.                 DWBusPutFrame_buf[i] = DataFrame_DS18B20[i];
  81.         }
  82.         DWBusPutFrame_buf_isPut = 1;
  83.         //開始輪詢發(fā)送數(shù)據(jù)
  84.         while(1){
  85.           DWBusPutFrame();
  86.         }
  87.    
  88.         while(1);
  89. }


復制代碼





回復

使用道具 舉報

ID:284106 發(fā)表于 2018-4-9 19:57 | 顯示全部樓層
wulin 發(fā)表于 2018-4-9 15:33
你如果無法協(xié)調(diào)使用時間片輪詢處理多任務管理,這通訊協(xié)議就要修改。上位機每發(fā)送一個字節(jié)需要等待下位機 ...

用兩個51單片機實現(xiàn)多任務,每個51單片機執(zhí)行不同的任務。
兩個單片機通信,不能用串口,因為被占用了。也不能用中斷,不然會引響時序。
用輪詢,有好的穩(wěn)定的實例嗎?
回復

使用道具 舉報

ID:284106 發(fā)表于 2018-4-9 23:05 | 顯示全部樓層
看到了用這個 RTX51 Tiny 可以讓51單片機實現(xiàn)多任務,得研究一下。這樣就可以實現(xiàn)收數(shù)據(jù)時,同時執(zhí)行查詢DS18B20溫度。
回復

使用道具 舉報

ID:158375 發(fā)表于 2018-12-27 13:04 | 顯示全部樓層
軟件結(jié)構(gòu)問題。
你可以定義標志位,有發(fā)送標志,發(fā)送數(shù)據(jù);有接收數(shù)據(jù)完成標志,處理接收數(shù)據(jù);有屏刷新標志,刷新屏幕。。。。。。
回復

使用道具 舉報

ID:449525 發(fā)表于 2018-12-27 17:18 | 顯示全部樓層
樓上有人說的是對的
我今天也寫了類似代碼,你串口檢測接受。當你采集溫度的時候,把串口中斷關閉。
還有就是你的顯示,你可以先判斷下數(shù)據(jù)改變了,在去刷屏顯示。沒有必要接受到數(shù)據(jù)就是顯示,做個判斷也是對資源合理利用
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表