资讯详情

dsPIC30F6014A 编写的MODBUS程序

/*------------------------------Modbus.c--------------------------*/ #include "PRJ.h" #include "p30f6014a.h" #include "stdio.h" #include "DFT.h" #include "Freq.h" #include "control.h" #include "ModBus.h"  #define R485C PORTGbits.RG14 //#define R485C PORTGbits.RG12    //for profibus  test #define TRUE   1 #define FALSE  0  unsigned char temp4[80]; unsigned int send_no;    ///发送数据数量 unsigned int Send_data[12]={'t','e','s','t','\r','\n,\r','\n'}; //发送的数组  /* **************************************************************** ** 函  数 名: Uart_Initial() ** 功能描述: 通用异步收发器UART初始化 *************************************************************** */  /*通用异步收发器UART初始化   */ void Uart_Initial() {  IFS0bits.U1TXIF=0;   ///发送中断标志  IFS0bits.U1RXIF=0;   ///  IPC2bits.U1TXIP=1;   ///发中断优先级:1级       IEC0bits.U1TXIE=0;   //UART发送中断使能      //IEC0bits.U1RXIE=TRUE;  //IEC0bits.U1RXIE=FALSE;     IEC0bits.U1RXIE=TRUE;  U1MODE=0x8000;        //UART使能,8位数据,无奇偶验证  U1STA=0x0400;    //当一个字符被传输到发送移位寄存器(发送缓冲器)  //U1STA=0x0000;      //少有一个字符)中断,当接收到一个字符时,中         //断标位置  //U1BRG=0X34;             //U1BRG=Fcy/(16*波特率)-1,波特率9600          U1BRG=0X33;     //U1BRG=0X06;     //U1STA=0x0400;    return; }  #define uchar  unsigned char  uchar rxd_get[20]={0x64,0x03,0x00,0x04,0x00,0x01}; uchar rxd_cnt=0; uchar rxd_flag=FALSE; uchar rxd_tms=0; uchar rxd_id=0x64;  void uart_err_todo(void) {  if(U1STAbits.OERR==1)  {   U1STAbits.OERR=0;       }  }  void uart_get(void)//1ms cycle called  {  rxd_tms  ;  if(rxd_tms>5)//dt=5ms,帧同步    {  rxd_tms=0;  rxd_cnt=0;     }  if(rxd_flag==FALSE)  {    while(U1STAbits.URXDA==1)   {       rxd_tms=0;    IFS0bits.U1RXIF=0;    rxd_get[rxd_cnt  ]=U1RXREG;    if(rxd_get[0]!=rxd_id)    {rxd_cnt=0;}    if(rxd_cnt>7)//get 8 byte     {     rxd_cnt=0;     rxd_flag=TRUE;           }//if()          }//while()   }//if()  }//end  //------------------------------------------- //3.CRC16算法 //-------------------------------------------  #define U16   unsigned int #define U8    unsigned char   U16 CRC16(U8 *p,U8 n)  {   U16 temp=0xffff;   U16 crc_result;   U8 i,j;   for(j=0;j<n;j  )     {   temp^=(*p);   for(i=0;i<8;i  )    {        /*        temp>>=1;        if(STATUSbits.C==1)     {temp^=0xa001;}*/             if((temp&0x0001)==0x0000)     {temp>>=1;}     else     {temp>>=1;      temp^=0xa001;       }              }      p  ;      }    crc_result=(temp/256) (temp%6)*256;    return(crc_result);   } //------------------------------------------ // //------------------------------------------ #define uint unsigned int  uchar txd_buff[8]; extern signed int I_sys;//=0; extern signed char pf_2nd;//pf real is 0.98 extern uchar relay_state;//=0x00;  void uart_echo(void)//100ms cycle called {  uchar i;  uint crc_temp,reg_addr;  if(rxd_flag==TRUE)    {  //send     /*  for(i=0;i<8;i  )  {   U1TXREG=rxd_get[i];   while(IFS0bits.U1TXIF==0);   IFS0bits.U1TXIF=0;   }      */     //crc test     crc_temp=CRC16(rxd_get,6);  if((crc_temp/256==rxd_get[6])&&\     (crc_temp%6==rxd_get[7])&&\     (rxd_get[1]==0x03))   {       reg_addr=(uint)rxd_get[2]*256 rxd_get[3];       /*    switch(reg_addr)    {      case 1://电压       txd_buff[4]=VL_2nd/256;       txd_buff[5]=VL_2nd%6;       break;      case 2://电流       txd_buff[4]=I_sys/256;       txd_buff[5]=I_sys%6;       break;      case 3:///功率因数       txd_buff[4]=pf_2nd/256;       txd_buff[5]=pf_2nd%6;       break;      case 4:///投切状态       txd_buff[4]=relay_state/256;       txd_buff[5]=relay_state%6;       break;      case 5://              break;      case 6://                             break;             default:break;     }     */    txd_buff[0]=rxd_id;       txd_buff[1]=0x03;    txd_buff[2]=0x00;    txd_buff[3]=0x01;    crc_temp=CRC16(txd_buff,6);    txd_buff[6]=crc_temp/256;    txd_buff[7]=crc_temp%6;    //_20ms_timer_clr();    //while(_20ms_timer()==FALSE);    //*     for(i=0;i<8;i  )    {     U1TXREG=txd_buff[i];     while(IFS0bits.U1TXIF==0);     IFS0bits.U1TXIF=0;     }     //*/    }     rxd_flag=FALSE;   }  } //---------------------------------------- //for @30000# format get //---------------------------------------- #define uint8    unsigned char #define uint16   unsigned int uint16 FS_SET=50;//300~30,000Hz void FS_SET_Update(void) {   uint16 temp;  temp=(uint16)(rxd_get[1]-'0')*10000;  temp=temp (uint16)(rxd_get[2]-'0')*1000;  temp=temp (uint16)(rxd_get[3]-'0')*100;  temp=temp (uint16)(rxd_get[4]-'0')*10;  temp=temp (uint16)(rxd_get[5]-'0');  if(temp<=30000)    {     FS_SET=temp;     //Update F sample     //printf()     PR4=(uint16)(250000.0/(float)temp);     printf("FS_SET=%d,PR4 Set=%d\r\n",FS_SET,PR4);     }  else     {printf("FS_SET Not Update\r\n");}  } // uint8 SIND_Get_Flag=FALSE; uint8 SIND_Get_State=0; uint8 GetTemp; extern void modbus_recieve(void); /// void __atribute__((__interrupt__)) _U1RXInterrupt()
{
 /*
 //while(U1STAbits.URXDA==1)
//	{
	 //IFS0bits.U1RXIF=0;
	 rxd_get[rxd_cnt++]=U1RXREG;
	 if(rxd_cnt>9)
		{rxd_cnt=0;
		 rxd_flag=TRUE;
		 }
//	 }
 */
 if(SIND_Get_Flag==FALSE)
 {
  GetTemp=U1RXREG;
  modbus_recieve();
  switch(SIND_Get_State)
    {
     case 0:if(GetTemp=='@')
			 {rxd_cnt=0;
			  rxd_get[rxd_cnt++]=GetTemp;
			  SIND_Get_State=1;
  		      }
			break;
     case 1:if(GetTemp=='#')
			 {//rxd_cnt=0;
			  rxd_get[rxd_cnt++]=GetTemp;
			  rxd_get[rxd_cnt++]='\0';
			  rxd_cnt=0;
			  SIND_Get_State=0;
			  SIND_Get_Flag=TRUE;
  		      }	
			else
			  {
			   rxd_get[rxd_cnt++]=GetTemp;
               }		
			break;
     }
  }
 IFS0bits.U1RXIF=0;
 }
 
 
