matlab_23550/Inu/Src/N12_Libs/RS_modbus_pultl.c
Razvalyaev 7e0063eee0 #3 Скомпилилось, но пока ничего не вызывается
Все основные файлы подтянуты без изменений

Изменены (только папка main_matlab):
- заглушки для ненужных функций (main_matlab.c)
- iq библиотека (IQmathLib_matlab.c)
- библиотеки DSP281x
2025-01-13 11:09:58 +03:00

1014 lines
36 KiB
C

#include <modbus_hmi.h>
#include "control_station.h"
#include "modbus_table_v2.h"
#include "options_table.h"
#include "RS_modbus_pult.h"
#include "DSP281x_Device.h"
#include "CRC_Functions.h"
#include "RS_Functions.h"
#include "RS_modbus_svu.h"
//#pragma DATA_SECTION(p_analog_data_in, ".logs");
MODBUS_REG_STRUCT *p_analog_data_in;
//#pragma DATA_SECTION(p_analog_data_out, ".logs");
MODBUS_REG_STRUCT *p_analog_data_out;
//#pragma DATA_SECTION(p_discrete_data_out, ".logs");
MODBUS_REG_STRUCT *p_discrete_data_out;
//#pragma DATA_SECTION(p_discrete_data_in, ".logs");
MODBUS_REG_STRUCT *p_discrete_data_in;
static int adres_wait_answer_cmd1 = 0;
static int count_registers_wait_answer = 0;
void ModbusRTUsetDataArrays(MODBUS_REG_STRUCT *array_in, MODBUS_REG_STRUCT *array_out)
{
p_analog_data_in = array_in;
p_analog_data_out = array_out;
}
void ModbusRTUsetDiscretDataArray(MODBUS_REG_STRUCT *discrete_in, MODBUS_REG_STRUCT *discrete_out)
{
p_discrete_data_in = discrete_in;
p_discrete_data_out = discrete_out;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************/
/***************************************************************/
/* Îòïðàâêà çàïðîñà äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 1
×òåíèå ß÷ååê äàííûõ Digital Output Holding Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUsend1(RS_DATA_STRUCT *rs_arr, int adr_contr, unsigned int adr_start, unsigned int count_bits)
{
// Êîíòðîëüíàß ñóììà
unsigned int crc;
unsigned int count_data_bytes;
count_data_bytes = (count_bits % 8) == 0 ? count_bits / 8 : count_bits / 8 + 1;
rs_arr->buffer[0] = LOBYTE(adr_contr);
rs_arr->buffer[1] = CMD_RS232_MODBUS_1;
rs_arr->buffer[2] = HIBYTE(adr_start);
rs_arr->buffer[3] = LOBYTE(adr_start);
rs_arr->buffer[4] = HIBYTE(count_bits);
rs_arr->buffer[5] = LOBYTE(count_bits);
crc = 0xffff;
crc = GetCRC16_IBM(crc, rs_arr->buffer, 6);
rs_arr->buffer[6] = LOBYTE(crc);
rs_arr->buffer[7] = HIBYTE(crc);
rs_arr->buffer[8] = 0;
rs_arr->buffer[9] = 0;
rs_arr->RS_DataWillSend = 1;
rs_arr->RS_DataWillSend2 = 1;
RS_Send(rs_arr, rs_arr->buffer, 10);
/* æäåì îòâåòà */
if (adr_contr > 0 && adr_contr < 0xff)
{
RS_Len[CMD_RS232_MODBUS_1] = 5 + count_data_bytes;
count_registers_wait_answer = count_bits;
adres_wait_answer_cmd1 = adr_start;
RS_SetControllerLeading(rs_arr, true);
RS_SetAdrAnswerController(rs_arr, adr_contr);
}
return;
}
/***************************************************************/
/***************************************************************/
/* Îòâåò ñ äàííûìè ïî ïðîòîêîëó ModBus - êîìàíäà 1
×òåíèå ß÷ååê äàííûõ Digital Output Holding Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUreceiveAnswer1(RS_DATA_STRUCT *RS232_Arr)
{
unsigned int first_word, end_byte_number, count_data_bytes, current_register, last_register;
unsigned int displacement_start, displacement, displacement_end, bits_in_last_byte, byte, mask = 0, mask_start, mask_end;
unsigned int i = 0, b = 0, buffer_position = 0, j = 0;
// unsigned char byte_buffer[SIZE_MODBUS_TABLE_DISCRET * 2];
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèß. */
first_word = (adres_wait_answer_cmd1 % 16 == 0) && (adres_wait_answer_cmd1 != 0)
? adres_wait_answer_cmd1 / 16 + 1
: adres_wait_answer_cmd1 / 16;
displacement_start = adres_wait_answer_cmd1 % 16;
displacement = adres_wait_answer_cmd1 % 16;
count_data_bytes = RS232_Arr->RS_Header[2];
current_register = adres_wait_answer_cmd1;
last_register = adres_wait_answer_cmd1 + count_registers_wait_answer;
displacement_end = last_register % 16;
/////////////////////////////////////////////////
mask = 0;
mask_start = 0;
mask_end = 0;
for (i = 0; i < displacement_start; ++i)
{
mask_start |= 1 << i;
mask_end |= 1 << i;
}
mask_start = ~mask_start;
displacement = displacement_start;
for (i = 0; i < count_data_bytes; ++i)
{
byte = RS232_Arr->RS_Header[3 + i];
mask = 0;
if ((last_register - current_register) > 8) {
mask = 0xFF;
} else {
for (j = 0; j < (last_register - current_register); ++j) {
mask |= 1 << j;
}
}
if (displacement < 8)
{
//mask = mask << displacement;
p_discrete_data_out[first_word].all &= ~(mask << displacement);
p_discrete_data_out[first_word].all |= (byte & mask) << displacement;
} else {
mask_start = (mask << displacement) & 0xFF00;
p_discrete_data_out[first_word].all &= ~mask_start;
p_discrete_data_out[first_word].all |= (byte & mask) << displacement;
mask_end = (mask >> (16 - displacement)) & 0xFF;
p_discrete_data_out[first_word].all &= ~mask_end;
p_discrete_data_out[first_word + 1].all |= (byte & mask) >> (16 - displacement);
}
displacement += 8;
if (displacement >= 16) {
displacement -= 16;
first_word += 1;
}
current_register += 8;
}
RS_SetControllerLeading(RS232_Arr, false);
RS_SetAdrAnswerController(RS232_Arr, 0);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************/
/***************************************************************/
/* Çàïðîñ äàííûõ îò ìàñòåðà ïî ïðîòîêîëó ModBus - êîìàíäà 3
×òåíèå ß÷ååê äàííûõ Analog Input Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUreceive3(RS_DATA_STRUCT *RS232_Arr)
{
// Êîíòðîëüíày ñóììà
unsigned int crc, Address_MB, Length_MB, i /*, Data*/;
// int buf_out[200];
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèy. */
Address_MB = (RS232_Arr->RS_Header[2] << 8) | RS232_Arr->RS_Header[3];
/* ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ */
Length_MB = (RS232_Arr->RS_Header[4] << 8) | RS232_Arr->RS_Header[5];
/////////////////////////////////////////////////
// Îòñûëêà
/* Ïîñ÷èòàëè êîíòðîëüíóþ ñóììó ïåðåä ñàìîé ïîñûëêîé */
// f.RScount = SECOND*3;
RS232_Arr->buffer[0] = RS232_Arr->addr_recive; //CNTRL_ADDR;
RS232_Arr->buffer[1] = CMD_RS232_MODBUS_3;
RS232_Arr->buffer[2] = Length_MB * 2;
for (i = 0; i < Length_MB; i++)
{
if (Address_MB >= ADR_MODBUS_TABLE && Address_MB < 0xe00)
{
// RS232_Arr->buffer[3 + i * 2] = p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.HB;
// RS232_Arr->buffer[3 + i * 2 + 1] = p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.LB;
RS232_Arr->buffer[3 + i * 2] = p_analog_data_out[Address_MB + i].byte.HB;
RS232_Arr->buffer[3 + i * 2 + 1] = p_analog_data_out[Address_MB + i].byte.LB;
}
if (Address_MB >= 0xe00 && Address_MB < 0xf00)
{
RS232_Arr->buffer[3 + i * 2] = options_controller[Address_MB - 0xe00 + i].byte.HB;
RS232_Arr->buffer[3 + i * 2 + 1] = options_controller[Address_MB - 0xe00 + i].byte.LB;
}
}
crc = 0xffff;
crc = GetCRC16_IBM(crc, RS232_Arr->buffer, Length_MB * 2 + 3);
RS232_Arr->buffer[Length_MB * 2 + 3] = LOBYTE(crc);
RS232_Arr->buffer[Length_MB * 2 + 4] = HIBYTE(crc);
RS232_Arr->buffer[Length_MB * 2 + 5] = 0;
RS232_Arr->buffer[Length_MB * 2 + 6] = 0;
// RS232_Arr->RS_DataWillSend = 1;
RS_Send(RS232_Arr, RS232_Arr->buffer, Length_MB * 2 + 7);
return;
}
/***************************************************************/
/***************************************************************/
/* Îòïðàâêà çàïðîñà äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 3
×òåíèå ß÷ååê äàííûõ Analog Input Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUsend3(RS_DATA_STRUCT *rs_arr, int adr_contr, unsigned int adr_start, unsigned int count_word)
{
// Êîíòðîëüíàß ñóììà
unsigned int crc; //, Address_MB, Length_MB, i, Data;
// int buf_out[200];
// int buf_in[200];
rs_arr->buffer[0] = LOBYTE(adr_contr);
rs_arr->buffer[1] = CMD_RS232_MODBUS_3;
rs_arr->buffer[2] = HIBYTE(adr_start);
rs_arr->buffer[3] = LOBYTE(adr_start);
rs_arr->buffer[4] = 0;
rs_arr->buffer[5] = LOBYTE(count_word);
crc = 0xffff;
crc = GetCRC16_IBM(crc, rs_arr->buffer, 6);
rs_arr->buffer[6] = LOBYTE(crc);
rs_arr->buffer[7] = HIBYTE(crc);
rs_arr->buffer[8] = 0;
rs_arr->buffer[9] = 0;
rs_arr->RS_DataWillSend = 1;
rs_arr->RS_DataWillSend2 = 1;
RS_Send(rs_arr, rs_arr->buffer, 10);
/* æäåì îòâåòà */
if (adr_contr > 0 && adr_contr < 0xff)
{
RS_Len[CMD_RS232_MODBUS_3] = 5 + count_word * 2;
adr_read_from_modbus3 = adr_start;
RS_SetControllerLeading(rs_arr, true);
RS_SetAdrAnswerController(rs_arr, adr_contr);
}
return;
}
/***************************************************************/
/***************************************************************/
/* Îòâåò ñ äàííûìè ïî ïðîòîêîëó ModBus - êîìàíäà 3
×òåíèå ß÷ååê äàííûõ Analog Input Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUreceiveAnswer3(RS_DATA_STRUCT *RS232_Arr)
{
unsigned int Address_MB, Length_MB, i;
MODBUS_REG_STRUCT elementData;
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèß. */
Address_MB = adr_read_from_modbus3;
/* ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ */
Length_MB = RS232_Arr->RS_Header[2] >> 1;
/////////////////////////////////////////////////
// Îòñûëêà
/* Ïîñ÷èòàëè êîíòðîëüíóþ ñóììó ïåðåä ñàìîé ïîñûëêîé */
for (i = 0; i < Length_MB; i++)
{
elementData.byte.HB = RS232_Arr->RS_Header[3 + i * 2];
elementData.byte.LB = RS232_Arr->RS_Header[3 + i * 2 + 1];
// p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].all = elementData.all;
if ((Address_MB + i)<SIZE_MODBUS_ANALOG_REMOUTE) // çàùèòà îò ïåðåïîëíåíèÿ
p_analog_data_out[Address_MB + i].all = elementData.all;
}
RS_SetControllerLeading(RS232_Arr, false);
RS_SetAdrAnswerController(RS232_Arr, 0);
err_modbus3 = 0;
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************/
/***************************************************************/
/* Îòïðàâêà çàïðîñà äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 4
×òåíèå ß÷ååê äàííûõ Analog Output Holding Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUsend4(RS_DATA_STRUCT *rs_arr, int adr_contr, unsigned int adr_start, unsigned int count_word)
{
// Êîíòðîëüíàß ñóììà
unsigned int crc; //, Address_MB, Length_MB, i, Data;
// int buf_out[200];
// int buf_in[200];
rs_arr->buffer[0] = LOBYTE(adr_contr);
rs_arr->buffer[1] = CMD_RS232_MODBUS_4;
rs_arr->buffer[2] = HIBYTE(adr_start);
rs_arr->buffer[3] = LOBYTE(adr_start);
rs_arr->buffer[4] = 0;
rs_arr->buffer[5] = LOBYTE(count_word);
crc = 0xffff;
crc = GetCRC16_IBM(crc, rs_arr->buffer, 6);
rs_arr->buffer[6] = LOBYTE(crc);
rs_arr->buffer[7] = HIBYTE(crc);
rs_arr->buffer[8] = 0;
rs_arr->buffer[9] = 0;
rs_arr->RS_DataWillSend = 1;
rs_arr->RS_DataWillSend2 = 1;
RS_Send(rs_arr, rs_arr->buffer, 10);
/* æäåì îòâåòà */
if (adr_contr > 0 && adr_contr < 0xff)
{
RS_Len[CMD_RS232_MODBUS_4] = 5 + count_word * 2;
adr_read_from_modbus3 = adr_start;
RS_SetControllerLeading(rs_arr, true);
RS_SetAdrAnswerController(rs_arr, adr_contr);
}
return;
}
/***************************************************************/
/***************************************************************/
/* Îòâåò ñ äàííûìè ïî ïðîòîêîëó ModBus - êîìàíäà 4
×òåíèå ß÷ååê äàííûõ Analog Output Holding Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUreceiveAnswer4(RS_DATA_STRUCT *RS232_Arr)
{
unsigned int Address_MB, Length_MB, i;
static unsigned int prev_Address_MB = 0;
MODBUS_REG_STRUCT elementData;
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèß. */
Address_MB = adr_read_from_modbus3;
/* ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ */
Length_MB = RS232_Arr->RS_Header[2] >> 1;
/////////////////////////////////////////////////
// Îòñûëêà
/* Ïîñ÷èòàëè êîíòðîëüíóþ ñóììó ïåðåä ñàìîé ïîñûëêîé */
for (i = 0; i < Length_MB; i++)
{
elementData.byte.HB = RS232_Arr->RS_Header[3 + i * 2];
elementData.byte.LB = RS232_Arr->RS_Header[3 + i * 2 + 1];
// p_analog_data_in[Address_MB - ADR_MODBUS_TABLE + i].all = elementData.all;
if ((Address_MB + i)<SIZE_MODBUS_ANALOG_REMOUTE) // çàùèòà îò ïåðåïîëíåíèÿ
p_analog_data_in[Address_MB + i].all = elementData.all;
}
RS_SetControllerLeading(RS232_Arr, false);
RS_SetAdrAnswerController(RS232_Arr, 0);
if (Address_MB == 0 && prev_Address_MB != 0)
RS232_Arr->RS_DataReadyFullUpdate = 1;
prev_Address_MB = Address_MB;
return;
}
/***************************************************************/
/***************************************************************/
/* Çàïðîñ äàííûõ îò ìàñòåðà ïî ïðîòîêîëó ModBus - êîìàíäà 4
×òåíèå ß÷ååê äàííûõ Analog Output Holding Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUreceive4(RS_DATA_STRUCT *RS232_Arr)
{
// Êîíòðîëüíày ñóììà
unsigned int crc, Address_MB, Length_MB, i /*, Data*/;
// int buf_out[200];
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèy. */
Address_MB = (RS232_Arr->RS_Header[2] << 8) | RS232_Arr->RS_Header[3];
/* ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ */
Length_MB = (RS232_Arr->RS_Header[4] << 8) | RS232_Arr->RS_Header[5];
/////////////////////////////////////////////////
// Îòñûëêà
/* Ïîñ÷èòàëè êîíòðîëüíóþ ñóììó ïåðåä ñàìîé ïîñûëêîé */
// f.RScount = SECOND*3;
RS232_Arr->buffer[0] = RS232_Arr->addr_recive; //CNTRL_ADDR;
RS232_Arr->buffer[1] = CMD_RS232_MODBUS_4;
RS232_Arr->buffer[2] = Length_MB * 2;
for (i = 0; i < Length_MB; i++)
{
if (Address_MB >= ADR_MODBUS_TABLE && Address_MB < 0xe00)
{
// RS232_Arr->buffer[3 + i * 2] = p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.HB;
// RS232_Arr->buffer[3 + i * 2 + 1] = p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.LB;
RS232_Arr->buffer[3 + i * 2] = p_analog_data_out[Address_MB + i].byte.HB;
RS232_Arr->buffer[3 + i * 2 + 1] = p_analog_data_out[Address_MB + i].byte.LB;
}
if (Address_MB >= 0xe00 && Address_MB < 0xf00)
{
RS232_Arr->buffer[3 + i * 2] = options_controller[Address_MB - 0xe00 + i].byte.HB;
RS232_Arr->buffer[3 + i * 2 + 1] = options_controller[Address_MB - 0xe00 + i].byte.LB;
}
}
crc = 0xffff;
crc = GetCRC16_IBM(crc, RS232_Arr->buffer, Length_MB * 2 + 3);
RS232_Arr->buffer[Length_MB * 2 + 3] = LOBYTE(crc);
RS232_Arr->buffer[Length_MB * 2 + 4] = HIBYTE(crc);
RS232_Arr->buffer[Length_MB * 2 + 5] = 0;
RS232_Arr->buffer[Length_MB * 2 + 6] = 0;
// RS232_Arr->RS_DataWillSend = 1;
RS_Send(RS232_Arr, RS232_Arr->buffer, Length_MB * 2 + 7);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************/
/***************************************************************/
/* Îòïðàâêà çàïðîñà äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 5
×òåíèå ß÷ååê äàííûõ Analog Output Holding Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUsend5(RS_DATA_STRUCT *rs_arr, int adr_contr, unsigned int adr_start)
{
// Êîíòðîëüíàß ñóììà
unsigned int crc;
unsigned int byte_number;
unsigned int bit_number;
byte_number = adr_start / 16;
bit_number = adr_start % 16;
rs_arr->buffer[0] = LOBYTE(adr_contr);
rs_arr->buffer[1] = CMD_RS232_MODBUS_5;
rs_arr->buffer[2] = HIBYTE(adr_start);
rs_arr->buffer[3] = LOBYTE(adr_start);
if ((p_discrete_data_out[byte_number].all >> bit_number) & 1) {
rs_arr->buffer[4] = 0xFF;
rs_arr->buffer[5] = 0;
} else {
rs_arr->buffer[4] = 0;
rs_arr->buffer[5] = 0;
}
crc = 0xffff;
crc = GetCRC16_IBM(crc, rs_arr->buffer, 6);
rs_arr->buffer[6] = LOBYTE(crc);
rs_arr->buffer[7] = HIBYTE(crc);
rs_arr->buffer[8] = 0;
rs_arr->buffer[9] = 0;
rs_arr->RS_DataWillSend = 1;
rs_arr->RS_DataWillSend2 = 1;
RS_Send(rs_arr, rs_arr->buffer, 10);
/* æäåì îòâåòà */
if (adr_contr > 0 && adr_contr < 0xff)
{
RS_Len[CMD_RS232_MODBUS_5] = 8;
adr_read_from_modbus3 = adr_start;
RS_SetControllerLeading(rs_arr, true);
RS_SetAdrAnswerController(rs_arr, adr_contr);
}
return;
}
/****************************************************************/
/****************************************************************/
/* Îòâåò ñ äàííûìè ïî ïðîòîêîëó ModBus - êîìàíäà 5
Çàïèñü ß÷ååêè äàííûõ Digital Output Holding Registers */
/****************************************************************/
/****************************************************************/
void ModbusRTUreceiveAnswer5(RS_DATA_STRUCT *RS232_Arr)
{
unsigned int Address_MB, Length_MB, i;
MODBUS_REG_STRUCT elementData;
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèß. */
Address_MB = adr_read_from_modbus3;
/* ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ */
Length_MB = RS232_Arr->RS_Header[2] >> 1;
RS_SetControllerLeading(RS232_Arr, false);
RS_SetAdrAnswerController(RS232_Arr, 0);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************/
/***************************************************************/
/* Îòïðàâêà çàïðîñà äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 6
çàïèñü ß÷ååêè äàííûõ Analog Output Holding Registers */
/***************************************************************/
/***************************************************************/
void ModbusRTUsend6(RS_DATA_STRUCT *rs_arr, int adr_contr, unsigned int adr_start)
{
// Êîíòðîëüíàß ñóììà
unsigned int crc; //, Address_MB, Length_MB, i, Data;
// int buf_out[200];
// int buf_in[200];
rs_arr->buffer[0] = LOBYTE(adr_contr);
rs_arr->buffer[1] = CMD_RS232_MODBUS_6;
rs_arr->buffer[2] = HIBYTE(adr_start);
rs_arr->buffer[3] = LOBYTE(adr_start);
rs_arr->buffer[4] = HIBYTE(p_analog_data_out[adr_start].all);
rs_arr->buffer[5] = LOBYTE(p_analog_data_out[adr_start].all);
crc = 0xffff;
crc = GetCRC16_IBM(crc, rs_arr->buffer, 6);
rs_arr->buffer[6] = LOBYTE(crc);
rs_arr->buffer[7] = HIBYTE(crc);
rs_arr->buffer[8] = 0;
rs_arr->buffer[9] = 0;
rs_arr->RS_DataWillSend = 1;
rs_arr->RS_DataWillSend2 = 1;
RS_Send(rs_arr, rs_arr->buffer, 10);
// control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] = 1;
/* æäåì îòâåòà */
if (adr_contr > 0 && adr_contr < 0xff)
{
RS_Len[CMD_RS232_MODBUS_6] = 8;
adr_read_from_modbus3 = adr_start;
RS_SetControllerLeading(rs_arr, true);
RS_SetAdrAnswerController(rs_arr, adr_contr);
}
return;
}
/****************************************************************/
/****************************************************************/
/* Îòâåò ñ äàííûìè ïî ïðîòîêîëó ModBus - êîìàíäà 6
×òåíèå ß÷ååê äàííûõ Analog Output Holding Registers */
/****************************************************************/
/****************************************************************/
void ModbusRTUreceiveAnswer6(RS_DATA_STRUCT *RS232_Arr)
{
unsigned int Address_MB, Length_MB, i;
MODBUS_REG_STRUCT elementData;
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèß. */
Address_MB = adr_read_from_modbus3;
/* ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ */
Length_MB = RS232_Arr->RS_Header[2] >> 1;
RS_SetControllerLeading(RS232_Arr, false);
RS_SetAdrAnswerController(RS232_Arr, 0);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************/
/***************************************************************/
/* Îòïðàâêà çàïðîñà äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 15
Çàïèñü äèñêðåòíûõ äàííûõ äàííûõ Discrete Output Coils */
/***************************************************************/
/***************************************************************/
void ModbusRTUsend15(RS_DATA_STRUCT *rs_arr, int adr_contr, unsigned int adr_start, unsigned int count_bits)
{
// Êîíòðîëüíàß ñóììà
unsigned int crc;
unsigned int start_byte_number, end_byte_number, count_data_bytes;
unsigned int displacement_start, bits_in_last_byte, mask_start, mask_end;
unsigned int i = 0;
// char byte_buffer[SIZE_MODBUS_TABLE_DISCRET * 2];
rs_arr->buffer[0] = LOBYTE(adr_contr);
rs_arr->buffer[1] = CMD_RS232_MODBUS_15;
rs_arr->buffer[2] = HIBYTE(adr_start);
rs_arr->buffer[3] = LOBYTE(adr_start);
rs_arr->buffer[4] = HIBYTE(count_bits);
rs_arr->buffer[5] = LOBYTE(count_bits);
start_byte_number = adr_start / 8;
end_byte_number = (adr_start + (count_bits - 1)) / 8;
count_data_bytes = (count_bits % 8) == 0 ? count_bits / 8
: count_bits / 8 + 1;
rs_arr->buffer[6] = count_data_bytes;
displacement_start = adr_start % 8;
bits_in_last_byte = count_bits % 8;
if (bits_in_last_byte == 0) { bits_in_last_byte = 0xFF; }
mask_start = 0;
for(i = 0; (i < (8 - displacement_start)) && (i < 8); i++) {
mask_start |= (1 << (7 - i));
}
mask_end = 0;
for(i = 0; (i < bits_in_last_byte) && (i < 8); i++) {
mask_end |= (1 << i);
}
for (i = 0; i < count_data_bytes; i++)
{
if (i < count_data_bytes - 1) {
rs_arr->buffer[7 + i] = 0;
if (((i + start_byte_number) & 1) == 0)
{
rs_arr->buffer[7 + i] |=
(p_discrete_data_out[(i + start_byte_number) / 2].all >> displacement_start) & 0xFF;
}
if (((i + start_byte_number) & 1) == 1)
{
rs_arr->buffer[7 + i] |=
(((p_discrete_data_out[(i + start_byte_number) / 2].all >> 8) & mask_start) >> displacement_start);
rs_arr->buffer[7 + i] |=
(((p_discrete_data_out[(i + start_byte_number) / 2 + 1].all) & ~mask_start) << (8 - displacement_start));
}
} else {
rs_arr->buffer[7 + i] = 0;
if (((i + start_byte_number) & 1) == 0)
{
rs_arr->buffer[7 + i] |=
((p_discrete_data_out[(i + start_byte_number) / 2].all) >> displacement_start) & mask_end;
}
if (((i + start_byte_number) & 1) == 1)
{
rs_arr->buffer[7 + i] |=
(((p_discrete_data_out[(i + start_byte_number) / 2].all >> 8) & mask_start) >> displacement_start);
rs_arr->buffer[7 + i] |=
(((p_discrete_data_out[(i + start_byte_number) / 2 + 1].all) & ~mask_start) << (8 - displacement_start)) & mask_end;
}
}
}
crc = 0xffff;
crc = GetCRC16_IBM(crc, rs_arr->buffer, count_data_bytes + 7);
rs_arr->buffer[count_data_bytes + 7] = LOBYTE(crc);
rs_arr->buffer[count_data_bytes + 8] = HIBYTE(crc);
rs_arr->buffer[count_data_bytes + 9] = 0;
rs_arr->buffer[count_data_bytes + 10] = 0;
rs_arr->RS_DataWillSend = 1;
rs_arr->RS_DataWillSend2 = 1;
// RS_Send(rs_arr, rs_arr->buffer, (count_data_bytes + 10 + 2));
RS_Send(rs_arr, rs_arr->buffer, (count_data_bytes + 10));
// control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] = 1;
/* æäåì îòâåòà */
if (adr_contr > 0 && adr_contr < 0xff)
{
RS_Len[CMD_RS232_MODBUS_15] = 8;
RS_SetControllerLeading(rs_arr, true);
RS_SetAdrAnswerController(rs_arr, adr_contr);
}
return;
}
/***************************************************************/
/***************************************************************/
/***************************************************************/
/* Îòâåò íà ïåðåäà÷ó äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 15
Çàïèñü äèñêðåòíûõ äàííûõ Discrete Output Coils */
/***************************************************************/
/***************************************************************/
/***************************************************************/
void ModbusRTUreceiveAnswer15(RS_DATA_STRUCT *RS232_Arr)
{
RS_SetAdrAnswerController(RS232_Arr, 0);
RS_SetControllerLeading(RS232_Arr, false);
}
/***************************************************************/
/***************************************************************/
/* Ïîëó÷åíèå äàííûõ îò ìàñòåðà ïî ïðîòîêîëó ModBus - êîìàíäà 15
Çàïèñü äèñêðåòíûõ äàííûõ äàííûõ Discrete Output Coils */
/***************************************************************/
/***************************************************************/
void ModbusRTUreceive15(RS_DATA_STRUCT *RS232_Arr)
{
// Êîíòðîëüíày ñóììà
unsigned int crc, register_address, array_address, length, byte_count, quantity;
unsigned int d_word, mask_start, mask_end;
unsigned int i1, i2, i;
unsigned int word_number, displacement_start, displacement_end;
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèy. */
register_address = RS232_Arr->RS_Header[3] | (RS232_Arr->RS_Header[2] << 8);
array_address = register_address / 16;
/* ïîëó÷èëè quantity. */
quantity = RS232_Arr->RS_Header[5] | ( RS232_Arr->RS_Header[4] << 8);
/* ïîëó÷èëè êîëè÷åñòâî áàéò äàííûõ */
byte_count = RS232_Arr->RS_Header[6];
length = (byte_count & 0x1) ? (byte_count >> 1) + 1 : (byte_count >> 1);
word_number = register_address / 16;
displacement_end = register_address % 16;
displacement_start = 16 - displacement_end;
mask_start = 0;
for(i = 0; (i < displacement_end) && (i < 15); i++) {
mask_start |= (1 << i);
}
mask_end = 0;
for(i = 0; (i < displacement_start) && (i < 15); i++) {
mask_end |= (1 << (15 - i));
}
for (i = 0; i < length; i++)
{
// if (register_address >= ADR_MODBUS_TABLE && Address_MB < 0xe00)
if (register_address < 0xe00)
{
d_word = (RS232_Arr->buffer[7 + i * 2] << 8) | RS232_Arr->RS_Header[7 + i * 2 + 1];
p_discrete_data_out[array_address + i].all &= mask_start;
p_discrete_data_out[array_address + i].all |= (d_word >> displacement_start) | mask_start;
if(i < length - 1) {
p_discrete_data_out[array_address + i].all &= mask_end;
p_discrete_data_out[array_address + i].all |= (d_word << displacement_end) | mask_end;
}
}
}
/////////////////////////////////////////////////
// Îòñûëêà
// Ïîñ÷èòàëè êîíòðîëüíóþ ñóììó ïåðåä ñàìîé ïîñûëêîé
RS232_Arr->buffer[0] = RS232_Arr->addr_recive;
RS232_Arr->buffer[1] = CMD_RS232_MODBUS_15;
RS232_Arr->buffer[2] = HIBYTE(register_address);
RS232_Arr->buffer[3] = LOBYTE(register_address);
RS232_Arr->buffer[4] = HIBYTE(quantity);
RS232_Arr->buffer[5] = LOBYTE(quantity);
crc = 0xffff;
crc = GetCRC16_IBM(crc, RS232_Arr->buffer, 6);
RS232_Arr->buffer[6] = LOBYTE(crc);
RS232_Arr->buffer[7] = HIBYTE(crc);
RS232_Arr->buffer[8] = 0;
RS232_Arr->buffer[9] = 0;
// RS232_Arr->RS_DataWillSend = 1;
RS_Send(RS232_Arr, RS232_Arr->buffer, 10);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***************************************************************/
/***************************************************************/
/***************************************************************/
/* Ïåðåäà÷à äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 16
Ïåðåäà÷à äàííûõ */
/***************************************************************/
/***************************************************************/
/***************************************************************/
void ModbusRTUsend16(RS_DATA_STRUCT *rs_arr, int adr_contr, unsigned int adr_start, unsigned int count_word)
{
// Êîíòðîëüíàß ñóììà
unsigned int crc, Address_MB, i; //, Length_MB; //, Bytecnt_MB, Data1,Data2;
// int Data, digital, ust_I, ust_Time;
//Length_MB = count_word;
Address_MB = adr_start;
// Îòñûëêà
// Ïîñ÷èòàëè êîíòðîëüíóþ ñóììó ïåðåä ñàìîé ïîñûëêîé
rs_arr->buffer[0] = adr_contr;
rs_arr->buffer[1] = CMD_RS232_MODBUS_16;
rs_arr->buffer[2] = HIBYTE(adr_start);
rs_arr->buffer[3] = LOBYTE(adr_start);
rs_arr->buffer[4] = HIBYTE(count_word);
rs_arr->buffer[5] = LOBYTE(count_word);
rs_arr->buffer[6] = LOBYTE(count_word * 2);
for (i = 0; i < count_word; i++)
{
// rs_arr->buffer[7 + i * 2] = p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.HB;
// rs_arr->buffer[7 + i * 2 + 1] = p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.LB;
rs_arr->buffer[7 + i * 2] = p_analog_data_out[Address_MB + i].byte.HB;
rs_arr->buffer[7 + i * 2 + 1] = p_analog_data_out[Address_MB + i].byte.LB;
}
crc = 0xffff;
// crc = get_crc_ccitt(crc, rs_arr->buffer, Length_MB*2+7);
crc = GetCRC16_IBM(crc, rs_arr->buffer, (unsigned long)(count_word * 2 + 7));
rs_arr->buffer[count_word * 2 + 7] = LOBYTE(crc);
rs_arr->buffer[count_word * 2 + 8] = HIBYTE(crc);
rs_arr->buffer[count_word * 2 + 9] = 0;
rs_arr->buffer[count_word * 2 + 10] = 0;
rs_arr->RS_DataWillSend = 1;
rs_arr->RS_DataWillSend2 = 1;
RS_Send(rs_arr, rs_arr->buffer, (count_word * 2 + 10));
// control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] = 1;
// æäåì îòâåòà
if (adr_contr > 0 && adr_contr < 0xff)
{
//rs_arr->RS_Length = -1;
RS_Len[CMD_RS232_MODBUS_16] = 8;
RS_SetControllerLeading(rs_arr, true);
RS_SetAdrAnswerController(rs_arr, adr_contr);
}
}
/***************************************************************/
/***************************************************************/
/* Ïîëó÷åíèå äàííûõ îò ìàñòåðà ïî ïðîòîêîëó ModBus - êîìàíäà 16
Ïåðåäà÷à äàííûõ */
/***************************************************************/
/***************************************************************/
void ModbusRTUreceive16(RS_DATA_STRUCT *RS232_Arr)
{
// Êîíòðîëüíày ñóììà
unsigned int crc, Address_MB, Length_MB, Bytecnt_MB, i /*, Data1,Data2,Quantity*/;
int /*Data,*/ i1, i2;
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèy. */
Address_MB = RS232_Arr->RS_Header[3] | (RS232_Arr->RS_Header[2] << 8);
/* ïîëó÷èëè quantity. */
//Quantity = RS232_Arr->RS_Header[5] | ( RS232_Arr->RS_Header[4] << 8);
/* ïîëó÷èëè êîëè÷åñòâî áàéò äàííûõ */
// Length_MB = (RS232_Arr->RS_Header[4] << 8 ) | RS232_Arr->RS_Header[5];
Bytecnt_MB = RS232_Arr->RS_Header[6];
Length_MB = Bytecnt_MB >> 1;
for (i = 0; i < Length_MB; i++)
{
if (Address_MB >= ADR_MODBUS_TABLE && Address_MB < 0xe00)
{
// p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.HB = RS232_Arr->buffer[3 + i * 2];
// p_analog_data_out[Address_MB - ADR_MODBUS_TABLE + i].byte.LB = RS232_Arr->buffer[3 + i * 2 + 1];
p_analog_data_out[Address_MB + i].byte.HB = RS232_Arr->buffer[3 + i * 2];
p_analog_data_out[Address_MB + i].byte.LB = RS232_Arr->buffer[3 + i * 2 + 1];
}
if (Address_MB >= 0xe00 && Address_MB < 0xf00)
{
options_controller[Address_MB - 0xe00 + i].byte.HB = RS232_Arr->RS_Header[7 + i * 2];
options_controller[Address_MB - 0xe00 + i].byte.LB = RS232_Arr->RS_Header[7 + i * 2 + 1];
}
}
if (Address_MB >= 0xe00 && Address_MB < 0xf00)
{
i1 = options_controller[0].all;
i2 = options_controller[1].all;
store_data_flash(options_controller, sizeof(options_controller));
SetCntrlAddr(i1, i2); /* Óñòàíîâêà àäðåñà êîíòðîëëåðà */
}
/////////////////////////////////////////////////
// Îòñûëêà
// Ïîñ÷èòàëè êîíòðîëüíóþ ñóììó ïåðåä ñàìîé ïîñûëêîé
RS232_Arr->buffer[0] = RS232_Arr->addr_recive;
RS232_Arr->buffer[1] = CMD_RS232_MODBUS_16;
RS232_Arr->buffer[2] = HIBYTE(Address_MB);
RS232_Arr->buffer[3] = LOBYTE(Address_MB);
RS232_Arr->buffer[4] = 0;
RS232_Arr->buffer[5] = 2;
crc = 0xffff;
crc = GetCRC16_IBM(crc, RS232_Arr->buffer, 6);
RS232_Arr->buffer[6] = LOBYTE(crc);
RS232_Arr->buffer[7] = HIBYTE(crc);
RS232_Arr->buffer[8] = 0;
RS232_Arr->buffer[9] = 0;
// RS232_Arr->RS_DataWillSend = 1;
RS_Send(RS232_Arr, RS232_Arr->buffer, 10);
return;
}
/***************************************************************/
/***************************************************************/
/***************************************************************/
/* Îòâåò íà ïåðåäà÷ó äàííûõ ïî ïðîòîêîëó ModBus - êîìàíäà 16
Ïåðåäà÷à äàííûõ */
/***************************************************************/
/***************************************************************/
/***************************************************************/
void ModbusRTUreceiveAnswer16(RS_DATA_STRUCT *RS232_Arr)
{
// Êîíòðîëüíàß ñóììà
unsigned int Address_MB; //, crc, Length_MB, Bytecnt_MB/*, i, Data1,Data2*/;
//int Data, digital, ust_I, ust_Time;
/* ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèß. */
// Address_MB = RS232_Arr->RS_Header[3] | ( RS232_Arr->RS_Header[2] << 8);
// if (Address_MB == ADRES_LOG_REGISTERS) {
// }
err_send_log_16 = 0;
/* ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ */
//Length_MB = (RS232_Arr->RS_Header[4] << 8 ) | RS232_Arr->RS_Header[5];
//Bytecnt_MB = RS232_Arr->RS_Header[6];
RS_SetAdrAnswerController(RS232_Arr, 0);
RS_SetControllerLeading(RS232_Arr, false);
err_modbus16 = 0;
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////