Форум программистов, компьютерный форум, киберфорум
АСУ ТП, промэлектроника
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.96/25: Рейтинг темы: голосов - 25, средняя оценка - 4.96
0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
1

MVI56-ADM. Релизация Modbus RTU

20.02.2013, 14:56. Показов 5013. Ответов 7

Author24 — интернет-сервис помощи студентам
Всем привет. Пытаюсь разобраться с программированием ADM модуля MVI56-ADM компании Allen Bradley и реализовать в нем протокол Modbus RTU силами C++.
Компилятор Borland C++ 5.02, программа пришется под 16-битную dos. Прикладываю код.
Кликните здесь для просмотра всего текста

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <dos.h>
#include <stdlib.h>

#include "MVI56ADM-SerialIn.H"

int setup_module(void);
int shutdown_module(void);
int startup(void);

//---------------------- do not edit following code -----------------------
static void interrupt intctl_c(void);
static void interrupt intcrit(void);

// Ctrl-C signal handling function. When a Ctrl-C is recognized, this function
// is called. The function ignores the request and must reinstall the signal
// handler for future calls.
static void interrupt intctl_c(void)
{
return;
}

static void interrupt intcrit(void)
{
_AX = 0; // ignore critical error
}
//--------------------- ok to edit following code ---------------------------

unsigned int CRC16(BYTE *Ptr, int Count)
{
unsigned int Data;
int CRC=0xFFFF;
int j;

while(Count--)
{
Data = *Ptr;
CRC ^= Data;
for(j=0;j<8;j++)
{
if(CRC&1)
{
CRC >>= 1;
CRC ^= 0xa001;
}
else CRC >>= 1;
}
Ptr++;
}
return CRC;
};


void main(void)
{
unsigned int CRC;

int len, se; // len- buffer length variables used in code. se - connection status with ports

int returnCode, i;

BYTE request[8],receive[8];

BYTE ch, status;


#ifdef __DMC__
extern int _8087;

_8087 = 0; /* never use 80x87 Math Coprocessor */
#endif

/* enable console on COM1 */
ADM_SetConsolePort(COM1);

/* set console to 57600 baud */
ADM_SetConsoleSpeed(COM1, 57600L);

/* open ADM API and get handle */
if(ADM_Open(&adm_handle) != ADM_SUCCESS)
{
printf("\nFailed to open ADM API... exiting program\n");
exit(1);
}

/* send status message to the status/debug port */
printf("\nProgram Initialization....\n");
if(!setup_module()) // Initialize hardware and load drivers
{
shutdown_module(); // if fail on init then shutdown
return;
}

// Open serial interface API
// Set comm parameters
printf("Open Communication Port 1 9600 8 1 None....");
se = MVIsp_Open(COM2, BAUD_9600, PARITY_NONE, WORDLEN8, STOPBITS1);
if(se != MVI_SUCCESS)
{
printf("Unsuccessfully!\n");
}
else
{
printf("Successfully!\n");
}

printf("Open Communication Port 2 9600 8 1 None....");
se = MVIsp_Open(COM3, BAUD_9600, PARITY_NONE, WORDLEN8, STOPBITS1);
if(se == MVI_SUCCESS)
{
printf("Successfully!\n");
}
else
{
printf("Unsuccessfully!\n");
}

// Set comm handshaking
MVIsp_SetHandshaking(COM2, HSHAKE_NONE);
MVIsp_SetHandshaking(COM3, HSHAKE_NONE);

// Set module status LED
MVIbp_SetModuleStatus(adm_handle, MVI_MODULE_STATUS_OK);

// Set user LED1 on to indicate program running
MVIbp_SetUserLED(adm_handle, MVI_LED_USER1, MVI_LED_STATE_ON);

ch = 0;
status = 0;
se = 0;
len = 8;

memset(&receive, 0, 8);

// Main loop for program ---------------------------------------------------
for(;
{
// Port 1 handler logic -------------------------------------------------
len = 8;

printf("Forming request...\n");
request[0] = 0x03; //Device address
request[1] = 0x03; //Function code
request[2] = 0x00; //Hi register address
request[3] = 0x11; //Low register address
request[4] = 0x00; //Hi length
request[5] = 0x08; //Low length

CRC = CRC16((BYTE *)request,6);

request[6] = (CRC % 256);

request[7] = (CRC / 256);

printf("Sending message from device......\n");
if(MVIsp_Puts(COM2,&request,0,&len,TIMEOUT_ASAP) == MVI_SUCCESS)
{
printf("Send successfull!\n");
}
else
{
printf("Error send char!\n");
};

sleep(2);

printf("Getting char from COM-port....\n");
if( (se = MVIsp_Getch(COM2,&receive[0],TIMEOUT_FOREVER)) == MVI_SUCCESS)
{
printf("Getting successfull!\n");
}
else
{
switch (se){
case MVI_ERR_NOACCESS:
printf("MVI_ERR_NOACCESS\n");
break;
case MVI_ERR_BADPARAM:
printf("MVI_ERR_BADPARAM\n");
break;
};
};


// increment loop counter for external health indication ----------------
*(wrbuff) = *(wrbuff) + 1;

// Set BP LED on
ADM_SetLed(adm_handle, interface_ptr, ADM_LED_USER2, ADM_LED_ON);
// write image to backplane ---------------------------------------------
if((returnCode=MVIcip_WriteConnected(interface_ptr->handle, ConnHandle, (BYTE*)wrbuff, 0, 64)) != MVI_SUCCESS)
{
printf("Error write to BP: %d\n", returnCode);
}
// Set BP LED off
ADM_SetLed(adm_handle, interface_ptr, ADM_LED_USER2, ADM_LED_OFF);

// Key Board Input ------------------------------------------------------
if(kbhit())
{
if(getch() == 27)
{
shutdown_module(); // if fail on init then shutdown
exit(1);
}
else
{
printf("Press Esc to Exit.\n\n");
}
}
} // End Main loop
};


///////////////////////////////////////////////////////////////////////////////
//
// This function is used to setup the module's hardware and load device
// drivers required by the application. Most of the items to look at closely
// are going to be related to the serial port configuration value at the top of
// of the function.
//
// Input : None.
// Output: The function returns a value of 1 if successful and 0 if not.
//
///////////////////////////////////////////////////////////////////////////////

int setup_module(void)
{

/******************************************************************
This section is required for the ADM API to function.
The names of the structures may be changed to suit the
developer's needs. The interface structure must be initialized
before it can be used.
*******************************************************************
*/

/* initialize structure pointers */
interface_ptr = &interface;
interface.adm_bt_data_ptr = &bt_data;
interface.adm_bt_err_ptr = &bt_err;

memset(interface.adm_bt_data_ptr, 0, sizeof(ADM_BT_DATA));
memset(interface.adm_bt_err_ptr, 0, sizeof(ADM_BLK_ERRORS));

if(ADM_BtOpen(adm_handle, interface_ptr, 1) != MVI_SUCCESS)
{
printf("Unsuccessfully!\n");
return 0;
}
else
{
printf("Successfully!\n");
}
MVIcip_GetVersionInfo(interface_ptr->handle, &verinfo);
MVIsp_GetVersionInfo(&spverinfo);
ADM_GetVersionInfo(adm_handle, &adm_version);

//----------- do not edit next 6 lines of code---------------------------
disable();
setvect(0x24, intcrit); // install in ISR handler for CTRL-C
setvect(0x23, intctl_c); // install in ISR handler for CTRL-C
setvect(0x1B, intctl_c); // install in ISR handler for CTRL-Break
setcbrk(0); // force DOS to ignore Ctrl-C
enable();
//-----------------------------------------------------------------------


printf("\nVERSION INFORMATION:\n\n\
%s\n\
(c) 1999-2006, ProSoft Technology, Inc.\n\n\
PRODUCT NAME CODE : %s\n\
SOFTWARE REVISION LEVEL : %s\n\
RUN NUMBER : %s\n\n\
BACKPLANE DRIVER VERSION : %d.%d\n\
BACKPLANE API VERSION : %d.%d\n\
SERIAL API VERSION : %d.%d\n\
ADM API VERSION : %d.%d\n\n",
"MVI56ADM",
"ADM Serial Input Sample",
"2.01",
"10/03/2006",
verinfo.BPDDSeries, verinfo.BPDDRevision,
verinfo.APISeries, verinfo.APIRevision,
spverinfo.APISeries, spverinfo.APIRevision,
adm_version.APIRevisionMajor, adm_version.APIRevisionMinor);

printf("Press Esc to Exit.\n\n");

return 1;
};

int shutdown_module(void)
{
MVIbp_SetUserLED(adm_handle, MVI_LED_USER1, MVI_LED_STATE_OFF);
MVIbp_SetUserLED(adm_handle, MVI_LED_USER2, MVI_LED_STATE_OFF);
MVIbp_SetModuleStatus(adm_handle, MVI_MODULE_STATUS_FAULTED);

/* close the backplane driver */
printf("Closing Backplane Driver....\n");
ADM_BtClose(adm_handle, interface_ptr);
/* close the com driver */
printf("Closing Serial Port Driver....\n");
MVIsp_Close(1);
MVIsp_Close(2);

return 1;
}



Заранее скажу что код из примеров с сайта Prosoft, немного подправленный. Отправка запроса проходит нормально, а в ответ прибор ничего не отправляет. Может кто-нибудь подскажет почему, а то я уже всю голову сломал.

Добавлено через 22 минуты
Либо виснет на этом моменте
...
if( (se = MVIsp_Getch(COM2,&receive[0],TIMEOUT_FOREVER)) == MVI_SUCCESS)
Либо выдает ошибку таймаута, если задать последний параметр в миллисекундах.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.02.2013, 14:56
Ответы с готовыми решениями:

Нет связи между модулем ввода (modbus rtu slave) и программой modbus poll на ноутбуке
Добрый день форумчанам. Сконфигурирован модуль modbus rtu slave в Ovation system. Опыт работы с...

Запрос MODBUS RTU
Добрый день! Никак не получается получить ответ от МВА8. По протоколу ascii проблем не...

Расшифровка данных Modbus RTU
Добрый день. Подскажите как расшифровать данные от прибора ? Снимаю снифером обмен данными через...

Modbus RTU. Oпрос прибора
подскажите пожалуйста, что-то явно делаю не так, прибор опрашиваю по modbus rtu , но в ответ в...

7
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
20.02.2013, 16:55 2

Не по теме:

...прежняя история с "жадным" руководством и игнорирование существования MVI56-MCM Modbus Master/Slave?



Отправка запроса проходит нормально...
...на основании чего вывод? Вы сравнили пакеты на осцилле от вашей утилиты с пакетами от того же модбас-монитора MBRTU? Можете ли вы навесить в сети RS-485 конвертор RS-485/RS-232/USB с целью помониторить пакеты на ПК/ноуте?
0
0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
20.02.2013, 21:34  [ТС] 3
Нет, именно это не сравнивал, сужу по тому что команда MVIsp_Puts возвращает MVI_SUCCESS, плюс на принимающем приборе есть диод который загорается при приёме данных. Насчет правильности передачи судить не берусь.
Завтра попробую проверить правильность передачи строки.
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
20.02.2013, 22:34 4
попробую проверить правильность передачи строки.
...проверяйте.

плюс на принимающем приборе есть диод который загорается при приёме данных
прием данных с 485-го драйвера совсем не одно и то же с корректным пакетом. Светодиодик повесить не проблема на RX/TX.
1
0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
22.02.2013, 07:11  [ТС] 5
Оказывается неправильно считалась контрольная сумма и были еще ошибки в коде, поэтому прибор не отвечал. Сейчас ошибки подправил, и так как контрольная сумма мне известно, решил не подсчитывать её, а задать напрямую. Итог - прибор начал отвечать, диод передачи моргает. Но опять таки - получить данные с порта не получается. Программа выдает ошибку таймаута.
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
22.02.2013, 13:08 6
...вот, а монитором-сниффером это бы сразу обнаружилось. И не вижу в вашем коде прерывания для приема.

RS-485. Работа с Modbus протоколом...
1
0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
11.03.2013, 08:18  [ТС] 7
Какое именно прерывание для приёма необходимо? Не могу к сожалению разобраться пока в этом.
0
0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
13.03.2013, 07:32  [ТС] 8
Вообще, я был бы очень рад, если бы кто-нибудь привел пример программы под любой из ADM модулей.
0
13.03.2013, 07:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.03.2013, 07:32
Помогаю со студенческими работами здесь

Интеграция с контроллером по ModBus RTU
Здравствуйте. В щите используется контроллер, который опрашивает модули, датчики и т.п. по modbus...

Modbus RTU и ASCII на одном интерфейсе
Возникла ситуация следующего рода. На один интерфейс посажены несколько приборов (одних и тех же)....

Modbus-RTU. Синхронизация. Формат времени
Здравствуйте! Помогите разобраться с форматом времени. Прибор- БМРЗ-100. В описании протокола...

Уточнить адреса регистров АС-3М MODBUS RTU
Доброго времени суток уважаемые форумчане. С авто синхронизатора (АС-3М) нужно получить данные,...

Modbus rtu: как из 4 байт получить вещественное число
Здравствуйте. у меня вопрос опять-таки про modbus rtu. посылаю запрос: 48 4 0 22 0 ...

Работа с модулем ICP DAS I-8831 по Modbus RTU
Доброго времени суток, господа. Прошу Вас подкинуть и указать путь к заголовочным файлам на &quot;C&quot;,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru