0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
|
|
1 | |
MVI56-ADM. Релизация Modbus RTU20.02.2013, 14:56. Показов 5013. Ответов 7
Всем привет. Пытаюсь разобраться с программированием 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
|
20.02.2013, 14:56 | |
Ответы с готовыми решениями:
7
Нет связи между модулем ввода (modbus rtu slave) и программой modbus poll на ноутбуке Запрос MODBUS RTU Расшифровка данных Modbus RTU Modbus RTU. Oпрос прибора |
20.02.2013, 16:55 | 2 |
Не по теме: ...прежняя история с "жадным" руководством и игнорирование существования MVI56-MCM Modbus Master/Slave?
0
|
0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
|
|
20.02.2013, 21:34 [ТС] | 3 |
Нет, именно это не сравнивал, сужу по тому что команда MVIsp_Puts возвращает MVI_SUCCESS, плюс на принимающем приборе есть диод который загорается при приёме данных. Насчет правильности передачи судить не берусь.
Завтра попробую проверить правильность передачи строки.
0
|
0 / 0 / 0
Регистрация: 06.02.2013
Сообщений: 6
|
|
22.02.2013, 07:11 [ТС] | 5 |
Оказывается неправильно считалась контрольная сумма и были еще ошибки в коде, поэтому прибор не отвечал. Сейчас ошибки подправил, и так как контрольная сумма мне известно, решил не подсчитывать её, а задать напрямую. Итог - прибор начал отвечать, диод передачи моргает. Но опять таки - получить данные с порта не получается. Программа выдает ошибку таймаута.
0
|
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 | |
13.03.2013, 07:32 | |
Помогаю со студенческими работами здесь
8
Интеграция с контроллером по ModBus RTU Modbus RTU и ASCII на одном интерфейсе Modbus-RTU. Синхронизация. Формат времени Уточнить адреса регистров АС-3М MODBUS RTU Modbus rtu: как из 4 байт получить вещественное число Работа с модулем ICP DAS I-8831 по Modbus RTU Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |