⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbus.c

📁 基于PIC 18f 系列的485通讯原程序
💻 C
字号:
#include "p18f8490.h"
//#include "Parameter.h"
//#include "Com_parameter.h"
//#include "VARbits.h"
#include "pindefine.h"
#include "Parameter.h"
#include  "variable.h"
void SendModbusData(unsigned char command,unsigned int RegAdd,unsigned int RegNum);
void CRC16(unsigned char *data,int len);
void ModbusCheck(void);
void Senddata(unsigned Len);
//void keyerr(void);
//void Writepara(unsigned int RegAdd,unsigned char len);
void CRC16(unsigned char *data,int len)
{
	unsigned char CL,CH,SaveHi,SaveLo,Flag;
	int i;
    CRC16Lo = 0xFF;
    CRC16Hi = 0xFF;
    CL = 0x01;
    CH = 0xA0;
    for (i=0;i<len;i++)
	{
        CRC16Lo=CRC16Lo^data[i]; 			//每一个数据与CRC寄存器进行异或
        for(Flag=0;Flag<8;Flag++)
		{
          	SaveHi=CRC16Hi;
          	SaveLo=CRC16Lo;
          	CRC16Hi=CRC16Hi>>1;            ///高位右移一位
          	CRC16Lo=CRC16Lo>>1;            //低位右移一位
          	if ((SaveHi&1) == 1)
			{
				CRC16Lo=CRC16Lo|0x80;	   //如果高位字节最后一位为1
			}
                                                          //则低位字节右移后前面补1
                                                        //否则自动补0
          	if ((SaveLo&1) == 1)                            //如果LSB为1,则与多项式码进行异或
		  	{
				CRC16Hi=CRC16Hi^CH;
            	CRC16Lo=CRC16Lo^CL;
		  	}
        }
	}
}



void SendModbusData(unsigned char command,unsigned int RegAdd,unsigned int RegNum)
{
  	unsigned int i,Len,j,BcdH,BcdL,K;
    
  	UART_buff[0] = Para[Add];					
  	UART_buff[1] = command;
    if(RegNum<1)   RegNum = 1;
	Len = 3;
////////////////////////////////////////读数据寄存器///////////////////////////////////// 
    if(command==0x03)                    
     {
       if(((RegAdd+RegNum)>7)||(RegAdd<1))
          {                                               
             UART_buff[1] = command|0x80;  //读数据寄存器越界
             UART_buff[2] = 0x02;
             Len = 3;
          }
        else
        {
            j = RegAdd;
            i = 0;
            while(i<RegNum)
            {
                if(j==1)     
                     UART_buff[Len++] = 0xff;
                else if(j==2)                   //开关量
                     UART_buff[Len++] = IO_InPort;
                else if(j==3) 
                   {
                      BcdH = AD_result[0]/100;      //A路温度
                      K = AD_result[0]%100;
                      BcdL = K/10;
                      UART_buff[Len++] = (BcdH<<4)|BcdL;
                      BcdH = K%10;
                      UART_buff[Len++] = (BcdH<<4);
                   }
                else if(j==4)                       //A路湿度
                   {
                      BcdH = HumidityData[0]/10;
                      BcdL = HumidityData[0]%10;
                      UART_buff[Len++] = (BcdH<<4)|BcdL;
                   }  
                else if(j==5)                      //B路温度
                   {
                      BcdH = AD_result[1]/100;
                      K = AD_result[1]%100;
                      BcdL = K/10;
                      UART_buff[Len++] = (BcdH<<4)|BcdL;
                      BcdH = K%10;
                      UART_buff[Len++] = (BcdH<<4);
                   }
                else if(j==6)                        //B路湿度
                   {
                      BcdH = HumidityData[1]/10;
                      BcdL = HumidityData[1]%10;
                      UART_buff[Len++] = (BcdH<<4)|BcdL;
                   }  
                   i++;
                   j++;             
            }
            UART_buff[2] = Len - 3;
        }

     }
/////////////////////////////////读参数寄存器//////////////////////////////////////////
   else if(command == 0x04)
      {
          if(((RegAdd+RegNum)>10)||(RegAdd<2))
          {
             UART_buff[1] = command|0x80;  //读数据寄存器越界
             UART_buff[2] = 0x02;
             Len = 3;
          }   
          else
          {
             j = RegAdd;
             i = 0;
            while(i<RegNum)
             {
	             if(j==2)     
	                     UART_buff[Len++] = Para[Add];
	             else if(j==3) 
	                     UART_buff[Len++] = Para[Baud];
	             else if(j==4) 
                       {
                          BcdH = Para[TempHigh]/10;
                          BcdL = Para[TempHigh]%10;
                          UART_buff[Len++] = (BcdH<<4)|BcdL;
                      }  
	             else if(j==5) 
                       {
                          BcdH = Para[TempLow]/10;
                          BcdL = Para[TempLow]%10;
                          UART_buff[Len++] = (BcdH<<4)|BcdL;
                       }
	             else if(j==6) 
                       {
                          BcdH = Para[HumidityHigh]/10;
                          BcdL = Para[HumidityHigh]%10;
                          UART_buff[Len++] = (BcdH<<4)|BcdL;
                       }
	             else if(j==7) 
                       {
                          BcdH = Para[HumidityLow]/10;
                          BcdL = Para[HumidityLow]%10;
                          UART_buff[Len++] = (BcdH<<4)|BcdL;
                       }
	             else if(j==8) 
                       {
                          BcdH = Para[WindHigh]/10;
                          BcdL = Para[WindHigh]%10;
                          UART_buff[Len++] = (BcdH<<4)|BcdL;
                       }
	             else if(j==9) 
                       {
                          BcdH = Para[WindLow]/10;
                          BcdL = Para[WindLow]%10;
                          UART_buff[Len++] = (BcdH<<4)|BcdL;
                       }
                 i++;
                 j++;
             }
           UART_buff[2] = Len - 3;
          }     
      }
      Senddata(Len);
}

