teste de publish

Dependencies:   DS1820 HighSpeedAnalogIn devices mbed

modbusMaster1.cpp

Committer:
brunofgc
Date:
2018-01-25
Revision:
18:1eefda1f7736
Parent:
0:1c0a769988ee
Child:
25:a6da63ed025b

File content as of revision 18:1eefda1f7736:

#include "modbusMaster1.h"
//RAD
enum {
    READ_COIL_STATUS = 1,
    READ_INPUT_STATUS,
    READ_HOLDING_REGISTERS,
    READ_INPUT_REGISTERS,
    WRITE_SINGLE_COIL,
    WRITE_SINGLE_REGISTER,
    WRITE_MULTIPLE_COILS,
    WRITE_MULTIPLE_REGISTERS
}modBusFunctions;

bool modBusMaster1::pacoteEmEspera;
bool modBusMaster1::startThreadModBusMaster;
Serial *modBusMaster1::serModBus;
DigitalOut *modBusMaster1::de;
uint16_t modBusMaster1::MODBUS_SERIAL_BAUD;

uint8_t modBusMaster1::buffer[maxLenBufModBus]; //Buffer in e out;
uint16_t modBusMaster1::index;

//Timer
osTimerId modBusMaster1::timer_pacote;
osTimerDef(timerProcessaPacoteModBusMaster1,modBusMaster1::processaPacote);
//Timer

void modBusMaster1::processaPacote(void const *){
    //Validando CRC
    uint16_t crc_calculado;
    uint16_t crc_lido;
    
    #ifdef modbusDebug
    //Lido resposta DEBUG
    pc.printf("Lido de resposta modbus <");
    for(crc_lido = 0; crc_lido < modBusMaster1::index; crc_lido++){
        pc.printf("%02X ",modBusMaster1::buffer[crc_lido]);
    }
    pc.printf(">.\n");
    #endif
    if(modBusMaster1::index<3){
        modBusMaster1::pacoteEmEspera=false;
        return;
    }
    
    crc_calculado = modBusMaster1::CRC16(modBusMaster1::buffer,modBusMaster1::index-2);
    crc_lido = (modBusMaster1::buffer[modBusMaster1::index-2]<<8)+(modBusMaster1::buffer[modBusMaster1::index-1]);
    
    
    if(crc_calculado == crc_lido){
        modBusMaster1::pacoteEmEspera=true;
    }
    //pc.printf("crc_calculado = 0x%02x, crc_lido = 0x%02x.\n",crc_calculado,crc_lido);
}

uint16_t modBusMaster1::CRC16(uint8_t *buf,uint16_t len){
  uint16_t crc = 0xFFFF;  
  uint16_t pos;
  uint16_t i;
  for (pos = 0; pos < len; pos++) {
    crc ^= buf[pos];          // XOR byte into least sig. byte of crc
 
    for (i = 8; i != 0; i--) {    // Loop over each bit
      if ((crc & 0x0001) != 0) {      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
  return ((crc<<8)+(crc>>8)); 
}

void modBusMaster1::modBusMaster(Serial *serial,uint32_t baud,DigitalOut *pinDe){
    modBusMaster1::serModBus = serial;     
    modBusMaster1::de = pinDe;
    modBusMaster1::index = 0;
    *modBusMaster1::de = 0;
    modBusMaster1::serModBus->attach(&modBusMaster1::processaCaractere);
    modBusMaster1::serModBus->baud(baud);
    modBusMaster1::pacoteEmEspera = false;  
    modBusMaster1::MODBUS_SERIAL_BAUD = baud;
    
    //Criando timer_pacote
    modBusMaster1::timer_pacote = osTimerCreate(osTimer(timerProcessaPacoteModBusMaster1),osTimerOnce,NULL);              
}

void modBusMaster1::processaCaractere(){
    uint32_t RBR = LPC_UART1->RBR;      //Reset RBR interrupt flag e captura o caractere entrante
    modBusMaster1::buffer[modBusMaster1::index]=RBR;
    modBusMaster1::index++;
    if(modBusMaster1::index>=maxLenBufModBus){
       modBusMaster1::index=modBusMaster1::index-1; 
    }
    modBusMaster1::startThreadModBusMaster=true;
    osSignalSet(idThreadTimers, 0x1); //Envia sinal para a thread de manipulação dos timers para ativar os timers agendados               
    //comLedIn=!comLedIn;
    //pc.printf("%c",RBR);
}

uint16_t modBusMaster1::sendFrame(uint16_t tamBytes){
    uint16_t timeout = 500;
    uint16_t i;
    #ifdef modbusDebug
    //DEBUG Mostrando o que é enviado via modbus
    pc.printf("Frame enviado (hexa) <");
    for(i=0;i<tamBytes;i++){       
        pc.printf("%02x ",modBusMaster1::buffer[i]);                
    }                
    pc.printf(">.\n");
    #endif
    
    osDelay(5);    
    
    modBusMaster1::pacoteEmEspera = false;
    modBusMaster1::index=0;
    *modBusMaster1::de=1;    
    //wait_us(1750);    
    osDelay(2);    
    for(i=0;i<tamBytes;i++){       
        modBusMaster1::serModBus->putc(modBusMaster1::buffer[i]);        
        //wait_us(750);            
        while( 
        ((LPC_UART1->LSR >> 6) &0x1)
         == 0 );
        //osDelay(1);
    }                
    //wait_us(1750);    
    //osDelay(1);    
    *modBusMaster1::de=0;
    
    while((timeout>0)&&(modBusMaster1::pacoteEmEspera!=true)){
        osDelay(1);        
        //wait_us(1000);
        timeout--;   
    }         
    return timeout;
}

uint8_t modBusMaster1::readRegister16BIT(uint8_t enderecoSlave,uint8_t funcao,uint16_t registrador,uint16_t qtdRegistros,uint16_t *var){
    union{
       char c[2];
       uint16_t v; 
    }u;
    uint16_t crc;
    uint16_t qtd_dados_recebidos;    
    uint16_t i;
    uint8_t result;
    
    for(i=0;i<qtdRegistros;i++){
        var[i]=NULL;
    }
    
    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=funcao;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    modBusMaster1::buffer[4]=qtdRegistros>>8;
    modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
    
    modBusMaster1::buffer[6]=crc>>8;
    modBusMaster1::buffer[7]=(crc & 0xFF);       
    
    
            
    if(!modBusMaster1::sendFrame(8)){
        pc.printf("Erro de timeout.\n");
        return 254;   
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        return 255;    
    }
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
        qtd_dados_recebidos = modBusMaster1::buffer[2]/2;    
        for(i=0;i<qtd_dados_recebidos;i++){        
            u.c[1]=modBusMaster1::buffer[(i*2)+3];
            u.c[0]=modBusMaster1::buffer[(i*2)+4];
            var[i]=u.v;
        }
        result = 0;
     }
    
    
    
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}

uint8_t modBusMaster1::writeSingleCoil(uint8_t enderecoSlave,uint16_t registrador,bool var){
    uint16_t crc;
    uint8_t result = 1;    //Tudo ok ate que se prove o contrario.
    uint16_t estadoSetado;    

    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=5;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    
    if(var){
        modBusMaster1::buffer[4]=0xFF;
        modBusMaster1::buffer[5]=0x00;
        estadoSetado = 0xFF00;
            
    }else{
        modBusMaster1::buffer[4]=0x00;
        modBusMaster1::buffer[5]=0x00;    
        estadoSetado = 0x0000;
     }
    
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
    
    modBusMaster1::buffer[6]=crc>>8;
    modBusMaster1::buffer[7]=(crc & 0xFF);       
    
    
            
    if(!modBusMaster1::sendFrame(8)){
        pc.printf("Erro de timeout.\n");
        result = 254;
        return result;
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        result = 255;
        return result;
    }
    
    if(result){
        if(modBusMaster1::buffer[1]&(0x1<<7)){        
            result = modBusMaster1::buffer[2];
        }else{
            if(
                (((modBusMaster1::buffer[2]<<8)+(modBusMaster1::buffer[3]))==registrador)
                    &&
                (((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))==estadoSetado) 
            ){
                result=0;
             }else{
                result=253;   
              }
         }    
    }
    
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}

uint8_t modBusMaster1::readCoils(uint8_t enderecoSlave,uint16_t registrador,uint16_t qtdRegistros,bool *var){
    uint16_t crc;
    uint8_t result;    
    uint16_t i;
    
    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=1;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    modBusMaster1::buffer[4]=qtdRegistros>>8;
    modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);    
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
    
    modBusMaster1::buffer[6]=crc>>8;
    modBusMaster1::buffer[7]=(crc & 0xFF);       
    
    
            
    if(!modBusMaster1::sendFrame(8)){
        pc.printf("Erro de timeout.\n");
        return 254;   
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        return 255;    
    }
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{    
        if(
            modBusMaster1::buffer[2] == (1+((uint16_t)(qtdRegistros/8)))
        ){
            //Bloco de leitura das coils
            for(i=0;i<qtdRegistros;i++){
                var[i] = (
                            (modBusMaster1::buffer[(i/8)+3] & ( 0x1 << (i%8) )) >0
                         );    
            }
            result = 0;
         }else{            
            result = 253; 
          }
    }
    
    
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}
uint8_t modBusMaster1::readRegister32BIT(uint8_t enderecoSlave,uint8_t funcao,uint16_t registrador,uint16_t qtdRegistros,uint32_t *var){
    union{
       char c[4];
       uint32_t v; 
    }u;
    uint16_t crc;
    uint16_t qtd_dados_recebidos;    
    uint16_t i;
    uint8_t result;
    
    for(i=0;i<qtdRegistros;i++){
        var[i]=NULL;
    }
    
    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=funcao;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    modBusMaster1::buffer[4]=qtdRegistros>>8;
    modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
    
    modBusMaster1::buffer[6]=crc>>8;
    modBusMaster1::buffer[7]=(crc & 0xFF);       
    
    
            
    if(!modBusMaster1::sendFrame(8)){
        pc.printf("Erro de timeout.\n");
        return 254;   
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        return 255;    
    }
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
    
        qtd_dados_recebidos = modBusMaster1::buffer[2]/4;    
        for(i=0;i<qtd_dados_recebidos;i++){        
            u.c[3]=modBusMaster1::buffer[(i*4)+3];
            u.c[2]=modBusMaster1::buffer[(i*4)+4];
            u.c[1]=modBusMaster1::buffer[(i*4)+5];
            u.c[0]=modBusMaster1::buffer[(i*4)+6];
            var[i]=u.v;
        }
        result =0;
     }
    
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;    
}

uint8_t modBusMaster1::writeRegister16BIT(uint8_t enderecoSlave,uint16_t registrador,uint16_t qtdRegistros,uint16_t *var){    
    uint16_t i;
    uint16_t crc;
    uint8_t result;
    
    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=16;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    modBusMaster1::buffer[4]=qtdRegistros>>8;
    modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
    modBusMaster1::buffer[6]=qtdRegistros*2;       
    
    for(i=0;i<qtdRegistros;i++){
        modBusMaster1::buffer[(i*2)+7]=var[i]>>8;
        modBusMaster1::buffer[(i*2)+8]=var[i]&0xFF;
    }
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,((qtdRegistros)*2)+7);
    
    modBusMaster1::buffer[(qtdRegistros*2)+7]=crc>>8;;
    modBusMaster1::buffer[(qtdRegistros*2)+8]=(crc & 0xFF);
    
    
    
    //Enviando frame
    if(!modBusMaster1::sendFrame((qtdRegistros*2)+9)){
        pc.printf("Erro de timeout.\n");
        return 254;   
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        return 255;    
    }
        
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0;
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
    
        //Interpratando resposta
        if(((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))!=qtdRegistros){
            return 253;
        }else{
            result = 0;
         }
    }
    return result;
}

uint8_t modBusMaster1::writeRegister32BIT(uint8_t enderecoSlave,uint16_t registrador,uint16_t qtdRegistros,uint32_t *var){    
    uint16_t i;
    uint16_t crc;
    uint8_t result;
    
    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=16;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    modBusMaster1::buffer[4]=qtdRegistros>>8;
    modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
    modBusMaster1::buffer[6]=qtdRegistros*4;       
    
    for(i=0;i<qtdRegistros;i++){
        modBusMaster1::buffer[(i*4)+7]=(var[i]>>24)&0xFF;
        modBusMaster1::buffer[(i*4)+8]=(var[i]>>16)&0xFF;
        modBusMaster1::buffer[(i*4)+9]=(var[i]>>8)&0xFF;
        modBusMaster1::buffer[(i*4)+10]=var[i]&0xFF;
    }
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,((qtdRegistros)*4)+7);
    
    modBusMaster1::buffer[(qtdRegistros*4)+7]=crc>>8;;
    modBusMaster1::buffer[(qtdRegistros*4)+8]=(crc & 0xFF);
    
    
    
    //Enviando frame
    if(!modBusMaster1::sendFrame((qtdRegistros*4)+9)){
        pc.printf("Erro de timeout.\n");
        return 254;   
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        return 255;    
    }
        
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0;
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
    
        //Interpratando resposta
        if(((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))!=qtdRegistros){
            return 253;
        }else{
            result = 0;   
         }
    }
    return result;
}