extern uint8 SIND_Get_Flag;//=FALSE;
extern uchar rs485_com_adr;//=0;//rs485 通讯地址
extern uint IL_real_uart;
extern uint relay_state_2nd;//=0x0fff;
extern unsigned int  ct_ratio;//CT 变比
extern unsigned int Iq_set;
extern unsigned int dt_interval;//控制时间间隔
extern unsigned int  pf_th;//功率因数上限
extern unsigned int uh_th;//电容运行电压上限
extern unsigned int swn;//补偿路数
void command_001_back(void)
{
 //VL_2nd=380;
 //IL_real_uart=2500;
 //relay_state_2nd=7;
 printf("\r\n");
 //0.
 printf("@%03d 001",(uint16)rs485_com_adr);
 //1.
 printf(" %03d",VL_2nd);
 //2.
 printf(" %04d",IL_real_uart);
 //printf(" %-04d")
 //pf_2nd=56;
 //3.
// pf_sign_2nd=IND;
 if(pf_sign_2nd==IND)
   {
	printf(" +%-04.2f",pf_2nd/100.0);
    }
 else
   {
	printf(" -%-04.2f",(pf_2nd/100.0));
    }
 //   */
  // pf_2nd=80;
  // printf(" %-04.2f",-(pf_2nd/100.0)); 
 //printf(" %-0d#\r\n",relay_state_2nd); 
 printf(" %05d",relay_state_2nd); 
 //-----------------------------------------------
 //2017.11.6 add part
 //-----------------------------------------------
 //4.ct_set
 printf(" %05d",ct_ratio);
 //5.iq_step
 printf(" %04d",Iq_set);
 //C:\quick_v5_2017.10.30\control.h:8: extern unsigned int Iq_set;
 //6.dt
 printf(" %05d",dt_interval);
 //7.pf_th
 printf(" %-04.2f",pf_th/100.0);
 //8.uh_th
 printf(" %04d",uh_th);
 //9.sw_sum
 printf(" %04d",swn);
 
 printf("#\r\n");
 
 }

