迪文科技论坛

 找回密码
 立即注册
搜索
查看: 1939|回复: 4

【开源】开源之智能网络机柜控制系统

[复制链接]

6

主题

40

回帖

327

积分

中级会员

Rank: 3Rank: 3

积分
327
发表于 2021-4-21 23:00:56 | 显示全部楼层 |阅读模式
本帖最后由 liuxiaofei 于 2021-4-27 14:27 编辑

很高兴参加这个开源活动,不知道大家对于智能网络机柜控制系统熟悉不?和大家共同学习这个


大概看下这个智能机柜的原理?
机柜内部安装有温、湿度探测装置,能够智能监测机柜设备舱内环境温度和湿,并将监测到的温度、湿度值、电压,电流,总电量等信息显示到实时显示在柜门上的屏幕上。
触摸屏这块采用迪文的K600屏幕


通讯这块采用232、485、RJ45
这是工程配置







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

6

主题

40

回帖

327

积分

中级会员

Rank: 3Rank: 3

积分
327
 楼主| 发表于 2021-4-25 22:53:41 | 显示全部楼层
本帖最后由 liuxiaofei 于 2021-4-27 10:56 编辑

单片机这块采用STM32F103V8T6,程序简单分析一下看主函数初始化,源码已上传,可以参考
  1. int main(void)
  2. {  
  3.         //Systick_Init (72);                                        // MCU时钟初始化
  4.          RCC_Configuration();  //系统时钟
  5.          //IWDG_Init(4,1250);    //与分频数为64,重载值为1250,溢出时间为2s
  6.    delay_ms(500);
  7.          EEP_init();         //初始化EEProm,读取参数
  8.          GPIO_Config();           //端口初始化
  9.          CAN_Config();                  //can通讯初始化
  10.          GPIO_Configuration();
  11.          Timer_Configuration();                        // 定时器初始化
  12.          NVIC_Configuration(); //中断优先级设定初始化         
  13.          ADE7758_IOINIT1();        //ADE7758管脚初始化
  14.          ADE_AdjustSaveData(); //功能:保存校准数据
  15.          ADE_Init();//初始化         
  16.          //TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms
  17.          uart_init(9600);    //串口初始化
  18.    DHT11_Init(); //温湿度传感器初始化         
  19.          //SPI1
  20.    WIZ_SPI_Init();                                                        // SPI初始化
  21.          Reset_W5200();                                                        // 硬重启W5500
  22.          STMFLASH_Read(FLASH_SAVE_ADDR,eep_read,20);  /*读取存储值        */        
  23.          set_network();                                                        // 设置W5200的初始化IP信息        
  24.          GUI_init();//初始化屏状态        
复制代码
存储数据这块采用单片机内部的flash,比如存储柜门的开门记录,报警记录等数据。以太网芯片W5200采用SPI通信,可以通过网络连接电脑来监控机柜状态。还有一个就是电能计量计ADE7758初始化,主要功能
  • 高精度;支持IEC 60687、IEC 61036、IEC 61268、IEC 62053-21、IEC 62053-22和IEC 62053-23标准
  • 兼容三相三线、三相四线及其它三相服务
  • 25°C时,在1000:1的动态范围内有功电能误差小于0.1%
  • 电源有功/无功/视在电能、电压均方根、电流均方根和采样波形数据
  • 两个脉冲输出,其中一个用于有功功率,而另一个可通过可编程的频率在无功功率和视在功率之间选择
  • 数字功率、相位和均方根失调校准
  • 片内、用户可编程阈值,用于线路电压SAG和过压检测

一、分析以太网这块程序
1.设置W5200的初始化IP信息

  1. void set_network(void)
  2. {
  3.   uint8 mac[6]={0x00,0x08,0xdc,0x01,0x02,0x03};
  4.   uint8 sub[4]={255,255,255,0};
  5.   uint8 gw[4]={192,168,1,1};
  6.   uint8 lip[4];//={192,168,1,100};  
  7.   uint8 tmp[6]={0x00,};
  8.   lip[0]=eep_read[6];
  9.   lip[1]=eep_read[7];
  10.   lip[2]=eep_read[8];
  11.   lip[3]=eep_read[9];
  12.   setSIPR(lip);
  13.   setSHAR(mac);
  14.   setSUBR(sub);
  15.   setGAR(gw);
  16.   
  17.   
  18.   //Init. TX & RX Memory size
  19.   sysinit(txsize, rxsize);
  20.   
  21.   setRTR(2000);
  22.   setRCR(3);
  23.   
  24.   getSHAR(tmp);
  25. // printf("mac: %02x:%02x:%02x:%02x:%02x:%02x\r\n",tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5]);
  26.   getSIPR(tmp);
  27. // printf("ip: %d.%d.%d.%d\r\n",tmp[0],tmp[1],tmp[2],tmp[3]);
  28.   getSUBR(tmp);
  29.   //printf("subnet: %d.%d.%d.%d\r\n",tmp[0],tmp[1],tmp[2],tmp[3]);
  30.   getGAR(tmp);
  31. // printf("gateway: %d.%d.%d.%d\r\n",tmp[0],tmp[1],tmp[2],tmp[3]);

  32. }
复制代码
2.TCP发送数据
  1. //TCP/IP_Modbus发送数据

  2. void TCP_SendDATA(void)
  3. {
  4.         
  5.         //if(Tcp_ip_connec_flag==1)
  6.         //                {
  7.         //                        Tcp_ip_connec_flag=0;
  8.         //                        socket(0, Sn_MR_TCP, 5000, 0x00);                // 重新打开Socket  //重启Socket
  9.         //                }
  10.   //else
  11.         //{
  12.         switch(getSn_SR(0))
  13.             {
  14.                         
  15.             case SOCK_INIT:                                                                                                // Socket处于初始化状态
  16.                         {
  17.               listen(0);                                                                                                        // 开始监听
  18.               ka_tick_flag=0;                                                                                        // KA定时器开始计时标志位清零
  19.               ka_send_flag=0;                                                                                        // KA发送标志位清零
  20.               ka_no_data_tick=0;                                                                        // 无数据传输时间计时器清零
  21.                         }
  22.               break;

  23.             case SOCK_ESTABLISHED:                                                                // Socket处于连接建立状态
  24.                 // case SOCK_UDP:
  25.               if(getSn_IR(0) & Sn_IR_CON)
  26.               {
  27.                 setSn_IR(0, Sn_IR_CON);                                                // Sn_IR的第0位置1
  28.                 ka_tick_flag=0;                                                                                // KA定时器开始计时标志位清零
  29.                 ka_no_data_tick=0;                                                                // 无数据传输时间计时器
  30.                 ka_send_flag=0;                                                                                // KA发送标志位清零
  31.                 ka_send_tick=0;                                                                                // KA发送定时器清零
  32.               }
  33.               if ((len = getSn_RX_RSR(0)) > 0)               
  34.               {                                
  35.                 len = recv(0, RX_BUF, len);                                // W5200收到数据
  36.                                         Tcp_ip_Recvdata();
  37.                 //send(0,RX_BUF,len,(bool)0);                                // W5200将收到的数据发回客户端形成回环
  38.                                        
  39.                 if(ka_tick_flag==0)                                
  40.                 {
  41.                   ka_tick_flag=1;                                                                        // W5200同客户端进行了一次通信后,将KA定时器开始计时标志位置1,进入定时器中断,只要接下来在NO_DATA_PERIOD内没有数据通信,就开始发KA包
  42.                 }
  43.                 ka_no_data_tick=0;                                                                // 无数据传输时间计时器清零
  44.                 ka_send_tick=0;                                                                                // KA发送定时器清零
  45.               }
  46.               if(ka_send_flag)
  47.               {
  48.                 ka_send_flag=0;                                                                                // KA发送标志位清零
  49.                 ka_send_tick=0;                                                                                // KA发送定时器清零
  50.                 send_keepalive(0);                                                                // W5200发KA包给客户端
  51.                 //printf("*");
  52.               }
  53.               break;
  54.             case SOCK_CLOSE_WAIT:                                                                        // Socket处于等待关闭状态
  55.               if ((len = getSn_RX_RSR(0)) > 0)                // 如果此时仍有数据
  56.               {        
  57.                 len = recv(0, RX_BUF, len);                                // W5200继续收数据
  58.                                         Tcp_ip_Recvdata();
  59.                // send(0,RX_BUF,len,(bool)0);                                // W5200将收到的数据发回客户端
  60.                                        
  61.               }
  62.               disconnect(0);                                                                                        // 关闭Socket
  63.               ka_tick_flag=0;                                                                                        // KA定时器开始计时标志位清零
  64.               ka_send_flag=0;                                                                                        // KA发送标志位清零
  65.               ka_no_data_tick=0;                                                                        // 无数据传输时间计时器清零
  66.               ka_send_tick=0;                                                                                        // KA发送定时器清零
  67.               break;
  68.             case SOCK_CLOSED:                                                                                        // Socket处于关闭状态
  69.               socket(0, Sn_MR_TCP, 5000, 0x00);                // 重新打开Socket
  70.               break;
  71.                 }  
  72.         //}                 Sn_MR_UDP
  73. }
复制代码
二、迪文屏发送数据下位机接受

处理迪文屏触摸事件
  1. void USART3_IRQHandler(void)                        //串口1中断服务程序
  2. {
  3.         u16 y;
  4.         //u8 i;
  5.         
  6.         TIM_Cmd(TIM2, DISABLE);  //使能TIMx外设DISABLE
  7.         
  8.         if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收中断()
  9.          {

  10.                   USART_ClearITPendingBit(USART3,USART_IT_RXNE); //清除中断标志
  11.                   j_timer[j_num] =USART_ReceiveData(USART3);//(USART3->DR);        //读取接收到的数据
  12.                   j_num++;        //接收字节计数
  13.                   j_num&=0XFF;
  14.                   time_1=1;
  15.                  if(j_timer[j_num-1]==0x5A)  //判断是否接收正确 如果接收错误从新接收
  16.                         {
  17.                                 RX_URAT1=j_num-1;//接收字节计数
  18.       }
  19.                          if(j_num>20)
  20.                         {
  21.                            j_num=0;    //清除
  22.                            RX_URAT1=0;//清除
  23.                         }
  24.                   if(j_timer[2]==(j_num-3)&&j_timer[RX_URAT1]==0x5A)
  25.                   {
  26.                           j_num=0;    //清除
  27.                           RX_URAT1=0;//清除
  28.                                 shezhi=j_timer[4]<<8|j_timer[5]; //屏寄存器地址
  29.                                 
  30.                                 switch (shezhi)
  31.                                 {
  32.                                         case 0x0099:   //设置  界面密码
  33.                                            {
  34.                                                          if((j_timer[7]<<8|j_timer[8])==eep_read[10]||(j_timer[7]<<8|j_timer[8])==eep_read[1])//设置密码与开门密码相同  最高密码9999
  35.                                                          {                                       
  36.                                                                 send_hmi(2);//更换界面返回设定界面               
  37.                                                                 send_hmi(2);//更换界面返回设定界面        
  38.                                                                 send_hmi(2);//更换界面返回设定界面        
  39.                                                                 send_hmi(2);//更换界面返回设定界面        
  40.                 send_hmi(2);//更换界面返回设定界面                                                                        
  41.                                                          }
  42.                                                  }
  43.                                                   break;
  44.                                         case 0x0001://修改密码
  45.                                            {
  46.                                                                 mi_ma[0]=j_timer[7]<<8|j_timer[8];   //密码
  47.                                                                 if(mi_ma[0]>0&&mi_ma[0]==mi_ma[1])
  48.                                                                 {
  49.                                                                    send_hmi(2);//更换界面返回设定界面
  50.                                                                          eep_flag=1;                //写EEP标志位
  51.                                                                          eep_read[10] = mi_ma[0]; //开门及设置密码
  52.                                                                 }
  53.                                                         }
  54.                                             break;
  55.                                         case 0x0002:  //确认密码
  56.                                            {
  57.                                                          mi_ma[1]=j_timer[7]<<8|j_timer[8];  //确认密码
  58.                                                          if(mi_ma[1]>0&&mi_ma[0]==mi_ma[1])
  59.                                                                 {
  60.                                                                    send_hmi(2);//更换界面返回设定界面
  61.                                                                          eep_flag=1;                //写EEP标志位
  62.                                                                          eep_read[10] = mi_ma[1]; //开门及设置密码
  63.                                                                 }
  64.               }
  65.                                                 
  66.                                             break;
  67.                                         case 0x0080: //开门
  68.                                             {
  69.                                                                  if((j_timer[7]<<8|j_timer[8])==eep_read[10]||(j_timer[7]<<8|j_timer[8])==eep_read[1])
  70.                                                                   {
  71.                                                                            kz_flag[0]=1;//开门标志位
  72.                                                                                  //send_time();//读取时间
  73.                                                                   }
  74.               }
  75.                                             break;         
  76.                                                                                                                                        
  77.                                         case 0x0061:  //温控启动设定
  78.                                        {
  79.                                                 y=j_timer[7]<<8|j_timer[8];
  80.                                                 if(y>100)
  81.                                                             y=100;
  82.                                                                         eep_flag=1;                //写EEP标志位
  83.                                                                         eep_read[4] = y; //温度报警值
  84.                                                          }
  85.                                             break;
  86.                                         case 0x0065:  //散热设定
  87.                                              {
  88.                                                 y=j_timer[7]<<8|j_timer[8];
  89.                                                 if(y>100)
  90.                                                             y=100;
  91.                                                                         eep_flag=1;                //写EEP标志位
  92.                                                                         eep_read[12] = y; //散热设置
  93.                                                         }
  94.                                             break;
  95.                                         case 0x0092:  //湿度启动设定
  96.                                             {
  97.                                                 y=j_timer[7]<<8|j_timer[8];
  98.                                                 if(y>100)
  99.                                                             y=100;
  100.                                                                         eep_flag=1;                //写EEP标志位
  101.                                                                         eep_read[5] = y; //湿度报警值
  102.                                                         }
  103.                                             break;
  104.                                         case 0x0091:  //过压设定
  105.                                            {
  106.                                                 y=j_timer[7]<<8|j_timer[8];
  107.                                                 if(y>300)
  108.                                                             y=300;
  109.                                                                         eep_flag=1;                //写EEP标志位
  110.                                                                         eep_read[13] = y; //过压报警值
  111.                                                                 }
  112.                                             break;
  113.                                         case 0x0093:  //欠压电压报警设定
  114.                                            {
  115.                                                 y=j_timer[7]<<8|j_timer[8];
  116.                                                 if(y>300)
  117.                                                             y=300;
  118.                                                                         eep_flag=1;                //写EEP标志位
  119.                                                                         eep_read[2] = y; //欠压电压报警值
  120.                                                                 }
  121.                                             break;
  122.                                         case 0x0094:  //电流报警设定
  123.                                             {
  124.                                                 y=j_timer[7]<<8|j_timer[8];
  125.                                                 if(y>50)
  126.                                                             y=50;
  127.                                                                         eep_flag=1;                //写EEP标志位
  128.                                                                         eep_read[3] = y; //湿度报警值
  129.                                                                 }
  130.                                             break;
  131.                                         case 0x0098:  //IP1
  132.                                            {   Tcp_ip_connec_flag=1;
  133.                                                 y=j_timer[7]<<8|j_timer[8];
  134.                                                // if(y>50)
  135.                                                            // y=50;
  136.                                                                         eep_flag=1;                //写EEP标志位
  137.                                                                         eep_read[6] = y; //湿度报警值
  138.                                                  }
  139.                                             break;               
  140.                                         case 0x0097:  //IP1
  141.                                            {     Tcp_ip_connec_flag=1;
  142.                                                 y=j_timer[7]<<8|j_timer[8];
  143.                                                // if(y>50)
  144.                                                            // y=50;
  145.                                                                         eep_flag=1;                //写EEP标志位
  146.                                                                         eep_read[7] = y; //湿度报警值
  147.                                                         
  148.                                                 }
  149.                                             break;               
  150.            case 0x0096:  //IP1
  151.                                           {     Tcp_ip_connec_flag=1;
  152.                                                 y=j_timer[7]<<8|j_timer[8];
  153.                                                // if(y>50)
  154.                                                            // y=50;
  155.                                                                         eep_flag=1;                //写EEP标志位
  156.                                                                         eep_read[8] = y; //湿度报警值
  157.                                                             
  158.                                           }
  159.                                             break;                                       
  160.           case 0x0095:  //IP1
  161.                                           {    Tcp_ip_connec_flag=1;
  162.                                                 y=j_timer[7]<<8|j_timer[8];
  163.                                                // if(y>50)
  164.                                                            // y=50;
  165.                                                                         eep_flag=1;                //写EEP标志位
  166.                                                                         eep_read[9] = y; //湿度报警值
  167.                                                            
  168.                                           }
  169.                                             break;                                                               
  170.                                         case 0x0200:  //清除开门记录
  171.                                            {
  172.                                                 if((j_timer[7]<<8|j_timer[8])==eep_read[10]||(j_timer[7]<<8|j_timer[8])==eep_read[1])//设置密码与开门密码相同
  173.                                                 {
  174.                                                                                 clear_full(1);
  175.                                                                                 eep_flag=2;                //写EEP标志位
  176.                                                                         }
  177.                                                                 }
  178.                                             break;
  179.                                         case 0x0300:  //清除报警记录
  180.                                           {
  181.                                                             if((j_timer[7]<<8|j_timer[8])==eep_read[10]||(j_timer[7]<<8|j_timer[8])==eep_read[1])//设置密码与开门密码相同
  182.                                                 {
  183.                                                                                 clear_full(2);
  184.                                                                                 eep_flag=3;                //写EEP标志位
  185.                                                                         }
  186.                                                                 }
  187.                                             break;
  188.                                         case 0x2007:  //时间读取
  189.                                             {
  190.                                                 if(kz_flag[0]==1)        //开门标志位
  191.                                                                         {
  192.                                                                                 opendoor_full();//栈顶
  193.                                                                           opendoor_timer(j_timer,0); //存放缓存区
  194.                                                                                 opendoor_event++;         //计数器++
  195.                                                                                 eep_flag=2;                //写EEP标志位

  196.                                                                         }        
  197.                                                                         else if((kz_flag[3] == 0||flag_m[0]==0||flag_m[1]==0||flag_m[2]==0||flag_m[3]==0)) //烟雾报警        
  198.                                                                         {
  199.                                                                                 alarm_full();//栈顶
  200.                                                                           alarm_timer(j_timer,0); //存放缓存区
  201.                                                                                 alarm_event++;         //计数器++
  202.                                                                                 eep_flag=3;                //写EEP标志位               
  203.                                                                         }               
  204.                                                                 }                                                                        
  205.                                             break;
  206.                                         default:
  207.                                                 break;
  208.                                 }                                                                                                                 
  209.            }
  210.           if(USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET)
  211.           {
  212.                  USART_ClearFlag(USART3,USART_FLAG_ORE);//清除一处错误中断
  213.                  USART_ReceiveData(USART3);//
  214.     }
  215.                 TIM_Cmd(TIM2, ENABLE);  //使能TIMx外设DISABLE
  216.         }
  217.         
  218. }
  219.         
复制代码








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

6

主题

40

回帖

327

积分

中级会员

Rank: 3Rank: 3

积分
327
 楼主| 发表于 2021-4-27 14:24:49 | 显示全部楼层
硬件这块简单分析
总共三块电路板,有主控继电器板,信号采集板  ,以太网板
1.主控MCU

2.电量采集

基本原理如下
ADE7758 有六路模拟量输入,分成电流和电压两个通道。 流通道由三对差分电压输入,分别是 IAP,IAN;IBP,IBN;ICP,ICN。
前端采用TA12-100的电流互感器,检测三路电流给
ADE7758差分采样
,电压这块电压互感器ZMPT107 ,采集三路电压,最后并把采样数据通过SPI给单片机,再上传迪文屏显示

3.通讯这块



485和CAN通信都加入了数字隔离器ADUM1201ARZ,这样安全可靠,供电这块也采用电源隔离模块

4.以太网模块


采用W5200芯片实现网络通信,和单片机采用SPI连接,迪文屏可以设置IP地址


5.继电器打开风扇,门这块,还有温度报警不一一细说了



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

11

主题

37

回帖

367

积分

中级会员

Rank: 3Rank: 3

积分
367
发表于 2021-9-27 07:48:48 | 显示全部楼层
对这行不了解,看不懂,但要感谢楼主的奉献精神
回复

使用道具 举报

6

主题

40

回帖

327

积分

中级会员

Rank: 3Rank: 3

积分
327
 楼主| 发表于 2021-10-3 18:15:57 | 显示全部楼层
xz130587tec 发表于 2021-9-27 07:48
对这行不了解,看不懂,但要感谢楼主的奉献精神

非常感谢
回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-11-21 23:20 , Processed in 0.101623 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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