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

📄 jk0061119_communication._h

📁 Modbus RTU 的C语言程序
💻 _H
字号:
unsigned int  calcul_value_decimal(unsigned int c,unsigned int a);
char   change_HEX_to_ASCLL(char *ptr,char len);
//////////////////////////////////////////////////////////////////
char pow2pow(char X)
{
   char i,c=1;
  if(X)
   {
    for(i=0; i<X; i++)
	   c*=2;  
	 }
   return c; 
 }
//////通讯部分程序
///////////////////////////////////////////////////////////////////////
unsigned short getCRC16( char *ptr, char len)
{
     char i;
	unsigned short crc=0xFFFF;
	while(len--) 
	  {  
	     crc^=*ptr;
         for(i=0; i<8; i++) 
		 {
           if(crc&1)
		     {
			   crc>>=1; 
			   crc^=0xA001;
			  } 
			else
			   crc>>=1;
           }
         ptr++;
       }
    return(crc);
 }
 ////////////////////////////////////
unsigned short getCRC12( char *ptr, char len)
{
   char i;
   unsigned short crc=0x0000;
   while(len--) 
     {
	    
	    for(i=0x80;i!=0;i>>=1)
		   {
		      if((crc&0x800)!=0)
		        {   
				   crc<<=1;
			       crc^=0x80D;
				 }
				else
				   crc<<=1;
			crc&=0xFFF;
			   if((*ptr&i)!=0)
			      crc^=0x80D;
		    }
		ptr++;
	  }
	return(crc);
 }
//TIMER0 initialisation - prescale:1024
// WGM: Normal
// desired value: 13mSec
// actual value: 12.917mSec (0.6%)
void timer0_init(void)
{
 TCCR0= 0x00; //stop
 TCNT0= 0xA3; //set count
 OCR0= 0x2B; //set compare value
 TCCR0= 0x05; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:18
void timer0_ovf_isr(void)
{
 TCNT0= 0xA3; //set count
 if(Time0_Ovf_com0_ProgramBranch==0)
	Com0_R_Cout=0;   
 else
   {
	  Com0_R_Complete=1;
	  Com0_R_CRCcouter=Com0_R_Cout-2;
	  UCSR0B = 0xC8;///close the receiveing  interrupt
	  Time0_Ovf_com0_ProgramBranch=0;
	}
}
//UART0 initialisation
// desired baud rate: 9600
// actual: baud rate:9600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
 UCSR0B = 0x00; //disable while setting baud rate
 UCSR0A = 0x00; //disable while setting baud rate
 UBRR0L  =0x2F; //set baud rate
 UBRR0H = 0x00;
 UCSR0C = 0x86;
 UCSR0A = 0x00; //enable
 UCSR0B = 0xD8; //enable
}

#pragma interrupt_handler uart0_rx_isr:20
void uart0_rx_isr(void)
{
 //uart has received a character in UDR
   Com0_R_Data[Com0_R_Cout]=UDR0;
	   if(Com0_R_Data[0]==Com0_S_Data[0])
	     {
		   if(Com0_R_Cout<18)
	          Com0_R_Cout++;
	       Time0_Ovf_com0_ProgramBranch=1;
	      }	 
       else
        { 
	       Com0_R_Cout=1;
	       Time0_Ovf_com0_ProgramBranch=0;
	     }   
     TCNT0=0xB9; 
}