//2020 modbus code 
///

int cnt_1ms_end=0;
int GET_EN=TRUE;
int pp_save=0;
unsigned char modbus_get_buff[100];

extern uint8 GetTemp;
//帧数据接收函数
void modbus_recieve(void)
{
 cnt_1ms_end=0;//
 if(GET_EN==TRUE)
   {
    modbus_get_buff[pp_save]=GetTemp;
    if(pp_save<99)
      {pp_save++;}
    }
 }

unsigned char modbus_send_buff[100];
unsigned char modbus_reg_data[20];//

void modbus_reg_data_init(void)
{
 int i;
 for(i=0;i<20;i++)
   {modbus_reg_data[i]=i;}
 }

void modbus_reg_update(void)
{
 /*
  0   380是当前电网电压
  1   2500是当前系统的电流
  2   小于100,例如98  代表0.98  大于100,代表容性,例如198,代表功率因数是-0.98
  3   7代表当前投切状态,转化成12位的二进制数,0000 0000 0000 0111
      “1”代表投入,“0”代表未投入
  4   00100 CT变比  100:5
  5   0020  单组电容电流
  6   00020  动作时间间隔单位ms,20ms
  7   0.90   补偿功率因数上限
  8   0420过电压保护阀值
  9   0012补偿总路数,12路
  */
/*
  VL_2nd=100;
  IL_real_uart=100;
  pf_2nd=98;
  relay_state_2nd=0xfff;
  ct_ratio=100;
  Iq_set=30;
  dt_interval=100;
  pf_th=98;
  uh_th=100;
  swn=10;
 */
//1  电网电压
   modbus_reg_data[0]=VL_2nd>>8;
   modbus_reg_data[1]=VL_2nd&0xff;
//2 电网侧电流   
   modbus_reg_data[2]=IL_real_uart>>8;
   modbus_reg_data[3]=IL_real_uart&0xff;
//3.功率因数
   if(pf_sign_2nd==IND)//感性
    {
      modbus_reg_data[4]=(unsigned int)pf_2nd>>8;
      modbus_reg_data[5]=(unsigned int)pf_2nd&0xff;
    }
    else
    {
     modbus_reg_data[4]=(unsigned int)(pf_2nd+100)>>8;
     modbus_reg_data[5]=(unsigned int)(pf_2nd+100)&0xff;
     }
//4 当前投切状态
   modbus_reg_data[6]=relay_state_2nd>>8;
   modbus_reg_data[7]=relay_state_2nd&0xff;
//5 CT变比比率 100,代表(500:5 或者100:1)
   modbus_reg_data[8]=ct_ratio>>8;
   modbus_reg_data[9]=ct_ratio&0xff;
//6 单组电容电流
   modbus_reg_data[10]=Iq_set>>8;
   modbus_reg_data[11]=Iq_set&0xff;
//7 动作时间间隔
   modbus_reg_data[12]=dt_interval>>8;
   modbus_reg_data[13]=dt_interval&0xff;
// 8   0.90   补偿功率因数上限
   modbus_reg_data[14]=pf_th>>8;
   modbus_reg_data[15]=pf_th&0xff;
//9 420过电压保护阀值
   modbus_reg_data[16]=uh_th>>8;
   modbus_reg_data[17]=uh_th&0xff;
//10 0012补偿总路数,12路
   modbus_reg_data[18]=swn>>8;
   modbus_reg_data[19]=swn&0xff; 


  Nop();
  Nop();
 }
