teste de publish
Dependencies: DS1820 HighSpeedAnalogIn devices mbed
modbusMaster1.cpp
- Committer:
- brunofgc
- Date:
- 2018-04-19
- Revision:
- 26:c246eacf6815
- Parent:
- 25:a6da63ed025b
- Child:
- 32:7cf1fb8a8bf3
File content as of revision 26:c246eacf6815:
#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; uint16_t modBusMaster1::T3_5; uint16_t modBusMaster1::T1_5; bool modBusMaster1::pacoteEmEspera; uint16_t modBusMaster1::MODBUS_TIMEOUT; 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; if(debug){ //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"); } 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; //Criando timer_pacote modBusMaster1::timer_pacote = osTimerCreate(osTimer(timerProcessaPacoteModBusMaster1),osTimerOnce,NULL); } void modBusMaster1::setBaud(uint32_t baud){ modBusMaster1::serModBus->baud(baud); if (baud > 19200){ modBusMaster1::T1_5 = 750; modBusMaster1::T3_5 = 1750; }else { modBusMaster1::T1_5 = 15000000/baud; modBusMaster1::T3_5 = 35000000/baud; } } 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 = modBusMaster1::MODBUS_TIMEOUT; uint16_t i; uint16_t retentativas = 5; uint16_t delayEntreTentativas = 500; while(retentativas){ if(debug){ //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"); } 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 ); //wait_us(modBusMaster1::T1_5); } //wait_us(1750); //osDelay(1); *modBusMaster1::de=0; while((timeout>0)&&(modBusMaster1::pacoteEmEspera!=true)){ osDelay(1); //wait_us(1000); timeout--; } wait_us(modBusMaster1::T3_5*2); if((!timeout) && (!modBusMaster1::pacoteEmEspera)){ osDelay(delayEntreTentativas); retentativas--; if(debug){ //DEBUG Mostrando o que é enviado via modbus pc.printf("Retentativa de comando modbus.\r\n"); } }else{ retentativas = 0; } } 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; }