#pragma interrupt_handler uart0_tx_isr:24
void uart0_tx_isr(void)
{
 //character has been transmitted
   Com0_S_Pointer++;
   Com0_S_DataByte=Com0_S_DataByte-1;
   if(Com0_S_DataByte>0)
      UDR0=*Com0_S_Pointer;
}
///////////////////////////////////////////////////////////////
char  Modbus_Function_1(char *Ptr_receive,char *Ptr_send)
{
   unsigned char  a, b,c,i;
    unsigned int temp;
    Ptr_send[1]=0x01;
	if((Ptr_receive[2]==0)&&(Ptr_receive[3]<=32))
	   {
		  if(Ptr_receive[3]+Ptr_receive[5]<=32) 
		    {
			    a=Ptr_receive[3]>>3;
				b=Ptr_receive[3]&0x07;
				c=Ptr_receive[5]+b;
				//Com0_S_DataByte=4+(Com0_R_Data[5]>>3);
				Ptr_send[2]=Ptr_receive[5]>>3;
				if(Ptr_receive[5]&0x07)
				   Ptr_send[2]+=1;
				
				//Com0_S_DataByte=Com0_S_Data[2]+3;
				if(c&0x07)
				 c=(c>>3)+1;
				 else
				 c=c>>3;
				for(i=0;i<c;i++)
				  {
				      temp=JK_IO[a];
					  a++;
					  temp+=(JK_IO[a]<<8);
					  temp>>=b;
					  Ptr_send[i+3]=temp&0xff;
				   }
				 Ptr_send[i+3]=temp>>8;
				 Ptr_send[i+3]<<=(8-Ptr_receive[5]&0x07);
				 Ptr_send[i+3]>>=(8-Ptr_receive[5]&0x07);
			 }
		   else
		    {////show   error!
		     Ptr_send[1]=0xFF;
		     Ptr_send[2]=2;
			 Ptr_send[3]=0x00;
			 Ptr_send[4]=0x01;
		    }
		}
	 else
	  {////show   error!
	     Ptr_send[1]=0xFF;
	     Ptr_send[2]=2;
		 Ptr_send[3]=0x00;
		 Ptr_send[4]=0x02; 
	   }
	return(Ptr_send[2]+3);
 }
/////////////////////////////////////////////////////////////
char  Modbus_Function_3(char *Ptr_receive,char *Ptr_send)
{
   char  i,a,b;
  Ptr_send[1]=0x03;
  if((Ptr_receive[2]==0)&&(Ptr_receive[3]<=30)) 
	 {
	   if(Ptr_receive[3]+Ptr_receive[5]<=30)    
	      {
			Ptr_send[2]=2*Ptr_receive[5];
			a=Ptr_receive[3];
			b=Ptr_receive[5]*2;
			for(i=0;i<b;i++)
			  {
	            Ptr_send[3+i]=JK_Value[2*a+i];
			   }
		   }
		
	   }
	else
	  {
	         ////show   error!
		     Ptr_send[1]=0xFF;
		     Ptr_send[2]=2;
			 Ptr_send[3]=0x00;
			 Ptr_send[4]=0x04;
	   }
  return(Ptr_send[2]+3);
}
////////////////////////////////////////////////////////////
char  Modbus_Function_5(char *Ptr_receive,char *Ptr_send)
{
     char  c;
    Ptr_send[1]=0x05;
	Ptr_send[2]=Ptr_receive[2];
	Ptr_send[3]=Ptr_receive[3];
	Ptr_send[4]=Ptr_receive[4];
	Ptr_send[5]=Ptr_receive[5];
	c=6;
	if((Ptr_receive[2]==0)&&(Ptr_receive[3]==0))
	   {
	       if((Ptr_receive[4]==0xFF)&&(Ptr_receive[5]==0x00))
		      {
			      Flag_JC_FC=1;
	              JK_IO[0]|=0x01;
			   }
		    else if((Ptr_receive[4]==0x00)&&(Ptr_receive[5]==0x00))
			   {
			      Flag_JC_FC=0;
	              JK_IO[0]&=0xFE;
			    }
			else
			   {
			       ////show   error!
		         Ptr_send[1]=0xFF;
		         Ptr_send[2]=2;
			     Ptr_send[3]=0x00;
			     Ptr_send[4]=0x05;
				 c=5;
			    }
	    }
	else
	   {
	       ////show   error!
		         Ptr_send[1]=0xFF;
		         Ptr_send[2]=2;
			     Ptr_send[3]=0x00;
			     Ptr_send[4]=0x06;
				 c=5;
	    }
     return(c);
 }
char  Modbus_Function_16(char *Ptr_receive,char *Ptr_send)
{
    char  i,c;
	unsigned int  Var_temp;
	Ptr_send[1]=0x10;
    Ptr_send[2]=Ptr_receive[2];
    Ptr_send[3]=Ptr_receive[3];
	i=Ptr_receive[3];
	///////////////////////////////////////////////////////
    Ptr_send[4]=Ptr_receive[4];
    Ptr_send[5]=Ptr_receive[5];
	c=6;
	if(Ptr_receive[2]==0)
	  {
		   if((i>5)&&(i<28))
		     {
			     JK_Value[2*i]=Ptr_receive[7];
	             JK_Value[2*i+1]=Ptr_receive[8];
			     Var_temp=(int)Ptr_receive[7]<<8;
				  Var_temp|=(int)Ptr_receive[8];
				  if(ram_array[i-6]!=Var_temp)
				    {
			          EEPROMwrite((int)&EEprom_array[2*i-12],Ptr_receive[7]);
				      EEPROMwrite((int)&EEprom_array[2*i-11],Ptr_receive[8]);
				      WDR();
					  ram_array[i-6]=Var_temp;
					 }
			  }
		   else if(i==28)
		     {
			    if(JK_Value[57]!=Ptr_receive[8])
				   {
			        EEPROMwrite((int)&Address_JK,Ptr_receive[8]);
				    Com0_S_Data[0]=Ptr_receive[8];
				    JK_Value[56]=0;
		            JK_Value[57]=Ptr_receive[8];
				    }
			  }
			else
			 {
			    ////show   error!
		         Ptr_send[1]=0xFF;
		         Ptr_send[2]=2;
			     Ptr_send[3]=0x00;
			     Ptr_send[4]=0x07;
				 c=5;
			  }
	   }
	 else
	   {
	      ////show   error!
		         Ptr_send[1]=0xFF;
		         Ptr_send[2]=2;
			     Ptr_send[3]=0x00;
			     Ptr_send[4]=0x08;
				 c=5;
	    }
	 return(c); 
 }
//call this routine to treat with the com1 of receiving data queues
void Com0_Receive_Datas(void)
{
   unsigned short crcresult;
    char   temp[2],r=1;
   crcresult= getCRC16(Com0_R_Data,Com0_R_CRCcouter);
   temp[1]=crcresult & 0xff;
   temp[0]=(crcresult >> 8) & 0xff;
   if((Com0_R_Data[Com0_R_CRCcouter+1]==temp[0])&&(Com0_R_Data[Com0_R_CRCcouter]==temp[1]))
      {
	     PORTD^=0x80;
		 if(Com0_R_Data[1]==1)
		      r=Modbus_Function_1(Com0_R_Data,Com0_S_Data);
		 else if(Com0_R_Data[1]==3)
		      r=Modbus_Function_3(Com0_R_Data,Com0_S_Data);
		 else if(Com0_R_Data[1]==5)
		      r=Modbus_Function_5(Com0_R_Data,Com0_S_Data);
		 else if(Com0_R_Data[1]==16)
		      r=Modbus_Function_16(Com0_R_Data,Com0_S_Data);
			  else
			    {
				    ////show   error!	  
		            //Com0_S_Data[1]=0xFF;
		            //Com0_S_Data[2]=2;
		             r=5;
		            //Com0_S_Data[3]=0x00;
		            //Com0_S_Data[4]=0x09;
			      }
		 }
   else
	  {
	    ////show   error!	  
		  Com0_S_Data[1]=0xFF;
		  Com0_S_Data[2]=2;
		  r=5;
		  Com0_S_Data[3]=0x00;
		  Com0_S_Data[4]=0x0A; 
	   }
   crcresult= getCRC16(Com0_S_Data,r);
   Com0_S_Data[r]=crcresult & 0xff;
   Com0_S_Data[r+1]=(crcresult >> 8) & 0xff;
   Com0_S_DataByte=r+2;
   Com0_S_Pointer=Com0_S_Data;
   UDR0=*Com0_S_Pointer;
   ///////////////////////////////////
   Com0_R_Complete=0;
   UCSR0B = 0xD8;  
}
//UART1 initialisation
// desired baud rate:9600
// actual baud rate:9600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart1_init(void)
{
 UCSR1B = 0x00; //disable while setting baud rate
 UCSR1A = 0x00; //disable while setting baud rate
 UBRR1L  =0x2F; //set baud rate
 UBRR1H = 0x00;
 UCSR1C = 0x86;
 UCSR1A = 0x00; //enable
 UCSR1B = 0xD8; //enable
}

#pragma interrupt_handler uart1_rx_isr:21
void uart1_rx_isr(void)
{
 //uart has received a character in UDR
    Com1_R_Data[Com1_R_Cout]=UDR1;
	if(Com1_R_Cout<30)
    Com1_R_Cout++;
	//if(Com1_R_Cout>=16)
	if(Com1_R_Data[Com1_R_Cout-1]==0x0D)
	  {
	    Com1_R_Complete=1;
		UCSR1B = 0x00; //disable while setting baud rate
        UCSR1A = 0x00; 
		}
}

#pragma interrupt_handler uart1_tx_isr:25
void uart1_tx_isr(void)
{
 //character has been transmitted
   Com1_S_Byte_UCSR1B++;
   if(Com1_S_Byte_UCSR1B==03)
     UCSR1B = 0xDC;
   Com1_S_Pointer++;
   Com1_S_DataByte=Com1_S_DataByte-1;
   if(Com1_S_DataByte>0)
      UDR1=*Com1_S_Pointer;
}
/////////////////////////
//void float_long_temp(void)
//{
    //MK_float_num.a=V_MK_float_num_temp;
	//MK_float_num.a*=300;
	//MK_float_num.a/=4095;
	//Com1_S_Data1[6]=MK_float_num.num[0];
	//Com1_S_Data1[7]=MK_float_num.num[1];
	//Com1_S_Data1[8]=MK_float_num.num[2];
	//Com1_S_Data1[9]=MK_float_num.num[3];
	//Com1_S_DataByte=change_HEX_to_ASCLL(Com1_S_Data1,10);