///
//帧数据发送函数

void modbus_byte_send(unsigned char n)
{
 int i;
 for(i=0;i<n;i++)
 {
   //modbus_send_buff[i]=i;
   U1TXREG=modbus_send_buff[i];	// 返送接收到的数
  }
 }

#define  FRAME_TIME   200  //20ms
void modbus_echo(void)
{
 unsigned char x=100;
 int i=0;
 unsigned int reg_addr=0;
 unsigned int num_data=0;
 unsigned char CRC_L,CRC_H;
 unsigned int crc16,crc16_get;

 //IEC0bits.U1TXIE=1;
 //U1STAbits.UTXEN=1;//发送使能!!!
 IEC0bits.U1TXIE=1;U1STAbits.UTXEN=1;
 if((cnt_1ms_end>FRAME_TIME)&&(pp_save>7))
  {
     GET_EN=FALSE;
     cnt_1ms_end=0;
     R485C=1;
	 Nop();Nop();Nop();Nop();
	 Nop();Nop();Nop();Nop();
     
     reg_addr=((unsigned int)modbus_get_buff[2]<<8)+modbus_get_buff[3];
     num_data=((unsigned int)modbus_get_buff[4]<<8)+modbus_get_buff[5];
     crc16_get=((unsigned int)modbus_get_buff[6]<<8)+modbus_get_buff[7];
     crc16=CRC16(modbus_get_buff,6);
     Nop();
     /
     if(modbus_get_buff[0]==rs485_com_adr)//地址判断
     {
       if(modbus_get_buff[1]==0x03)//功能代码判断
         {
          if((reg_addr<10)&&(num_data<=10)&&(crc16_get==crc16))//地址 数据 CRC  校验
            {
              //todo:modbus 数据准备与发送 
              modbus_send_buff[0]=rs485_com_adr;
              modbus_send_buff[1]=0x03;
              modbus_send_buff[2]=num_data*2;//数据字节个数
              for(i=0;i<num_data;i++)
               {
                modbus_send_buff[3+2*i]=modbus_reg_data[reg_addr*2];
                modbus_send_buff[3+2*i+1]=modbus_reg_data[reg_addr*2+1];
                reg_addr++;
                }
              //add crc data
               CRC_L=CRC16(modbus_send_buff,3+num_data*2)>>8;
               CRC_H=CRC16(modbus_send_buff,3+num_data*2)&0xff;
               modbus_send_buff[3+num_data*2]=CRC_L;
               modbus_send_buff[3+num_data*2+1]=CRC_H;
              //send
              modbus_byte_send(5+num_data*2);
              Nop();
              Nop();
              }
          }
      }


     //modbus_byte_send(50);
	 pp_save=0;
    
     /
	 Nop();Nop();Nop();Nop();
	 Nop();Nop();Nop();Nop();
	 R485C=0; 

     GET_EN=TRUE;
   }
 }