void ModbusCheck(void)
{
   unsigned char   i,len,command;
   unsigned int   RegAdd,RegNum;
   if(RXD_num>=8)
     {
       /*  for(i=0;i<RXD_num;i++)
          {
	             if((UART_buff[i+0]==Para[Add])&&((UART_buff[i+1]==0x03)||(UART_buff[i+1]==0x04))&&((RXD_num-i)>=0x08))
	                {
	
	                    CRC16(&UART_buff[i+0],6);
	                   	if((CRC16Lo==UART_buff[i+6])&&(CRC16Hi==UART_buff[i+7]))		//效验正确
	                       {
	                            RegAdd=UART_buff[i+2]*256+UART_buff[i+3];
		                        RegNum=UART_buff[i+4]*256+UART_buff[i+5];
	                            command = UART_buff[i+1];
	                            PIE3bits.RC2IE = 0;
	                            RXD_num=0;
	                            SendModbusData(command,RegAdd,RegNum);
	                       }
	                }
                 else if((UART_buff[i+0]==Para[Add])&&(UART_buff[i+1]==0x05))
                   {
                         len = UART_buff[i+2];
                         if((RXD_num-i)>=(len+5))
                         {
                            CRC16(&UART_buff[i+0],len+3); 
                            if((CRC16Lo==UART_buff[i+len+3])&&(CRC16Hi==UART_buff[i+len+3+1]))		//效验正确
                             {
                                if((UART_buff[i+5]==0x66)&&(UART_buff[i+5]==0x66))   //密码固定为6666
                                   {
                                       RegAdd = UART_buff[i+3]*256+UART_buff[i+4];
                                      // Writepara(RegAdd,len-4);
                                   }
                               // else           keyerr();
                             }
                         }
                   }
          }
         RXD_num=0;*/
     }
}

void keyerr(void)
{
   	unsigned int Len;
    
  	UART_buff[0] = Para[Add];					
  	UART_buff[1] = 0x85;
    UART_buff[2] = 0x04;
	Len = 3; 
    Senddata(Len);
}
/*
void Writepara(unsigned int RegAdd,unsigned char len)
{
    unsigned char Len;
      if((RegAdd<2)||(RegAdd>9))
          {
             UART_buff[1] = 0x85;  //读数据寄存器越界
             UART_buff[2] = 0x02;
             Len = 3;
          }   
        else
          {
             if(len>1) 
               {
                 UART_buff[1] = 0x85;  //读数据寄存器越界
                 UART_buff[2] = 0x03;   //数据超长无效
                 Len = 3;
               } 
              else
               {
                 UART_buff[1] = 0x85;
                  if( RegAdd>3)
                    {
	                  if(((UART_buff[7]&0x0f)>9)||(((UART_buff[7]&0xf0)>>4)>9))
	                   {
	                     UART_buff[1] = 0x85;  //读数据寄存器越界
	                     UART_buff[2] = 0x03;   //数据超长无效
	                     Len = 3;
                         Senddata(Len);;
                         return;
                       }
                    }                     
		             if(RegAdd==2)     
		                     Para[Add] = UART_buff[7];   //修改通信地址 
	                 else if(RegAdd==3)
	                         Para[Baud] = UART_buff[7];  //修改波特率   
	                 else if(RegAdd==4) 
	                         Para[TempHigh] = ((UART_buff[7]&0xf0)>>4)*10 + UART_buff[7]&0x0f;  //温度上限 
	                 else if(RegAdd==5) 
	                         Para[TempLow] = ((UART_buff[7]&0xf0)>>4)*10 + UART_buff[7]&0x0f;  //温度下限 
	                 else if(RegAdd==6) 
	                         Para[HumidityHigh] = ((UART_buff[7]&0xf0)>>4)*10 + UART_buff[7]&0x0f;  //湿度上限 
	                 else if(RegAdd==7) 
	                         Para[HumidityLow] = ((UART_buff[7]&0xf0)>>4)*10 + UART_buff[7]&0x0f;  //湿度下限 
	                 else if(RegAdd==8) 
	                         Para[WindHigh] = ((UART_buff[7]&0xf0)>>4)*10 + UART_buff[7]&0x0f;  //排风上限 
	                 else if(RegAdd==8) 
	                         Para[WindLow] = ((UART_buff[7]&0xf0)>>4)*10 + UART_buff[7]&0x0f;  //排风下限 	                           
                    UART_buff[1] = 0x05;   //读数据寄存器越界
	                UART_buff[2] = UART_buff[3];   //数据超长无效
                    UART_buff[3] = UART_buff[4];   //数据超长无效
	                Len = 4;
                 } 
               
          }
         Senddata(Len);
}  
*/
void Senddata(unsigned Len)
 {
         CRC16(&UART_buff[0],Len);
  	     UART_buff[Len]=CRC16Lo;
  	     UART_buff[Len+1]=CRC16Hi;
	     TX_Allnum = Len+2;
         TX_num = 0;
         PIR3bits.TX2IF = 0;
         PIE3bits.TX2IE = 1;
         TXSTA2bits.TXEN = 1;

 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -