温室监控下位机部分

本文详细介绍了基于51普中开发板的温室监控系统代码,利用ModbusRTU通信协议,接收上位机通过串口发送的信息,根据接收到的数据控制不同操作。代码涉及CRC校验、线圈映射、寄存器读写等功能,实现了温度监控及报警功能。主函数中包含了串口初始化、温度传感器处理和数据处理循环。
摘要由CSDN通过智能技术生成

用的是51普中开发板

功能主要就是接收串口发送过来的信息,

然后根据接收到的信息执行不同的操作,

上位机部分链接:http://t.csdn.cn/evEle

先附上源码链接:(3条消息) 【免费】c#上位机(温室监控系统源码)资源-CSDN文库

通信协议采用modbusRTU

为了能方便的处理数据,在代码中把用到的管脚全都映射到数组上

本文主要介绍了一个用于温室监控系统的代码。该代码使用了多个库文件,包括"Delay.h"、"UART.h"、"DS18B20.h"、"Tool.h"和"Buzzer.h"等等。在代码中定义了一些函数和变量,用于处理Modbus通信、读写线圈和寄存器等操作。

代码解析

以下是代码中定义的一些重要函数和变量的解析:

  1. 函数

crc_cal_value:用于计算CRC校验值。

  1. 函数

ModbusCpu:用于处理接收到的Modbus报文。

  1. 函数

CoilMapper:将Coils数组中的数据映射到对应的GPIO口。

  1. 函数

writeCoils:用于写入线圈状态。

  1. 函数

readCoilsStatus:读取指定范围内的线圈状态。

  1. 函数

RegistersMapper:更新寄存器数据,包括读取温度和设置报警功能。

  1. 函数

TemperatureAlarmSetting:根据温度设置触发报警功能。

  1. 函数

resultKeepRegister:返回指定范围内的寄存器数据。

  1. 函数

SetSingleKeepRegister:设置单个寄存器的值。

  1. 函数

UART_Routine:串口中断处理程序,用于接收数据。

  1. 变量

SlaveAddr:Modbus从机的地址。

  1. 变量

Message:用于接收Modbus报文的数组。

  1. 变量

Coils:存储线圈状态的数组。

  1. 变量

Registers:存储寄存器数据的数组。

主函数

主函数中初始化了串口和温度传感器,并设定了报警温度的上限和下限。然后进入了一个死循环,在循环中调用了CoilMapper和RegistersMapper函数,实现了对线圈和寄存器的处理和更新。

#include <REGX52.H>
#include "Delay.h"
#include "UART.h"
#include "DS18B20.h"
#include "Tool.h"
#include "Buzzer.h"
//*************************************************** 函数
unsigned int crc_cal_value(unsigned char* data_value, unsigned char data_length);
void ModbusCpu();
void CoilMapper();
void writeCoils(int CoilsAddr,int onoff);
void readCoilsStatu(int startAddr,int coilsCount);
void RegistersMapper();
void resultKeepRegister(int StartAddr,int RegisterDataPort);
void TemperatureAlarmSetting(int* T);
void SetSigleKeepRegister(int StartAddr,int Value);
//***************************************************
char SlaveAddr=0x01;
unsigned char Message[8]={0x01,0x03,0x00,0x00,0x00,0x01};//用于接收报文
int mesgIndex=0;
unsigned int CRC;

char Coils[32];//线圈
int Registers[4];//寄存器
void main()
{
     DS18B20_ConvertT();        //上电先转换一次温度,防止第一次读数据错误
     Delay(500);
   UART_Init();    //串口初始化
     
    Registers[1]=50;//报警温度上限
    Registers[2]=-40;//报警温度下限
    while(1)
    {
         CoilMapper();
         RegistersMapper();
    }
}

void ModbusCpu()//处理接收到的报文
{
        CRC=crc_cal_value(Message,sizeof(Message)-2);
        if(Message[6]==(unsigned char)CRC &&  Message[7]==(unsigned char)(CRC>>8))//验证CRC 验证接收到的数据是否正确
        {   
              int Count;
                int Addr=(Message[2]<<8);//
                Addr|=Message[3];
              Count=(Message[4]<<8);
                Count|=Message[5];
                switch(Message[1])//判断功能码
                {
                    case 0x05:writeCoils(Addr,Message[4]==0xFF?1:0);
                        break;
                    case 0x01:readCoilsStatu(Addr,Count);
                                break;
                    case 0x03:resultKeepRegister(Addr,Count);
                                break;
                        case 0x06:SetSigleKeepRegister(Addr,Count);//this Count is Value
                                break;
                }
        }
}


 void writeCoils(int CoilsAddr,int onoff)
 {
     if(CoilsAddr>=sizeof(Coils)||CoilsAddr<0)
         return;
     Coils[CoilsAddr]=onoff;
 }
void readCoilsStatu(int startAddr,int coilsCount)
{
     unsigned int crc;
   int datalen=((coilsCount/8)+(coilsCount%8>0?1:0));
     int retuleMsgLenth=3;
     unsigned char retuleMsg[sizeof(Coils)+3];
     char i=0;
     char temp=0x00;//表示一个字节的数据(表示8个线圈)
     char tempIndex=1;
     retuleMsg[0]=SlaveAddr;
     retuleMsg[1]=0x01;
     retuleMsg[2]=(char)datalen;
    
    
     for(i=startAddr;i<(startAddr+coilsCount);i++)
    {
         if(i>=sizeof(Coils))break;
         temp|=(Coils[i]<<tempIndex++);
         if(tempIndex>=9)
         {
             tempIndex=1;
             retuleMsg[retuleMsgLenth++]=temp;
         }
    }
    if(tempIndex!=1 && tempIndex<=8)
    {
         retuleMsg[retuleMsgLenth++]=temp;
    }
     crc =crc_cal_value(retuleMsg,retuleMsgLenth);
     retuleMsg[retuleMsgLenth++]=(unsigned char)crc;
     retuleMsg[retuleMsgLenth++]=(unsigned char)(crc>>8);
     SendMessage(retuleMsg,retuleMsgLenth);
}
void RegistersMapper()
{
     int T=0;
     DS18B20_ConvertT();    //转换温度
     T=DS18B20_ReadT();    //读取温度
   TemperatureAlarmSetting(&T);
     
     Registers[0]=T;
}
void TemperatureAlarmSetting(int* T)
{
     if(*T>Registers[1]||*T<Registers[2])
     {
           Buzzer_Time(100);
     }
}
 void resultKeepRegister(int StartAddr,int RegisterDataPort)
 {
      char i=0;
      unsigned int crc;
      unsigned char retuleMsg[sizeof(Registers)+3];
      char retuleMsgLenth=3;
      retuleMsg[0]=SlaveAddr;
      retuleMsg[1]=0x03;
      retuleMsg[2]=((char)RegisterDataPort)*2;
     
      for(i=StartAddr;i<(StartAddr+RegisterDataPort);i++)
      {
           if(i<0||i>=sizeof(Registers))break;
             retuleMsg[retuleMsgLenth++]=Registers[i]>>8;//高位
             retuleMsg[retuleMsgLenth++]=(Registers[i]<<8)>>8;//低位
      }
      crc =crc_cal_value(retuleMsg,retuleMsgLenth);
      retuleMsg[retuleMsgLenth++]=(unsigned char)crc;
      retuleMsg[retuleMsgLenth++]=(unsigned char)(crc>>8);
      SendMessage(retuleMsg,retuleMsgLenth);
 }
 void SetSigleKeepRegister(int StartAddr,int Value)
 {
      if(StartAddr<0||StartAddr>sizeof(Registers))return;
      Registers[StartAddr]=Value;
 }
void UART_Routine() interrupt 4
{
    if(RI==1)                    //如果接收标志位为1,接收到了数据
    {
          // P2=~SBUF;                //读取数据,取反后输出到LED
        if(mesgIndex>=8)return;
            Message[mesgIndex]=SBUF;//
          mesgIndex++;
            if(mesgIndex>=8)
            {
                mesgIndex=0;
                ModbusCpu();
            }
        RI=0;                    //接收标志位清0
    }
    
}
void CoilMapper()
{
   P0_0=Coils[0];
     P0_1=Coils[1];
     P0_2=Coils[2];
     P0_3=Coils[3];
     P0_4=Coils[4];
     P0_5=Coils[5];
     P0_6=Coils[6];
     P0_7=Coils[7];
    
     P1_0=Coils[8];
     P1_1=Coils[9];
     P1_2=Coils[10];
     P1_3=Coils[11];
     P1_4=Coils[12];
     P1_5=Coils[13];
     P1_6=Coils[14];
     P1_7=Coils[15];
    
     P2_0=Coils[16]==1?0:1;
     P2_1=Coils[17]==1?0:1;
     P2_2=Coils[18]==1?0:1;
     P2_3=Coils[19]==1?0:1;
     P2_4=Coils[20]==1?0:1;
     P2_5=Coils[21]==1?0:1;
     P2_6=Coils[22]==1?0:1;
     P2_7=Coils[23]==1?0:1;
     
}
 
  

总结

该代码实现了一个基本的温室监控系统,使用了Modbus通信协议,并通过GPIO口控制了线圈状态和读取了温度传感器数据。读取的数据进行相应的处理,如报警功能等。在主函数中将不断循环执行这些功能,实现了温室监控系统的基本功能。

以上是对给定代码的简要解析,希望对你有所帮助。如有任何疑问,请随时向我提问。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值