// }
///////////////////////
//call this routine to treat with the com0 of sending data queues
void Com1_Send_Datas(void)
{
   unsigned int crcresult,A_CD_Current_temp;
   float temp_temp;
   unsigned char  i,temp;
   Com1_R_Cout=0;
   Com1_S_Byte_UCSR1B=0;
   UCSR1B = 0xDD;
   if(Master_Com1_S_Data_flag==1)
      {
	      //////////////////////////////////模块通讯故障记录
		  if(MK_Communication_Error[Master_Com1_S_Data_flag_ID-1]<200)
		    MK_Communication_Error[Master_Com1_S_Data_flag_ID-1]++;
		  /////////////////////////////////////
	      Master_Com1_S_Data_flag=2;
		  Com1_S_Data2[0]=Master_Com1_S_Data_flag_ID;
		  Com1_S_DataByte=change_HEX_to_ASCLL(Com1_S_Data2,4); 
	   }
   else if(Master_Com1_S_Data_flag==2)
      {
	      Master_Com1_S_Data_flag=10;
		  Com1_S_Data3[0]=Master_Com1_S_Data_flag_ID;
		  Com1_S_DataByte=change_HEX_to_ASCLL(Com1_S_Data3,4); 
	   }
   else if(Master_Com1_S_Data_flag==8)//发调流广播命令
      {
	      Master_Com1_S_Data_flag=9;
		  if(Flag_JC_FC)
		    {
			    crcresult=calcul_value_decimal(A_KM_Load_Current,*A_Current_Sensor);
			    crcresult+=*A_Current_JC;
				temp_temp=crcresult;
				MK_float_num.a=temp_temp;
				MK_float_num.a/=JK_Value[49];
				MK_float_num.a/=ram_array[19];
			 }
		  else
		    {
			    MK_float_num.a=1.0;
			 }
		  Com1_S_Data2[4]=0x01;
		  //Com1_S_Data2[5]=0x1A;
		  Com1_S_Data2[6]=MK_float_num.num[0];
		  Com1_S_Data2[7]=MK_float_num.num[1];
		  Com1_S_Data2[8]=MK_float_num.num[2];
		  Com1_S_Data2[9]=MK_float_num.num[3];
		  Com1_S_DataByte=change_HEX_to_ASCLL(Com1_S_Data1,10);
	   }
   else/////////发调压广播命令
      {
	       temp_temp=A_MK_OUTPUT;
	  ////////////////////////////
	       A_MK_OUTPUT=0;
	  /////////////////////////////////
	  Var_temp_int=temp_temp;////////////////以下三行为模块电流
	  JK_Value[59]=Var_temp_int & 0xff;
	  JK_Value[58]=(Var_temp_int >> 8) & 0xff;
	  ///////////////////////////////////以下部分行,模块故障数据处理
	  JK_IO[2]=0;
	  JK_IO[3]=0;
	  for(i=0; i<JK_Value[49]; i++)	
	    {
		   if(MK_Communication_Error[i]>20)
		      {
			      if(i>8)
			          JK_IO[3]|=pow2pow(i-8);
			      else 
			          JK_IO[2]|=pow2pow(i);
			   }
		      
		 }
	  JK_IO[2]|=MK_error[0];
	  JK_IO[3]|=MK_error[1];
	  MK_error[0]=0;
	  MK_error[1]=0;
	  ////////////////////////////////////////////////////////
	       Master_Com1_S_Data_flag=10;
		   if(Flag_JC_FC)
		       temp_temp=*v_MK_JC_Voltage;
		   else
		       temp_temp=*v_MK_FC_Voltage;
			   temp_temp*=300;
			   MK_float_num.a=temp_temp;
			   MK_float_num.a/=4095;
			   Com1_S_Data2[4]=0x07;
			   //Com1_S_Data2[5]=0x1A;
			   Com1_S_Data1[6]=MK_float_num.num[0];
			   Com1_S_Data1[7]=MK_float_num.num[1];
			   Com1_S_Data1[8]=MK_float_num.num[2];
			   Com1_S_Data1[9]=MK_float_num.num[3];
			   Com1_S_DataByte=change_HEX_to_ASCLL(Com1_S_Data1,10);
	   }
    crcresult=getCRC12(Com1_S_Data+1,Com1_S_DataByte);
	Com1_S_DataByte++;
	for(i=0;i<4;i++)
	 {
		temp=crcresult&0x000F;
		if(temp>0x09)
		 temp+=0x07;
		Com1_S_Data[Com1_S_DataByte+i]=temp+0x30;
		crcresult>>=4;
	  }
	Com1_S_Data[Com1_S_DataByte+i]=0x0D;
	Com1_S_DataByte+=5;
	Com1_S_Pointer=Com1_S_Data;
	UDR1=*Com1_S_Pointer;
}
//call this routine to treat with the com1 of receiving data queues
void Com1_Receive_Datas(void)
{
   unsigned short crcresult;
   unsigned short   temp=0;
   char i,K;
   K=Com1_R_Cout;
   Com1_R_Cout=0;
   crcresult= getCRC12(Com1_R_Data+1,K-6);
   for(i=K-2;i>K-6;i--)
    {
	     temp<<=4;
	    if(Com1_R_Data[i]>0x39)
		  Com1_R_Data[i]-=7;
		  temp|=(Com1_R_Data[i]-0x30);
	  }
   if(temp==crcresult)
    {
	   
	   
	   PORTD^=0x80;//通讯正常  灯闪烁!
	   ///////////////////////////////////
	   K=Com1_R_Data[2]-0x30;
	   if(Com1_R_Data[1]>0x39)
		 Com1_R_Data[1]-=7;
	   K=K*10+Com1_R_Data[1]-0x30;
	   MK_Communication_Error[K-1]=0;
	   //////////////////////////////////
	   if(Com1_R_Data[3]==0x33)///////////////0x43命令接收
	     {
		    
			if(Com1_R_Data[9]==0x31)
			  {
			    if(K>8)
			          MK_error[1]|=pow2pow(K-8);
			    else 
			          MK_error[0]|=pow2pow(K);
			   }
		  }
	   else if(Com1_R_Data[3]==0x31)////////////0x41命令接收
	     {
		    MK_float_num.num[0]=Com1_R_Data[13];
			MK_float_num.num[1]=Com1_R_Data[14];
			MK_float_num.num[2]=Com1_R_Data[15];
			MK_float_num.num[3]=Com1_R_Data[16];
		    A_MK_OUTPUT+=MK_float_num.a;
		  }
	   
	 }
}

⌨️ 快捷键说明

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