找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14326|回复: 29
打印 上一主题 下一主题
收起左侧

基于RS485总线的温湿度监控网络设计 带上位机 下位机

  [复制链接]
跳转到指定楼层
楼主
   忙活了好久终于做出了温湿度采集和485的多机通信,还有上位机。本系统完成的功能有:各个从机采集数据传送给主机再由主机传送到上位机,下位机同时可以接受上位机的控制,来改变温湿度。找了好久发现网上这方面的资料很不全,而且大部分不能用,现将资料全部共享,方便大家学习交流,有不足之处,还请各位多提意见建议。
先上几张作品图,预览预览,呵呵···

    传感器是 奥松 的,型号为AM2301(又名DHT21),挺好用的,传输距离可达到20米,本人已通过实地验证。上位机是用VC做的,版本为VC6.0,界面做了简单的美化,用到了不少控件,按键类、Edit类、图表类等等。
上位机、下位程序、以及用到的芯片及参考资料现打包上传







参考资料.zip

1.26 MB, 下载次数: 359, 下载积分: 黑币 -5

程序.7z

5.49 MB, 下载次数: 419, 下载积分: 黑币 -5

电路图.zip

523.85 KB, 下载次数: 357, 下载积分: 黑币 -5

评分

参与人数 2黑币 +45 收起 理由
luliang02003 + 15 赞一个!
INVIO + 30 赞一个!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏26 分享淘帖 顶7 踩1
回复

使用道具 举报

沙发
ID:137190 发表于 2016-9-8 15:38 | 只看该作者
下面是下位机的主机源代码:
  1. /***************************************************************************
  2. 函数名称: AM2301多机通信主机部分
  3. 主控芯片: STC12C5A60S2,晶振11.0592MHz
  4. 功          能: 和从机及上位机通信,接收从机发送过来的温湿度,用1620显示出来并
  5.                    将数据传送到上位机
  6. 创建日期: 2011.5.22
  7. 修改日志: 无
  8. ****************************************************************************/                                                                          
  9. //#include <reg52.h>
  10. #include <STC12C5A.h>
  11. #include <intrins.h>
  12. #include "LCD1602.h"

  13. #define uchar unsigned char
  14. #define uint  unsigned int
  15. #define _Nop() _nop_()

  16. sbit  RDE =P3^2;         //        485控制输入输出控制(与从机)
  17. sbit  RDE2=P1^4;        //485控制输入输出控制(与上位机)
  18. #define SlaveNum 2   //从机数量

  19. uchar code dis1[]={"H:     % T:    C"} ;
  20. uchar code dis2[]={"h:     % t:    c"} ;
  21. #define num 8  //缓冲数据的长度
  22. char Revdata[num];//接收到的数据缓存
  23. uchar SLAVE_ID = 1;//从机地址
  24. uchar  rc;//串口1接收到和数据缓存
  25. uchar Rev;//串口2接收数据
  26. //----------------------------------------
  27. uchar state = 0;//状态标志位。1-进入等待从机回应,2-更新显示数据
  28. uchar recv_length = 0;
  29. bit recving_flag = 0;
  30. bit recfinish=0;
  31. bit recflag=0;
  32. bit minusflag=0,addflag=0,stopflag=0;
  33. //----------------------------------------
  34. ////////////////////////////////////////////////////////////////////////
  35. //////////////////延时函数///////////////////////////////////////
  36. ////////////////////////////////////////////////////////////////////////
  37. void Delay(unsigned int t)
  38. {

  39. while(t--);

  40. }
  41. /////////////////////////////////
  42. void Delay_10us(unsigned int us)
  43. {
  44.   do{
  45.          _nop_();
  46.          _nop_();
  47.          _nop_();
  48.          _nop_();
  49.          _nop_();
  50.         }while(--us);
  51. }
  52. //////////////////////////////////
  53. void Delay_ms(unsigned int ms)
  54. {
  55.   do Delay_10us(131);
  56.         while(--ms);
  57. }
  58. ////////////////////////////////////////////////////////////////////////
  59. //////////////////////串口1发送地址函数//////////////////////////////
  60. ////////////////////////////////////////////////////////////////////////
  61. void senda(unsigned char adra) //发送地址
  62. {

  63.         TB8 = 1;//发送地址帧
  64.     RDE = 1;//允许发送
  65.         Delay_10us(50);
  66.         ES=0;  //关串1口中断
  67.     TI  = 0; //清标志位
  68.         SBUF = adra;
  69.         while(!TI);
  70.         TI  = 0;//等待发送完毕
  71.         ES=1;  //开串口1中断
  72.         RDE = 0;//485允许接收         
  73.         Delay_10us(50);
  74. }
  75. ////////////////////////////////////////////////////////////////////////
  76. //////////////////////串口1发送数据函数//////////////////////////////
  77. //////////////////////////////////////////////////////////////////////
  78. /**/
  79. void sendata(unsigned char tdata) //发送地址
  80. {

  81.         TB8=0;//发送数据帧
  82.     RDE = 1;//允许发送
  83.     TI = 0;
  84.         SBUF = tdata;
  85.         while(!TI);
  86.         TI=0;
  87.         RDE = 0;//485允许接收         

  88. }
  89. //////////////////////////////////////////////////////////////////////
  90. //////////////////////串口2发送数据函数///////////////////////////////
  91. //////////////////////////////////////////////////////////////////////
  92. void Uart2_senbyte(uchar val)
  93. {
  94.   RDE2=1;//485发送状态
  95. // Delay(50);
  96.   IE2=0x00;//关串口2中断
  97.   S2BUF=val;
  98.   while ((S2CON & 0x02) == 0);   //等待发送完毕
  99.                   S2CON &= 0xFD;  //清标志位(S2TI=0)
  100.   IE2=0x01;//开串口2中断
  101.   RDE2=0;
  102. //  Delay(50);
  103. }

  104. ////////////////////////////////////////////////////////////////////////
  105. ///////////////////////////////显示函数/////////////////////////////////
  106. ////////////////////////////////////////////////////////////////////////

  107. ///////////显示字符///////
  108. void showchar()
  109. { uchar string;
  110. //====显示字符1======
  111.         string=0;
  112.   writecmd(0x80);  
  113.     while(dis1[string] != '\0')//显示字符
  114.      {                        
  115.        writedata(dis1[string]) ;
  116.        string++ ;
  117.      }string = 0 ;         
  118. //=====显示字符2=====
  119.   writecmd(0xc0);  
  120.     while(dis2[string] != '\0')//显示字符
  121.      {                        
  122.        writedata(dis2[string]) ;
  123.        string++ ;
  124.      }string = 0 ;
  125. }
  126. //////////////显示数据/////////////
  127. void showdata()
  128. {
  129. if(SLAVE_ID==1)
  130.    {
  131.    //=====显示湿度=====
  132.     writecmd(0x82);  
  133.     writedata(Revdata[1]+0x30);
  134.     writedata(Revdata[2]+0x30);
  135.     writedata('.');
  136.     writedata(Revdata[3]+0x30);
  137.    //=====显示温度=====
  138.         writecmd(0x8b);
  139.     writedata(Revdata[4]+0x30);
  140.     writedata(Revdata[5]+0x30);
  141.     writedata('.');
  142.     writedata(Revdata[6]+0x30);
  143.     Delay_ms(400);
  144.    }
  145. if(SLAVE_ID==2)
  146.   {
  147.    //=====显示湿度=====
  148.     writecmd(0xc2);
  149.     writedata(Revdata[1]+0x30);
  150.     writedata(Revdata[2]+0x30);
  151.     writedata('.');
  152.     writedata(Revdata[3]+0x30);
  153.    //=====显示温度=====
  154.         writecmd(0xcb);
  155.     writedata(Revdata[4]+0x30);
  156.     writedata(Revdata[5]+0x30);
  157.     writedata('.');
  158.     writedata(Revdata[6]+0x30);
  159.     Delay_ms(1000);
  160.   }
  161.        
  162. }
  163. ////////////////////////////////////////////////////////////////////////
  164. ///////////////////串口初始化函数////////////////////////////////
  165. ////////////////////////////////////////////////////////////////////////
  166. void UARTinit()
  167. {     
  168.    //串口1初始化/////////
  169.    TMOD|=0x21;//定时器1工作在方式2,定时器0工作在方式1
  170.    TH1=0xfa;TL1=0xfa; //波特率9600   
  171.    SCON=0x50;//SCON:SM0,SM1,SM2,REN,TB8,RB8,TI,RI
  172.    PCON|=0x80;//波特率倍增
  173.    TR1=1;//开定时器1
  174.    EA=1;//开总中断
  175.    ES=1;//串口1中断
  176.    //--------------------//       
  177.    //串口2初始化///////////
  178.    BRT  = 0XDC; //设置独立的波特率发生器的重载数值,此数值的波特率为9600
  179.    AUXR = 0X14; //设置波特率的发生方式(允许波特率发生器运行,波特率不加倍,每个时钟计数一次)
  180.    S2CON|=0x50;//串口2,方式1,允许接收
  181.    IE2|=0X01;//允许串口2中断
  182.    EA=1;//开总中断
  183.    //--------------------//
  184.    Delay(10000);  //热机时间
  185.    init_LCD(); //初始化液晶
  186. }
  187. //==========================================
  188. ////////////////////////////////////////////////////////////////////////

  189. ///////////////////////////////主函数///////////////////////////////////

  190. ////////////////////////////////////////////////////////////////////////
  191. void main()
  192. {
  193. //   uchar i;
  194.      UARTinit();//串口初始化
  195.      Delay(40000);//热机
  196.        

  197.       while(1)
  198.       {
  199.                  WDT_CONTR=0x3c;//启动看门狗,超过该时间未能喂狗则系统复位,
  200.                 //0011.1011---WDT_FLAG=0,EN_WDT=1,CLR_WDT=1,IDLE_WDT=0,PS2=1,PS1=1,PS0=0
  201.                 //IDLE_WDT=1时,"空闲模式"计数,IDLE_WDT=0时"空闲模式"不计数
  202.                  //0x38-71.1ms,0x39-142.2ms, 0x3a-284.4ms, 0x3b-568.8ms,
  203.                  //0x3c-1.1377s,0x3d-2.2755s,0x3e-4.5511s,0x3f-9.1022s
  204.               showchar();//显示字符       
  205.          if(state == 0)
  206.           {
  207.                        
  208.                         senda(SLAVE_ID++);
  209.                         if(SLAVE_ID>SlaveNum)SLAVE_ID = 1;

  210.                         if(addflag==1&&SLAVE_ID==1){sendata(0xf1);addflag=0;}//发送指令给从机1
  211.                         if(minusflag==1&&SLAVE_ID==2){sendata(0xf2);minusflag=0;}//发送指令给从机2
  212.                         if((stopflag==1&&SLAVE_ID==1)||(stopflag==1&&SLAVE_ID==2))
  213.                                 {stopflag=0,sendata(0xf0);}   // 发哦能够停止指令给从机1、2         
  214.                        
  215.                          Delay_ms(30);

  216.                          state = 1;// 状态转为等待从机应答,在串口中断
  217. /*                if(recfinish==1)
  218.                         {        recfinish=0;
  219.                                
  220.                                
  221.                                  if(recflag == 0)
  222.                                 {//   recflag =0;
  223.                                 //        senda(SLAVE_ID);
  224.                                 senda(SLAVE_ID++);        Delay_ms(4000);
  225.                                   if(SLAVE_ID>SlaveNum)
  226.                                         {
  227.                                          SLAVE_ID = 1;
  228.                                          senda(SLAVE_ID);
  229.                                          Delay_ms(4000);
  230.                                          }
  231.                
  232.                                 }//end of recving_flag =0
  233.                         }//end of recfinish=1
  234.         */                 



  235.          }  //end of state=0      
  236.      


  237.           if(state == 2)   // 状态 转为 显示         
  238.          {
  239.           showdata();//更新数据显示
  240.                   Delay_ms(800);

  241.                   //发送数据到上位机
  242.                   Uart2_senbyte('R');//上位机识别湿度的标志
  243.                   Uart2_senbyte(Revdata[1]+0x30);//                  
  244.                   Uart2_senbyte(Revdata[2]+0x30);
  245.                   Uart2_senbyte('.');
  246.                   Uart2_senbyte(Revdata[3]+0x30);
  247.                   Uart2_senbyte('T');//上位机识别温度的标志
  248.                   Uart2_senbyte(Revdata[4]+0x30);
  249.                   Uart2_senbyte(Revdata[5]+0x30);
  250.                   Uart2_senbyte('.');
  251.                   Uart2_senbyte(Revdata[6]+0x30);
  252.                   if(SLAVE_ID==1)Uart2_senbyte('A');//上位机识别从机的标志
  253.                   if(SLAVE_ID==2)Uart2_senbyte('B');

  254. /*               ////////////////////////////////////////////////////////////////
  255.           for(i = 1; i<num-1; i++)
  256.             {
  257.                           
  258.                  
  259.                           senda(Revdata[i]); //把收到的数据往PC机回送(串口助手调试用)
  260.                     Delay_ms(20);                  
  261.             }
  262. */                        ////////////////////////////////////////////////////////////////
  263.            Delay_ms(20);               
  264.            state = 0;    // 状态转为0,重新查询从机         
  265.           }//end of state=2

  266.                 WDT_CONTR=0x3c;//喂狗,若超过时间不喂狗,则系统复位

  267.      }//end of while(1)
  268.        
  269.           
  270. }//end of main()

  271. ////////////////////////////////////////////////////////////////////////

  272. ///////////////////串口 1接收 中断 函数//////////////////////////////////

  273. ////////////////////////////////////////////////////////////////////////
  274. void Recv_int(void)interrupt 4 //using 2               
  275. {

  276.         RDE=0;
  277.         if(RI)
  278.         {  
  279.        RI=0;
  280.        rc=SBUF;
  281.           
  282.          if(state==1)
  283.                 {
  284.                        
  285.            if((recv_length == 0)&&(rc == 0xf7 )  ) //这里判断发送的第一个字节
  286.            {
  287.               recving_flag = 1;
  288.                           recflag=1;
  289.            }
  290.            
  291.            if(recving_flag == 1)
  292.            {
  293.               Revdata[recv_length++] = rc;
  294.                             if(rc == 0xf3)//判断结束帧
  295.               {
  296.                recv_length = 0;
  297.                recving_flag = 0;
  298.                            recfinish=1;
  299.                 state = 2;   //接收完毕,置标志位,准备显示

  300.               }//end of rc=0xf3              
  301.               
  302.             }//end of recving_flag = 1
  303.                  
  304.                  }//end of state=1

  305.    
  306.      }//end of RI
  307.       
  308. }//end of interrupt

  309. //////////////////串口2中断服务子程序////////////////////////////
  310. void Uart2() interrupt 8 //using 1
  311. {
  312.         RDE2=0;//485保持为接收状态
  313.    if (S2CON & S2RI)
  314.     {
  315.         S2CON &= ~S2RI; //清除接收完成标志
  316.         Rev = S2BUF;   
  317.         switch(Rev)
  318.                         {
  319.                         case 'a':  //加大湿度
  320.                                 addflag=1;
  321.                                 break;
  322.                         case 'm':  //降低湿度
  323.                                 minusflag=1;
  324.                                 break;
  325.                         case 's':  //停止
  326.                                 stopflag=1;
  327.                                 break;       
  328.                         default:
  329.                                 break;
  330.                         }//end of swtich  
  331.         } //end of if                  
  332.                
  333.     RDE2=1;//485允许发送       
  334.    
  335. }


  336. ////////////////////////////////End/////////////////////////////////////
复制代码
回复

使用道具 举报

板凳
ID:96326 发表于 2017-2-14 10:47 | 只看该作者
学习了,谢谢楼主
回复

使用道具 举报

地板
ID:167870 发表于 2017-3-3 15:13 | 只看该作者
学习了,谢谢楼主
回复

使用道具 举报

5#
ID:166122 发表于 2017-3-3 16:21 | 只看该作者
学习了,谢谢楼主
回复

使用道具 举报

6#
ID:186708 发表于 2017-4-21 15:40 | 只看该作者
下载了三次都是内部服务器有问题,白白扣金币,不能下载还要扣金币

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

7#
ID:186708 发表于 2017-4-21 15:55 | 只看该作者
就是那个参考资料不能下载,程序可以下载
回复

使用道具 举报

8#
ID:207132 发表于 2017-6-2 16:28 | 只看该作者
学习了,谢谢楼主!!
回复

使用道具 举报

9#
ID:109053 发表于 2017-6-15 11:55 | 只看该作者
是那个参考资料不能下载,程序可以下载
回复

使用道具 举报

10#
ID:321960 发表于 2018-5-4 11:46 | 只看该作者
学习中
回复

使用道具 举报

11#
ID:334782 发表于 2018-5-21 12:28 | 只看该作者
支持楼主,歇息
回复