uint8_t modBusMaster1::writeFloat(uint8_t enderecoSlave,uint16_t registrador,uint8_t qtdRegistros,float *var){    
    union{
       char c[4];
       float v;        
    }u;    
    uint16_t i;
    uint16_t crc;
    uint8_t result;
    
    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=16;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    modBusMaster1::buffer[4]=qtdRegistros>>8;
    modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
    modBusMaster1::buffer[6]=qtdRegistros*4;       
    
    for(i=0;i<qtdRegistros;i++){
        u.v = var[i];
        modBusMaster1::buffer[(i*4)+7]=u.c[3];
        modBusMaster1::buffer[(i*4)+8]=u.c[2];
        modBusMaster1::buffer[(i*4)+9]=u.c[1];
        modBusMaster1::buffer[(i*4)+10]=u.c[0];
    }
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,((qtdRegistros)*4)+7);
    
    modBusMaster1::buffer[(qtdRegistros*4)+7]=crc>>8;;
    modBusMaster1::buffer[(qtdRegistros*4)+8]=(crc & 0xFF);
    
    
    
    //Enviando frame
    if(!modBusMaster1::sendFrame((qtdRegistros*4)+9)){
        pc.printf("Erro de timeout.\n");
        return 254;   
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        return 255;    
    }
        
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0;
   
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{ 
        //Interpratando resposta
        if(((modBusMaster1::buffer[4]<<8)+(modBusMaster1::buffer[5]))!=qtdRegistros){
            return 253;
        }else{
            result = 0;   
         }
     }
    return result;
}

uint8_t modBusMaster1::readFloat(uint8_t enderecoSlave,uint8_t funcao,uint16_t registrador,uint16_t qtdRegistros,float *var){
    union {
        char c[4];
        float v;
    }u;
    uint16_t crc;
    uint16_t qtd_dados_recebidos;
    //void *p;
    uint16_t i; 
    uint8_t result;
    
    for(i=0;i<qtdRegistros;i++){
        var[i]=0.0;
    }
       
    modBusMaster1::buffer[0]=enderecoSlave;
    modBusMaster1::buffer[1]=funcao;
    modBusMaster1::buffer[2]=registrador>>8;
    modBusMaster1::buffer[3]=(registrador & 0xFF);
    modBusMaster1::buffer[4]=qtdRegistros>>8;
    modBusMaster1::buffer[5]=(qtdRegistros & 0xFF);
    
    crc=modBusMaster1::CRC16(modBusMaster1::buffer,6);
    
    modBusMaster1::buffer[6]=crc>>8;
    modBusMaster1::buffer[7]=(crc & 0xFF);       
    

        
    if(!modBusMaster1::sendFrame(8)){
        pc.printf("Erro de timeout.\n");
        return 254;   
    }    
    
    if(!modBusMaster1::pacoteEmEspera){
        pc.printf("Erro de CRC.\n");
        return 255;    
    }
    
    
    /*
    for(i=3;i<modBusMaster1::index-2;i++){    
        u.c[3-(i-3)]= modBusMaster1::buffer[i];
    }
        
    *var = u.f;
    */
    
    
    /*pc.printf("Lido pacote de modBus <0x");
    
    for(i=0;i<modBusMaster1::index;i++){
        pc.printf("%02x ",modBusMaster1::buffer[i]);        
    }
    pc.printf(">.\n");*/
    
    if(modBusMaster1::buffer[1]&(0x1<<7)){        
        result = modBusMaster1::buffer[2];
    }else{
        qtd_dados_recebidos = modBusMaster1::buffer[2]/4;    
        for(i=0;i<qtd_dados_recebidos;i++){
            u.c[3]=modBusMaster1::buffer[(i*4)+3];
            u.c[2]=modBusMaster1::buffer[(i*4)+4];
            u.c[1]=modBusMaster1::buffer[(i*4)+5];
            u.c[0]=modBusMaster1::buffer[(i*4)+6];
            var[i]=u.v;
        }    
        result = 0;
     }
    modBusMaster1::pacoteEmEspera = false; //Sinalizo que li o pacote
    modBusMaster1::index = 0; 
    return result;
}