找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3099|回复: 11
收起左侧

关于单片机温度采集串口中断的问题?

[复制链接]
ID:284106 发表于 2018-4-8 20:47 | 显示全部楼层 |阅读模式
在用STC89C52单片机做一个温度采集功能。
功能是这样的:
      1、工作频率 11.0592
      2、P2.0,P2.1,P2.2,P2.3 普通IO口分别接了四个S18B20温度传感器,用来采集温度。
      3、RX,TX分别和电脑的串口连好,实现和电脑通讯
      4、电脑串口定时发送定义好的查询帧,单片机串口收到后,判断帧的内容,查询温度,并返回温度数据。
      5、功能己经实现,这样运行的也没有问题。

现在的操作方式是被动操作,(也就是电脑发送一帧数据,单片机查询一次温度,并返回)流程如下:
   1,电脑串口发送定义好的16字数据 --->2、单片机串口收到数据,根据数据的类型,查询S18B20温度传感器温度---->3,单片机将温度数据再编码成16个字节数据发送给电脑串口---->4,电脑串口收到数据后处理并显示


存在一个问题是:
现在我想在单片机上装一个显示屏,让单片机定时不断查询温度并显示在屏幕上。
但是单片机在进行S18B20查询温度是很讲究时序的,在1602显示屏上显示文字,也是讲究时序的。
问题:单片机正在对S18B20查询温度时(IO口电平拉高,或拉底),这时有串口数据来到,会中断当前的操作,直到中断函数执行完毕。这时查询S18B20的操作时序就不准确了,1602显示屏也一样。

问:有串口数据来到要接收,不能丢弃。对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];            //定义数据帧长度为16个字节
  11. uchar dataFrame_RI;             //数据帧是否己读取标记

  12. uchar dataFrame_temp[16];            //数据帧临时缓冲区16个字节
  13. uchar dataFrame_temp_count;     //定义数据帧己接收的字节数

  14. //定义发送数据缓冲区
  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;         //有数据接收倒计时变量
  20. INT32U led4_count;                   //有数据发送倒计时变量
  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;   //小数1位

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

  38.         while(1)
  39.         {
  40.                 //调试使用
  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;          //执行时间2.17微妙

  43.                 //如果己接收到一帧数据
  44.                 if(dataFrame_RI == 1)        // 执行时间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){         // 执行时间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){         // 执行时间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;     //置数据帧己读取
  243.                         DataFrame_Put_init(); //初始化发送帧,为下一次发送数据做准备
  244.                 }

  245.                 //LED1运行指示灯闪烁,整个循环在没有接收数据时,执行一次约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.                 //有数据接收闪一下
  272.                 if(led3_count > 0){
  273.                   LED3 = 0;
  274.                   led3_count--;
  275.                 }else{
  276.                   LED3 = 1;
  277.                 }

  278.                 //有数据发送闪一下
  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;    //小数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. //串口发送一帧数据函数,一帧16个字节
  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.          // 如果接收的一帧,第一个字节不是包头标志,则抛弃这个字节
  346.          if(dataFrame_temp_count == 0)
  347.          {
  348.             if(temp != DATAFRAME_HEAD)
  349.                         return;
  350.          }
  351.          //如果接收的一帧,最后一个字节不是包尾标志,则抛弃这帧数据
  352.          if(dataFrame_temp_count == 15)
  353.          {
  354.             if(temp != DATAFRAME_TAIL){
  355.                   dataFrame_temp_count = 0;
  356.                   return;
  357.                 }               
  358.          }
  359.      //将接收的一个字节装入缓冲区
  360.      dataFrame_temp[dataFrame_temp_count] = temp;
  361.          dataFrame_temp_count++;

  362.          //如果一帧数据接收完
  363.          if(dataFrame_temp_count >= 16){
  364.             //如果上一帧还没有读取,则抛弃这一帧
  365.                 if(dataFrame_RI == 1){
  366.                         dataFrame_temp_count = 0;
  367.                         return;
  368.                 }

  369.                 //拷贝一帧数据,并置这一帧数数没有读取
  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 发表于 2018-4-8 21:23 | 显示全部楼层
串口接收使用查询法,放弃使用中断法,这样可以避免与其他应用程序发生冲突。
回复

使用道具 举报

ID:111517 发表于 2018-4-8 22:40 | 显示全部楼层
在进行DS18B20查询之前把中断给关掉不就好了吗
回复

使用道具 举报

ID:284106 发表于 2018-4-9 09:08 | 显示全部楼层
沧浪 发表于 2018-4-8 22:40
在进行DS18B20查询之前把中断给关掉不就好了吗

中断关了,如果这时串口有数据来到,串口数据就会丢失。
回复

使用道具 举报

ID:284106 发表于 2018-4-9 12:46 | 显示全部楼层
wulin 发表于 2018-4-8 21:23
串口接收使用查询法,放弃使用中断法,这样可以避免与其他应用程序发生冲突。

如果使用查询法,单片机不能一直只查询串口有没有数据来到。同时还要l轮询DS18B20的温度数据,查询一个DS18B20 时间就早己超过1毫秒,如果查询几个,还执行其他的操作,如1602显示的话,就会更长。

9600波特率下,串口收取数据,下一个字节数据接收完成前,约有1毫秒的时间,要把数据取走,不然串口就会丢弃接收的数据。这样,在查询其他器件时,串口还是会丢数据。

感觉查询法似乎不行
回复

使用道具 举报

ID:213173 发表于 2018-4-9 15:33 | 显示全部楼层
本帖最后由 wulin 于 2018-4-9 16:50 编辑
duwen009 发表于 2018-4-9 12:46
如果使用查询法,单片机不能一直只查询串口有没有数据来到。同时还要l轮询DS18B20的温度数据,查询一个DS ...

你如果无法协调使用时间片轮询处理多任务管理,这通讯协议就要修改。上位机每发送一个字节需要等待下位机应答后才能发送下一个字节。你的程序写得很啰嗦,会占用MCU很多时间,DS18B20是单总线器件,不必开多个I/O口。串口中断里也不要处理非必须的事务,信息保存后由主程序处理。
回复

使用道具 举报

ID:284106 发表于 2018-4-9 19:50 | 显示全部楼层
wulin 发表于 2018-4-9 15:33
你如果无法协调使用时间片轮询处理多任务管理,这通讯协议就要修改。上位机每发送一个字节需要等待下位机 ...

新手,这是第一个51单片机程序,想在电脑上显示采集的温度,和控制继电器开关,程序是很啰嗦。

我又想了一种方法,把这样的通讯写出来,串口收发数据,同时操作其他的不影响。不知别人有没有这么实现的。打了个草稿。用两个51单片机来弄,相当于两个进程在工作。两个单片机传数据用轮询,不使用中断,用逻辑来判断。
发送端代码写出来了,接收端还没有写。还要再想想,大家一般是怎么弄的。写的很费劲,要想很久。 3.jpg
通讯的方法打了个草稿。四根线实现单向通讯。八根线实现双向通讯。
4.jpg


发送端代码

  1. #include        "config.h"

  2. #define dataFrame_headFlag 254   //用于串口通信时,定义数据帧头部的验证标记
  3. #define dataFrame_tailFlag 255   //用于串口通信时,定义数据帧尾部的验证标记

  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;                          //正在发送的byte
  11. uchar DWBusPutFrame_bitCount;                  //己发送bit计数
  12. uchar DWBusPutFrame_byteCount;                  //己发送的byte计数

  13. uchar DWBusPutFrame_buf[16];          //一帧数据缓冲区,16个字节
  14. uchar DWBusPutFrame_buf_isPut = 0;    //缓冲区发送标志,0 不发送,1 发送

  15. uchar DWBusPutFrame_step;                          //步骤

  16. //发送数据
  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;  //置不发送,因为数据己发送
  29.          }
  30.   }
  31.   if(DWBusPutFrame_step == 1){
  32.      if(DWBusPutFrame_bitCount == 0){  //发送开始位
  33.                    D1 = 0;_nop_();
  34.                 D2 = 0;_nop_();
  35.                 C1 = 0;_nop_();
  36.          }
  37.          if(DWBusPutFrame_bitCount > 0 && DWBusPutFrame_bitCount < 9){        //发送数据
  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){  //发送结束位
  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发送
  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.         //开始轮询发送数据
  84.         while(1){
  85.           DWBusPutFrame();
  86.         }
  87.    
  88.         while(1);
  89. }


复制代码





回复

使用道具 举报

ID:284106 发表于 2018-4-9 19:57 | 显示全部楼层
wulin 发表于 2018-4-9 15:33
你如果无法协调使用时间片轮询处理多任务管理,这通讯协议就要修改。上位机每发送一个字节需要等待下位机 ...

用两个51单片机实现多任务,每个51单片机执行不同的任务。
两个单片机通信,不能用串口,因为被占用了。也不能用中断,不然会引响时序。
用轮询,有好的稳定的实例吗?
回复

使用道具 举报

ID:284106 发表于 2018-4-9 23:05 | 显示全部楼层
看到了用这个 RTX51 Tiny 可以让51单片机实现多任务,得研究一下。这样就可以实现收数据时,同时执行查询DS18B20温度。
回复

使用道具 举报

ID:158375 发表于 2018-12-27 13:04 | 显示全部楼层
软件结构问题。
你可以定义标志位,有发送标志,发送数据;有接收数据完成标志,处理接收数据;有屏刷新标志,刷新屏幕。。。。。。
回复

使用道具 举报

ID:449525 发表于 2018-12-27 17:18 | 显示全部楼层
楼上有人说的是对的
我今天也写了类似代码,你串口检测接受。当你采集温度的时候,把串口中断关闭。
还有就是你的显示,你可以先判断下数据改变了,在去刷屏显示。没有必要接受到数据就是显示,做个判断也是对资源合理利用
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表