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

📄 modbus.c

📁 8051F_Modbus.rar是在C8051F020单片机上编写的CRC16校验的MODBUS协议.
💻 C
📖 第 1 页 / 共 3 页
字号:
	         SBUF1 = the_char;               // transmit it
              
	   }          
	   else
	   {    
	        TX1_Ready = 1;                 // indicate ready for next TX
            TX1_index=0;
			RE485=0;
	   }
   }
}



   

//定时器0初始化

void Timer0_Init (void)
{
   TMOD |=0X01;
   TH0=0XB8;
   TL0=0X00;
   ET0=1;
  
}


//---------------------------------------------------------------------------------------
//定时器T0溢出中断处理子程序
void Timer0_ISR(void) interrupt 1      	
{
          tend=temp;
           if(time>=tend)     
          {
              TL0=0X00;        //11.0592MHZ T0低8位初值:定时10ms
	          TH0=0XB8;        //T0高8位初值
              TR0=0;           //终止定时器T0
              sendinterval=1;
              time=0;
           }
           else

           {
           
              TL0=0X00;        //T0低8位初值:定时50ms
	          TH0=0XB8;        //T0高8位初值
	          time=time+1;
	          sendinterval=0;
	    }
}
//---------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <baudrate> and 8-N-1.
//
void UART0_Init (void)
{
   SCON0   = 0x50;                     // SCON0: mode 1, 8-bit UART, enable RX
   TMOD   |= 0x20;                     // TMOD: timer 1, mode 2, 8-bit reload
   TH1    = 0x6F;                      // set Timer1 reload value for baudrate
   CKCON |= 0x10;                      // Timer1 uses SYSCLK as time base
   PCON  |= 0x90;                      // SMOD0 = 1
   ES0    = 1;                         // enable UART0 interrupts
   TI0    = 0;                         // Indicate TX0 ready
   TR1    = 1;                         // start Timer1

   TX0_Ready = 1;                       // indicate TX ready for transmit
   RX0_Ready = 0;                       // indicate RX string not ready
   TX0_ptr = NULL;
}



void UART0_ISR (void) interrupt 4 
{
   
   static unsigned int TX0_index = 0;    // send buffer index
   unsigned char the_char0;
   
   if (RI0 == 1) 
   {                    
      RI0 = 0; 
	  if (RX0_Ready == 0)                        //可以接收
	  {   the_char0 = SBUF0;                      // check to see if message pending
          if(RX0_index >=RX0_LENGTH)
		  {
		     if (the_char0 == RX0_END)             //是结束符
			 {
			      	RX0_Buf[RX0_index] = the_char0;   // NULL-terminate message
                    RX0_Ready = 1;              // post message ready
                    RX0_index = 0;              // reset RX message index
			 }
			 else                              //不是结束符
			 {      
			        RX0_Ready =0;              // post message ready
                    RX0_index = 0;              // reset RX message index
			        
			 }
		  }     
		  else
		  {
		    
			  if(RX0_index==0)
			  {
			        if (the_char0 == RX0_START)             //是起始符
			        {
			      	       RX0_Buf[RX0_index] = the_char0;
		                   RX0_index++;
						   //RECEIVENUM1=2;
			        }
			        else                              //不是起始符
			       {

        			        RX0_Ready =0;              
                            RX0_index = 0; 
							//RECEIVENUM1=1;             
                    }   
			  }
			  else
			  {
			        if (the_char0 == RX0_END)             //是结束符
			        {
			      	       RX0_Buf[RX0_index] = the_char0;   // NULL-terminate message
                           RX0_Ready = 1;              // post message ready
                           RX0_index = 0;              // reset RX message index
			        }
			        else                              //不是结束符
			       {

        			       RX0_Buf[RX0_index] = the_char0;
		                   RX0_index++;
						   //RECEIVENUM1++;
                    }
			    
			  }
		 }

      }
	  else 
	  {
         ; // ignore character -- previous message has not been processed
      }

   } 
   else if (TI0 == 1) 
   {              
      TI0 = 0;                         // clear TX complete indicator
	   the_char0 = *TX0_ptr;                 // read next character in string
       if(TX0_index<SENDNUM0)
	   {
	       TX0_ptr++;
		   TX0_index++;                     // get ready for next character
	       SBUF0 = the_char0;               // transmit it
           
	   }
	   else
	   {    
	        TX0_Ready = 1;                 // indicate ready for next TX
            TX0_index=0;
		
	   }
   }
}

//------------------------------------------------------------------------------------
//RX0_BufClear() 
//-----------------------------------------------------------------------------------
void RX0_BufClear(void)
{
        unsigned char m;
        for(m=0;m<5;m++)
        {
            RX0_Buf[m]=0x00;
        }
} 


//-------------------------------------------------------------------------------------
//写FLASH
//-------------------------------------------------------------------------------------
void FlashWrite(unsigned char xdata *pwrite,unsigned char *BufFrom)
{
       unsigned char i;
	   
	   WDTCN = 0xde;                       // disable watchdog timer
       WDTCN = 0xad;
	   EA=0;
       
	   FLSCL |= 0x01;                      // Enable FLASH writes/erases

       PSCTL |= 0x03;                      // set PSWE = PSEE = 1
       PSCTL |= 0x04;                      // set SFLE = 1 (enable
                                           // access to scratchpad)
       *pwrite = 0x00;                     // erase SCRATCH PAGE     该页被擦除

       PSCTL &= ~0x07;                     // set PSWE = PSEE = SLFE = 0

       PSCTL |= 0x01;                      // set PSWE = 1 写FLASH允许
                                               

       for(i=0;i<2;i++)
	   {   
	       PSCTL |= 0x04;                   // set SFLE to enable FLASH writes
                                            // to Scratch Pad memory
	       *pwrite++=*BufFrom++;

		   PSCTL &= ~0x04;                      // set SFLE to enable FLASH writes
                                            // to Scratch Pad memory
	   }

       PSCTL &= ~0x07;                     // set PSWE = PSEE = SFLE = 0   
       FLSCL &= ~0x01;                     // clear FLWE to disable FLASH
                                          // write/erases
       EA=1;

       
}

//--------------------------------------------------------------------------------------
//读FLASH
//--------------------------------------------------------------------------------------
void FlashRead(unsigned char code *pread,unsigned char *BufTo)
{
    unsigned char i;
	for(i=0;i<2;i++)
	{  
	   PSCTL |= 0x04;                   // set SFLE to enable FLASH writes
                                        // to Scratch Pad memory
       BufTo[i]=*pread;
	   pread++;

	   PSCTL &= ~0x04;                     // clear SFLE to disable access
                                          // to Scratch Pad memory
	}

}

//-------------------------------------------------------------------------------------
//向总控中心发送传感器地址
//-------------------------------------------------------------------------------------
void SendCgqAddr(void)
{
    unsigned char sendaddr[5];
	sendaddr[0]=0x7e;
    sendaddr[1]=0xe0;
	sendaddr[2]=raddr[0];
	sendaddr[3]=raddr[1];
	sendaddr[4]=0x0d;
    while (!TX0_Ready) ;              // wait for transmitter to be available
    TX0_Ready = 0;                    // claim transmitter
    TX0_ptr = sendaddr;               // set TX buffer pointer to point to 
                                      // received message
    SENDNUM0=5;
    
	TI0 = 1;
}

//--------------------------------------------------------------------------------------
//RX1_BufClear(void)
//--------------------------------------------------------------------------------------
void RX1_BufClear(void)
{
     unsigned char m;
     for(m=0;m<64;m++)
     {
          RX1_Buf[m]=0x00;
     }
}


//---------------------------------------------------------------------------------------
//定时器T2初始化子程序
//---------------------------------------------------------------------------------------
void Timer2_Init(void) 
{
   TH2=0XB8;
   TL2=0X00;
   
   T2CON |=0X00;  //T2定时器方式1,自动重装载

    ET2=1;            //定时器T2允许中断

   
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////



//---------------------------------------------------------------------------------------
//定时器T2溢出中断处理子程序
//---------------------------------------------------------------------------------------
void Timer2_ISR(void) interrupt 5
{
   
   TF2=0; /*定时器T2溢出标志零*/
   
   tend2=temp2;
   if(time2>=tend2)     
   {
       TR2=0;           //终止定时器T0
       sendinterva2=1;
       time2=0;
   }
   else
   {
       time2=time2+1;
	   sendinterva2=0;
   } 
   
  
}

//--------------------------------------------------------------------------------------------
//modubus串口通过485向传感器发送命令子程序,addr为传感器地址
//--------------------------------------------------------------------------------------------
void modbuscgqsend(unsigned char  addr)
{
      unsigned char Cd[6];
      unsigned char SendCd[8];
	  unsigned int c,crc=0xFFFF;
      unsigned char i,j,temp;
      Cd[0]=addr;
      Cd[1]=0x03;
      Cd[2]=0x00;
      Cd[3]=0x00;
      Cd[4]=0x00; 
      Cd[5]=0X02;
        
      for (i=0;i<6;i++)
      {
        c=Cd[i] & 0x00FF;
        crc^=c;
	    for(j=0;j<8;j++)
	   { 
	       if (crc & 0x0001)
		   {
		      crc>>=1;
			  crc^=0xA001;
		    }
		    else 
		    {
		      crc>>=1;
            }
        }
      }
      temp=crc & 0x00ff;
	  SendCd[6]=temp;
      crc>>=8;
	  temp=crc & 0x00ff;
      SendCd[7]=temp;
      
	  SendCd[0]=Cd[0];
      SendCd[1]=Cd[1];
      SendCd[2]=Cd[2];
      SendCd[3]=Cd[3];
      SendCd[4]=Cd[4]; 
      SendCd[5]=Cd[5];

	  while (!TX1_Ready);                  // wait for TX ready
      TX1_Ready = 0;                       // claim transmitter
      TX1_ptr = SendCd;                    // set buffer pointer
	  SENDNUM1=8;
	  RE485=1;
      SCON1 |= 0x02;                      // TI1 = 1; start transmit
	
}



⌨️ 快捷键说明

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