Modbus_master_2/modbus/modbus.c

284 lines
6.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdint.h>
unsigned int CRC16_Modbus(unsigned char* buf, int len)
{
unsigned int crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
crc ^= (unsigned int)buf[pos]; // XOR-байт в наименьший sig. байт crc
for (int i = 8; i != 0; i--) // Повторите цикл над каждым битом
{
if ((crc & 0x0001) != 0) // Если установлен LSB
{
crc >>= 1; // Сдвиг вправо и XOR 0xA001
crc ^= 0xA001;
}
else // В противном случае LSB не установлен
{
crc >>= 1; // Сдвиг вправо
}
}
}
crc = ((crc & 0x00ff) << 8) | ((crc & 0xff00) >> 8); // преобразование младших байтов
return crc;
}
size_t read_coil_status(uint8_t address, uint16_t discret_input, unint8_t* buf, size_t buf_len)
{
int i = 0;
buf[i] = address;
i++;
buf[i] = 0x01;
i++;
buf[i] = (discret_input >> 8) & 0xFF;
i++;
buf[i] = discret_input & 0xFF;
i++;
buf[i] = 0x00;
i++;
buf[i] = 0x01;
i++;
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}
size_t read_coil_status_ans(unit8_t address, uint8_t meaning, unint8_t* buf, size_t buf_len)
{
n = 0;
buf[n] = address;
n++;
buf[n] = 0x01;
n++;
buf[n] = 0x01;
n++;
buf[n] = meaning;
n++;
crc_otv = CRC16_Modbus(buf, n);
buf[n] = crc_otv & 0xFF;
i++;
buf[n] = (crc_otv >> 8) & 0xFF;
i++;
return n;
}
size_t read_input_status(uint8_t address, uint16_t discret_input, unint8_t* buf, size_t buf_len)
{
int i=0;
buf[i] = address;
i++;
buf[i] = 0x02;
i++;
buf[i] = (discret_input >>8)&0xFF;
i++;
buf[i] = discret_input&0xFF;
i++;
buf[i] = 0x00;
i++;
buf[i] = 0x01;
i++;
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}
size_t read_input_status_ans(unit8_t address, uint8_t meaning, unint8_t* buf, size_t buf_len)
{
n = 0;
buf[n] = address;
n++;
buf[n] = 0x02;
n++;
buf[n] = 0x01;
n++;
buf[n] = meaning;
n++;
crc_otv = CRC16_Modbus(buf, n);
buf[n] = crc_otv & 0xFF;
i++;
buf[n] = (crc_otv >> 8) & 0xFF;
i++;
return n;
}
size_t read_holding_register(uint8_t address, uint16_t holding_reg, unint8_t* buf, size_t buf_len)
{
int i = 0;
buf[i] = address;
i++;
buf[i] = 0x03;
i++;
buf[i] = (holding_reg >> 8) & 0xFF;
i++;
buf[i] = holding_reg & 0xFF;
i++;
buf[i] = 0x00;
i++;
buf[i] = 0x01;
i++;
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}
size_t read_holding_register_ans(unit8_t address, uint8_t meaning, unint8_t* buf, size_t buf_len)
{
n = 0;
buf[n] = address;
n++;
buf[n] = 0x03;
n++;
buf[n] = 0x01;
n++;
buf[n] = meaning;
n++;
crc_otv = CRC16_Modbus(buf, n);
buf[n] = crc_otv & 0xFF;
i++;
buf[n] = (crc_otv >> 8) & 0xFF;
i++;
return n;
}
size_t read_input_register(uint8_t address, uint16_t input_reg, unint8_t* buf, size_t buf_len)
{
int i = 0;
buf[i] = address;
i++;
buf[i] = 0x04;
i++;
buf[i] = (input_reg >> 8) & 0xFF;
i++;
buf[i] = input_reg & 0xFF;
i++;
buf[i] = 0x00;
i++;
buf[i] = 0x01;
i++;
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}
size_t read_input_register_ans(unit8_t address, uint8_t meaning, unint8_t* buf, size_t buf_len)
{
n = 0;
buf[n] = address;
n++;
buf[n] = 0x04;
n++;
buf[n] = 0x01;
n++;
buf[n] = meaning;
n++;
crc_otv = CRC16_Modbus(buf, n);
buf[n] = crc_otv & 0xFF;
i++;
buf[n] = (crc_otv >> 8) & 0xFF;
i++;
return n;
}
size_t forse_single_coil(unit8_t address, uint16_t address_input, int on, unint8_t* buf, size_t buf_len)
{
int i = 0;
buf[i] = address;
i++;
buf[i] = 0x05;
i++;
buf[i] = (address_input >> 8)&0xFF;
i++;
buf[i] = address_input & 0xFF;
i++;
buf[i] = on ? 0xFF : 0x00;
i++;
buf[i] = 0x00;
i++
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}
size_t forse_single_coil_ans(unit8_t address, uint16_t address_input, int on, unint8_t* buf, size_t buf_len)
{
int i = 0;
buf[i] = address;
i++;
buf[i] = 0x05;
i++;
buf[i] = (address_input >> 8) & 0xFF;
i++;
buf[i] = address_input & 0xFF;
i++;
buf[i] = on ? 0xFF : 0x00;
i++;
buf[i] = 0x00;
i++
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}
size_t preset_single_register(unit8_t address, uint16_t address_input, uint16_t recorded_value, unint8_t* buf, size_t buf_len)
{
int i = 0;
buf[i] = address;
i++;
buf[i] = 0x06;
i++;
buf[i] = (address_input >> 8) & 0xFF;
i++;
buf[i] = address_input & 0xFF;
i++;
buf[i] = (recorded_value >> 8) & 0xFF;
i++;
buf[i] = recorded_value & 0xFF;
i++;
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}
size_t preset_single_register_ans(unit8_t address, uint16_t address_input, uint16_t recorded_value, unint8_t* buf, size_t buf_len)
{
int i = 0;
buf[i] = address;
i++;
buf[i] = 0x06;
i++;
buf[i] = (address_input >> 8) & 0xFF;
i++;
buf[i] = address_input & 0xFF;
i++;
buf[i] = (recorded_value >> 8) & 0xFF;
i++;
buf[i] = recorded_value & 0xFF;
i++;
crc = CRC16_Modbus(buf, i);
buf[i] = crc & 0xFF;
i++;
buf[i] = (crc >> 8) & 0xFF;
i++;
return i;
}