///

void UartGetReturn(void)
{
 uint8 com_addr,com_command;
 if(SIND_Get_Flag==TRUE)
  {
	com_addr=(rxd_get[1]-'0')*100+(rxd_get[2]-'0')*10+(rxd_get[3]-'0');
	com_command=(rxd_get[4]-'0')*100+(rxd_get[5]-'0')*10+(rxd_get[6]-'0');
//	if(com_addr==rs485_com_adr)
    if(1)
	 {
	  switch(com_command)
	     {
		  case 1:
		  		  R485C=1;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
			      //printf("%s",rxd_get);
			      //printf("\r\n");
			      //printf("----------------\r\n");
			      command_001_back();
			      //printf("command valid!\r\n");
			      R485C=0;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
		  		 break;
		  default:
		  		  R485C=1;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
			      //printf("%s",rxd_get);
			      //printf("\r\n");
			      //printf("----------------\r\n");
			      printf("command no valid!\r\n");
			      R485C=0;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
			      break;
	      }
	  /*
      R485C=1;
      Nop();Nop();Nop();Nop();
      Nop();Nop();Nop();Nop();
      printf("%s",rxd_get);
      printf("\r\n");
      printf("----------------\r\n");
      R485C=0;
      Nop();Nop();Nop();Nop();
      Nop();Nop();Nop();Nop();
      */	  
	  }
	/*
    R485C=1;
    Nop();Nop();Nop();Nop();
    Nop();Nop();Nop();Nop();
    printf("%s",rxd_get);
    printf("\r\n");
    printf("----------------\r\n");
    R485C=0;
    Nop();Nop();Nop();Nop();
    Nop();Nop();Nop();Nop();
    */
    
    SIND_Get_Flag=FALSE;
   } 
 }
 
void __attribute__((__interrupt__)) _U1TXInterrupt()
 {
	while(U1STAbits.TRMT ==0);	//当为0时,表明移位寄存器没空
	IFS0bits.U1TXIF=0;			//发送中断标志位清零   
 }

void io_init(void)
{
  TRISGbits.TRISG14=0;
  Nop();
  R485C=1;
  Nop();
  R485C=0;
  Nop();
 }

void Send1Byte(void)
{
 unsigned char i;
 printf("**************************************************************\r\n");
 printf("*                   电能质量分析结果                         * \r\n");
 printf("**************************************************************\r\n");
 printf("频率f=%6.3f(Hz)\r\n",(1000000.0)/(float)FreqTerm);
 printf("功率Pa=%8.2f(W),Pb=%8.2f(W),Pc=%8.2f(W)\r\n",Pa,Pb,Pc);

 printf("功率因数cosFA=%5.2f,cosFB=%5.2f,cosFC=%5.2f\r\n",cosFA,cosFB,cosFC);

 printf("有效值(有名值):\r\n");
 printf("Va=%d(V),Vb=%d(V),Vc=%d(V)\r\n",Va_rms,Vb_rms,Vc_rms);
 printf("Ia=%f(A),Ib=%f(A),Ic=%f(A)\r\n",Ia_rms/100.0,Ib_rms/100.0,Ic_rms/100.0);
 printf("--------------------------------------------------------------\r\n");
 printf("谐波总畸变率:\r\n");
 printf("-------------------------------------------------------------\r\n");
 printf("THD is: Va_THD=%d%%%,Vb_THD=%d%%,Vc_THD=%d%%\r\n",Va_THD,Vb_THD,Vc_THD);
 printf("THD is: Ia_THD=%d%%%,Ib_THD=%d%%,Ic_THD=%d%%\r\n",Ia_THD,Ib_THD,Ic_THD);
 printf("-------------------------------------------------------------\r\n");
 printf("谐波含量(百分值)\r\n");
 for(i=1;i<32;i++)
 {
  printf("%2dst----Va=%d%%,Vb=%d%%,Vc=%d%%,Ia=%d%%,Ib=%d%%,Ic=%d%%",\
               i,Va_dft_pu[i],Vb_dft_pu[i],Vc_dft_pu[i],\
                 Ia_dft_pu[i],Ib_dft_pu[i],Ic_dft_pu[i]);
  printf("\r\n");
  printf("-------------------------------------------------------------\r\n");
  }
 printf("**************************************************************\r\n");
 printf("*                   The End of the Report                     * \r\n");
 printf("**************************************************************\r\n");
 }
 
