Microgenios Tecnologia e Educação
31/05/2022 12:37:39
Este tópico foi movido no dia 31/05/2022, pois o aluno (TALLES NEWTON DE CARVALHO) tinha postado no local errado.
Bom dia, Fernando
estou estudando sobre o modbus e vou ter uma aplicação que necessito do microcontrolador ser um modbus slave para comunicação com um supervisorio que tenho, e ao mesmo tempo, gostaria de incluir algumas IO expander que imagino fazer por comunicação I2C, gostaria de saber se o microcontrolador pode ser slave com protocolo modbus e master com protocolo I2C ao mesmo tempo?
e se sim, algumas literaturas que posso ir vendo sobre o assunto, ou ate mesmo algo no curso, Obrigado
FERNANDO SIMPLICIO DE SOUSA
31/05/2022 13:48:00
Sim, é possível. Você pode seguir o exemplo abaixo. A função MBSlaveFunc03CallBack é chamada quando o Master requisita o Slave via função holding register. O Slave, faz a leitura do sensor I2C (como master no barramento I2c) e retorna o valor para o Modbus Master.
#include "lib/defs.h" #include "lib/lcd.h" #include "lib/mb_config.h" #include "lib/mb_timer.h" #include "lib/mb_serial.h" void INTERRUPCAO() iv 0x0008 ics ICS_AUTO { uart_irq(); timer_irq(); } BOOL MBSlaveFunc03CallBack( UCHAR * wRegHoldingbuffer, USHORT startAddress, USHORT numberOfPoints ) { char byte; /* startAddress = armazena o endereço de offset da requisição do master; numberOfPoints = quantidade de registradores a serem lidos; wRegHoldingbuffer = endereço do buffer que receberá o conteúdo lido via I2C; */ I2C1_Start(); // issue I2C start signal I2C1_Wr(0xA2); // send byte via I2C (device address + W) I2C1_Wr(2); // send byte (data address) I2C1_Repeated_Start(); // issue I2C signal repeated start I2C1_Wr(0xA3); // send byte (device address + R) byte = I2C1_Rd(0u); // Read the data (NO acknowledge) I2C1_Stop(); // issue I2C stop signal if(numberOfPoints > 0) { wRegHoldingbuffer[0] = byte; //retorna para o Modbus Master o valor lido via I2C; } return TRUE; } /** * Modbus RTU Function Code 03 - Modo Slave */ void main( void ) { #ifdef P18F45K22 ANSELA = 0; ANSELB = 0; ANSELC = 0; ANSELD = 0; ANSELE = 0; #else ADCON1 |= 0X0F; #endif uart_init(); timer_init(); /** * Função LCD do compilador mikroC */ Lcd_Init(); Lcd_Cmd(_LCD_CLEAR); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Out(1,1, "ADD: "); Lcd_Out(2,1, "REG: "); I2C1_Init(100000); // initialize I2C communication for(;;) { MB(); } }
EDEMILSO FARIAS ILHA
03/06/2022 13:49:03
Olá,
Apenas uma pequena dica: eu prefiro tratar a leitura de sensores antes, armazenar isso numa variável e quando requisitado pelo Master, apenas envia essa informação já tratada e não fazer a sua captura durante a requisição do Master.
Esse procedimento pode evitar Timeout do Master durante sua requisição dependendo do que está sendo processado, principalmente em redes maiores, onde a espera pela resposta é importante.
Um abraço a todos.