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

📄 16f877_modbus.c

📁 ModBus通讯
💻 C
📖 第 1 页 / 共 5 页
字号:
    TMR0IE=0;
    MainSendNoack=0;
    buffer.a=get_crc(n);
    data_buf[n+1]=buffer.b[1];
    data_buf[n]=buffer.b[0];
    TXREG=data_buf[0];
    TXIE=1;
    TXEN=1;
    while(send_ok!=0);
    while(TRMT==0);
    
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    
    TXEN=0;
    send_counter=1;
    /* swich to the receve mode*/
    RB0=0;
    RCIE=1;
    CREN=1;
    /* wait the slave equipment ack with 200mS */
    TMR0L=0;
    TMR0H=0;
    Delay200=0;
    TMR0ON=1;
    TMR0IF=0;
    TMR0IE=1;
}
/*******************************************************************************
* Function Name  : UsartReceveSlave
* Description    : UsartReceveSlave
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void UsartReceveSlave(void)
 {
    uint crc_buf;
    uchar i;
    if(rece_counter==0)return;
    rece_ok=1;
    if(rece_counter>5){
        RCIE=0;
        CREN=0;
        CREN=1;
        CREN=0;
        CREN=1;
        RCIE=1;
        rece_counter=0;
        BufferPointOut = Buffer;
        BufferPointIn = Buffer;
        return;
    }
    DataPoint=data_buf;
    for(i=0;i<8;i++){
      *DataPoint++=*BufferPointOut++;
       
      if(BufferPointOut==BufferPointIn){
        RCIE=0;
        CREN=0;
        CREN=1;
        CREN=0;
        CREN=1;
        RCIE=1;
        rece_counter=0;
        BufferPointOut = Buffer;
        BufferPointIn = Buffer;
        return;
      }
      
      if(BufferPointOut==(Buffer+159))BufferPointOut=Buffer;
    }

    rece_counter--;
    
    if(data_buf[1]==0x00){  
       rece_ok=0;
       return;
     }
     
     buffer.b[1]=data_buf[7];
     buffer.b[0]=data_buf[6];
     crc_buf=get_crc(0x06);

    if((buffer.a)!=crc_buf){ 
       rece_ok==0;
       data_buf[0]=0;
       data_buf[1]=0;
       CREN=1;
       RCIE=1;
       return;
     }
}

/*******************************************************************************
* Function Name  : interrupt isr
* Description    : interrupt isr
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void interrupt isr(void)
{
   char i;
   
   /* save the register */
   
   
   /* None */
   if(TMR1IF&&TMR1IE){
    TMR1IF=0;
    TMR1H=T1HValue;
    TMR1L=T1LValue;
    
    KeyScanTime++;
    if(KeyScanTime==100){
      KeyScanTime=0;
      KeyScanFlag=1;
      LcdFlag=1;
      Flag10ms=1;
    }
    return;
   } 
   /* None */ 
   if(RBIF&&RBIE){  
     i=PORTB; 
     RBIF=0;  
    // rbint();
    return;
   } 
    
    /* receve the message */   
    if(RCIF&&RCIE){
          *BufferPointIn=RCREG;
          BufferPointIn++;
          if(BufferPointIn==&Buffer[159]) BufferPointIn=Buffer;
          if(BufferPointIn==BufferPointOut) UsartInit();
          TMR3ON=1;
          TMR3L=T3LValue;
          TMR3H=T3HValue; 
       return;       
     }
   
    /* send the message */
    if(TXIF&&TXIE){
       TXREG=data_buf[send_counter];
       send_counter++;
       if(send_counter==send_number){
         TXIE=0;
         send_ok=1;
       }  
       return;
     }
   
    /* wait for receve end */
    if(TMR3IF&&TMR3IE){
       TMR3IF=0;
       TMR3ON=0;
       TMR0ON=0;
       rece_counter++;
       return;
     } 
      
   
    /* wait for the slave ack and return message */
    if(TMR0IF&&TMR0IE){
       TMR0IF=0;
       Delay200++;
       if(Delay200==30){
         Delay200=0;
         TMR0ON=0;
         MainSendNoack=1;
       }
       return;
     }   
   
    /* reout the register */
   
}