unsigned char  print_cnt=0;
void UartSend(void)
{
 unsigned char i;
 switch(print_cnt)
 {case 0:
         printf("**************************************************************\r\n");
         printf("*                   电能质量分析结果                         * \r\n");
         printf("**************************************************************\r\n");
         break;
  case 1: 
         printf("频率f=%6.3f(Hz)\r\n",(1000000.0)/(float)FreqTerm);
         printf("功率Pa=%8.2f(W),Pb=%8.2f(W),Pc=%8.2f(W)\r\n",Pa,Pb,Pc);
         break;
  case 2:

         printf("功率因数cosFA=%5.2f,cosFB=%5.2f,cosFC=%5.2f\r\n",cosFA,cosFB,cosFC);

         printf("有效值(有名值):\r\n");
         break;
  case 3:
         printf("Va=%d(V),Vb=%d(V),Vc=%d(V)\r\n",Va_rms,Vb_rms,Vc_rms);
         printf("Ia=%f(A),Ib=%f(A),Ic=%f(A)\r\n",Ia_rms/100.0,Ib_rms/100.0,Ic_rms/100.0);
         break;
  case 4:
 		 printf("--------------------------------------------------------------\r\n");
         printf("谐波总畸变率:\r\n");
         printf("-------------------------------------------------------------\r\n");
         break;
  case 5:
         printf("THD is: Va_THD=%d%%%,Vb_THD=%d%%,Vc_THD=%d%%\r\n",Va_THD,Vb_THD,Vc_THD);
         printf("THD is: Ia_THD=%d%%%,Ib_THD=%d%%,Ic_THD=%d%%\r\n",Ia_THD,Ib_THD,Ic_THD);
         break;
  case 6:
         printf("-------------------------------------------------------------\r\n");
         printf("谐波含量(百分值)\r\n");
         break;
  case 7:
  case 8:
  case 9:
  case 10:
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
  case 16:
  case 17:
  case 18:
  case 19:
  case 20:
  case 21:
  case 22:
  case 23:
  case 24:
  case 25:
  case 26:
  case 27:
  case 28:
  case 29:
  case 30:
  case 31:
  case 32:
  case 33:
  case 34:
  case 35:
  case 36:
  case 37:
        i=print_cnt-6;
        printf("%2dst----Va=%d%%,Vb=%d%%,Vc=%d%%,Ia=%d%%,Ib=%d%%,Ic=%d%%",\
               i,Va_dft_pu[i],Vb_dft_pu[i],Vc_dft_pu[i],\
                 Ia_dft_pu[i],Ib_dft_pu[i],Ic_dft_pu[i]);
         printf("\r\n");
         printf("-------------------------------------------------------------\r\n");
        // }
         break;
  case 38:
        printf("**************************************************************\r\n");
        printf("*                   The End of the Report                     * \r\n");
        printf("**************************************************************\r\n");
        break;
  default:print_cnt=0;break;
 }
 print_cnt++;
 if(print_cnt>38){print_cnt=0;}
}

标签: dst电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台