使用道具 举报

12#
ID:323951 发表于 2018-5-21 14:28 | 只看该作者
谢谢楼主
回复

使用道具 举报

13#
ID:337273 发表于 2018-5-24 16:50 | 只看该作者
谢谢楼主分享出来
回复

使用道具 举报

14#
ID:349444 发表于 2018-7-28 11:59 | 只看该作者
谢谢分享
回复

使用道具 举报

15#
ID:92810 发表于 2018-11-12 15:30 | 只看该作者
谢谢分享了,学习学习
回复

使用道具 举报

16#
ID:210375 发表于 2018-11-14 21:50 | 只看该作者
最近正好在学这个,楼主的分享给了我很大的启发,谢谢楼主
回复

使用道具 举报

17#
ID:373813 发表于 2018-11-25 12:09 | 只看该作者
谢谢分享
回复

使用道具 举报

18#
ID:53978 发表于 2018-12-14 21:35 | 只看该作者
好东西 谢谢分享
回复

使用道具 举报

19#
ID:509877 发表于 2019-5-23 11:05 来自手机 | 只看该作者
单片机只有一个串口怎么同时接受两个采集的物理量
回复

使用道具 举报

20#
ID:92810 发表于 2019-10-28 11:31 | 只看该作者
学习了,谢谢楼主
回复

使用道具 举报

21#
ID:632444 发表于 2019-11-3 08:57 | 只看该作者
虽然现在还没接触到,还是要谢谢楼主的无私奉献,挺好的,给于初学着帮助,一个方向。
回复

使用道具 举报

22#
ID:639650 发表于 2019-11-12 09:57 | 只看该作者
上位机与下位机的RS485的通讯程序能粘贴出来吗?
回复

使用道具 举报

23#
ID:411700 发表于 2020-1-8 10:20 | 只看该作者
请问怎么打开上位机程序丫
回复

使用道具 举报

24#
ID:214276 发表于 2020-3-18 17:20 | 只看该作者
利害!不愧为高手!
回复

使用道具 举报

25#
ID:283908 发表于 2020-3-19 16:28 | 只看该作者
下载学习了,谢谢楼主。
回复

使用道具 举报

26#
ID:704585 发表于 2020-4-28 15:49 | 只看该作者
学习中,感谢楼主
回复

使用道具 举报

27#
ID:755119 发表于 2020-5-26 18:25 | 只看该作者
楼主,你这还有详细的代码吗?这个不好用啊,谢谢
回复

使用道具 举报

28#
ID:941205 发表于 2022-4-13 15:20 | 只看该作者
太感谢楼主了,连参考资料都有。
回复

使用道具 举报

29#
ID:19250 发表于 2023-4-12 13:09 | 只看该作者
连参考资料都有
回复

使用道具 举报

30#
ID:65956 发表于 2023-4-13 08:37 | 只看该作者
上位机在哪个下载,分这么多,要花好多米
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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