/*******************************************************************************
* Function Name  : get_crc
* Description    : get_crc
* Input          : the nuber of bytes 
* Output         : None
* Return         : the byte of crc 
*******************************************************************************/
uint get_crc(uchar n)
{
    uint crc_word=0xffff;
    uchar i,j;
    for(i=0;i<n;i++){
         crc_word^=(uint)data_buf[i];
         for(j=0;j<8;j++){
             if(crc_word&0x0001){
                crc_word=crc_word>>1;
                crc_word^=0xa001;
              }
             else crc_word>>=1;             
          }
      }
    return crc_word;
}
/*******************************************************************************
* Function Name  : Function_slave
* Description    : Function_slave
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Function_slave(void)
{
    if(rece_ok==0) return;
    rece_ok=0;
    buffer.a=x_number[0x17];
    address=buffer.b[0];
    /* is the right address of the equipment */
    if(data_buf[0]==address){ 
       if(data_buf[1]==0x03){
            UsartSendSlave(Function_03(data_buf[3]));
            return;       
         }
        
        if(data_buf[1]==0x06){ 
            UsartSendSlave(Function_06(data_buf[3]));
            return;       
         }
     }
    /* reserve: broadcast mode */
    if(data_buf[0]==0x00){   
       if(data_buf[1]==0x06){
           /* the addres is stored in data_buf[3] */
           UsartSendSlave(Function_06(data_buf[3]));
           return;
        }
     } 
     /* not the right,some thing is erro */
    send_counter=1;
    RB0=0;
    data_buf[0]=0;
    data_buf[1]=0;
    RCIE=1;
    CREN=1;
}
/*******************************************************************************
* Function Name  : Function_03
* Description    : the MDS function No. of 03,read
* Input          : the addres to be read ofx_number[x],x canbe ...
* Output         : None
* Return         : the total number of bytes to ack 
*******************************************************************************/
uchar Function_03(uchar addr_8)
{
   if(addr_8>0x1f)
    { 
       data_buf[1]=0x83;
       data_buf[2]=0x02;           
       return 0x03;
    }
   /*address 0-0x1f can be read*/
   data_buf[1]=0x03;
   data_buf[2]=0x02;          
   buffer.a=x_number[addr_8];
   data_buf[3]=buffer.b[1];
   data_buf[4]=buffer.b[0];
   return 0x05;  
}
/*******************************************************************************
* Function Name  : Function_06
* Description    : the MDS founction NO. of 06,write
* Input          : data_buf[x],x can be ...
*                  the addres that want to write ti x_number[x]
* Output         : None
* Return         : the total number of bytes to ack  
*******************************************************************************/
uchar Function_06(uchar addr_8)
{
   uchar l=addr_8<<1;
   LcdFlag=1;
   LcdScanTime=100;
   if(data_buf[2]>0){
       data_buf[1]|=0x80;
       data_buf[2] =0x02;
       return 0x03;
    }
   
    buffer.b[1]=data_buf[4];
    buffer.b[0]=data_buf[5];
    x_number[addr_8]=buffer.a;
    
    CLRWDT;
    /* addres 0-0x1a can be write  */
    if(addr_8<0x1a){       
       writeee2b(buffer.a,l);
       CLRWDT;
       writeee2b(buffer.a,(l+52));   
       CLRWDT;
       writeee2b(buffer.a,(l+104));
       CLRWDT;
       x_number[addr_8]=readee2b(l);
       if(addr_8==0x17) return 0x01;
       return 0x06; 
     }
    /* because of user,reset to the factory-set value */
    if(addr_8==0x1a){
       x_number[0x1a]=buffer.a; 
       if(x_number[0x1a]==0) return 0x06;
       x_number[0x1a]=0x00;
       rom_toram(22);
       ram_toee(22);
       CLRWDT;
       CLRWDT;
       //dismainl();
       return 0x00;
     }
    /* because of equipment has erro,reset to the factory-set value */
    if(addr_8==0x1f){
       x_number[0x1f]=buffer.a; 
       if(x_number[0x1f]==0) return 0x06;
       x_number[0x1f]=0x00;
       //dismainl();
       //gz_value=0; 
       //pid_flag=0;
       //pid_flag1=0;   
       return 0x00;
    }   

    data_buf[1]|=0x80;
    data_buf[2] =0x02;
    return 0x03;
} 

/*******************************************************************************
* Function Name  : readee
* Description    : readee
* Input          : the addres want to read
* Output         : None
* Return         : the readed byte
*******************************************************************************/
uchar readee(uchar eeaddr)
{
  EEADR=eeaddr;               
  EEPGD=0;
  CFGS=0;
  RD=1;  
  while(RD==1);
  return EEDATA;              
}
/*******************************************************************************
* Function Name  : readee2b
* Description    : readee2b
* Input          : the addres to be readed
* Output         : None
* Return         : the readed 2bytes
*******************************************************************************/
uint readee2b(uchar eeaddr)
{
 return(uint)(readee(eeaddr)+readee(eeaddr+1)*256);
}
/*******************************************************************************
* Function Name  : writee
* Description    : writee
* Input          : the 8bits to write to e2prom,and the addres to be writed
* Output         : None
* Return         : None
*******************************************************************************/
void writee(uchar eevalue,uchar eeaddr)
{
 while(WR);
 GIE=0;
 EEIF=0;
 EEADR=eeaddr;
 EEDATA=eevalue;
 EEPGD=0;
 CFGS=0;
 WREN=1;
 EECON2=0x55;
 EECON2=0xaa;
 WR=1;
 GIE=1;
 WREN=0;
 while(WR==1);
 EEIF=0;
}
/*******************************************************************************
* Function Name  : writeee2b
* Description    : writeee2b
* Input          : the 16 bits value to be write to e2prom,and the addres to be write to
* Output         : None
* Return         : None
*******************************************************************************/
void writeee2b(uint eevalue,uchar eeaddr)
{
   /* write the high addres first */
   writee(eevalue/256,eeaddr+1);     
   /* write the low addres second */
   writee(eevalue%256,eeaddr);       
}
/*******************************************************************************
* Function Name  : ram_toee
* Description    : ram to three eeprom blocks 
* Input          : the range of e2prom to be writed uchar u
* Output         : None
* Return         : None
*******************************************************************************/
void ram_toee(uchar u)
{
  uchar i;
  for(i=0;i<u;i++){
     writeee2b(x_number[i],(i*2));
   }
  for(i=0;i<52;i++){
    writee(readee(i),i+52);
    writee(readee(i),i+104);
   }  
}
/*******************************************************************************
* Function Name  : ee_toram
* Description    : the first e2prom block to ram 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void ee_toram(void)
{
   uchar i;
   for(i=0;i<26;i++){
      /* two bytes,the addres doubling */ 
      x_number[i]=readee2b(i*2);
    }
}
/*******************************************************************************
* Function Name  : rom_toee
* Description    : rom_toee 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void rom_toee(void)
{
  uchar i;
  for(i=0;i<26;i++){
     writeee2b(pre_number[i],(i*2));
   }
  for(i=0;i<52;i++){
    writee(readee(i),i+52);
    writee(readee(i),i+104);
   }
  /* set the flag */
  writee(0xcc,200);  

⌨️ 快捷键说明

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