реклама на сайте
подробности

 
 
> FreeModbus
andrewlekar
сообщение Feb 3 2011, 09:13
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Кто-нибудь использовал такую штуку? Пробую скомпилировать - какая-то лабуда в заголовках. Ругается, что то одного определения не видит, то другого. Что происходит то? Как побороть?
Go to the top of the page
 
+Quote Post
5 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 64)
MrYuran
сообщение Feb 3 2011, 09:18
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(andrewlekar @ Feb 3 2011, 12:13) *
Что происходит то? Как побороть?

Как обычно.
Включить все модули в проект или в пути поиска, если свой мэйкфайл.

У меня так сделано:
Код
...
MODULES +=  modbus
MODULES +=  modbus/RTU
MODULES +=  modbus/Port
MODULES +=  modbus/Functions
MODULES +=  modbus/system

...

SRCDIRS = $(PROJECT_ROOT)/
SRCDIRS += $(addprefix $(PROJECT_ROOT)/,$(MODULES))

#INCLUDES  = -I$(PROJECT_ROOT)/
INCLUDES  = $(addprefix -I$(PROJECT_ROOT)/,$(MODULES))

CSRC    = $(wildcard $(addsuffix /*.c,$(SRCDIRS)))
CPPSRC  = $(wildcard $(addsuffix /*.cpp,$(SRCDIRS)))
ASRC    = $(wildcard $(addsuffix /*.s,$(SRCDIRS)))


Ну и не забыть подключить:
Код
/* ----------------------- Modbus includes ----------------------------------*/
#include "../modbus/include/mb.h"
#include "../modbus/include/mbport.h"
#include "../modbus/port/port.h"


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Feb 3 2011, 09:59
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Попробую, хотя вроде все так же делаю. Я версию модбаса использовал 1.3 - может с 1.5 лучше покатит. И ещё, сами модули собрались, а вот в программе пытаюсь использовать их тайпдефы и вызовы из mb.h - ругается на то, что они не объявлены. Ничего не пойму - сколько на си пишу, такого безобразия не встречал.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 3 2011, 10:16
Сообщение #4


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(andrewlekar @ Feb 3 2011, 12:59) *
Ничего не пойму - сколько на си пишу, такого безобразия не встречал.

Нет там никакого безобразия, библиотека сделана очень чётко и грамотно.
Подключается буквально в три шага, в документации расписано.
Возьмите для начала готовый пример.

Чтобы не гадать, выкладывайте, что именно не получается и какие ошибки.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Feb 3 2011, 10:40
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Ну вот, стало сильно лучше. Помогло волшебное добавление именно в таком порядке
Код
/* ----------------------- Modbus includes ----------------------------------*/
#include "../modbus/include/mb.h"
#include "../modbus/include/mbport.h"
#include "../modbus/port/port.h"


Причем добавление во все без исключения модули модбаса - иначе нет-нет да поругивалось.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 3 2011, 11:25
Сообщение #6


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(andrewlekar @ Feb 3 2011, 13:40) *
Причем добавление во все без исключения модули модбаса

Это идеологически неправильно...
Надо просто пути поиска к этим папкам прописать.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Feb 3 2011, 11:52
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Пути поиска просто скажут где находится тот или иной заголовочный файл, но добавлять всё равно нужно при помощи #include. Проблема не в путях, а в том, что каждый модуль модбаса хочет именно эту последовательность инклудов. Для меня это оказалось несколько странным. Хотя я не отрицаю, что тут я что-то не понимаю, но до этого успешно добавлял в проект и ucOS, и lwIp, и PolarSSL - такой странной реакции не наблюдал.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 3 2011, 12:14
Сообщение #8


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(andrewlekar @ Feb 3 2011, 14:52) *
Проблема не в путях, а в том, что каждый модуль модбаса хочет именно эту последовательность инклудов. Для меня это оказалось несколько странным.

Действительно странно...
Хотя, может я тоже добавлял, просто не помню. Давно это было, а отлаженная библиотека кочует из проекта в проект без изменений.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Feb 4 2011, 08:51
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



А ещё подскажите, где код для мастера искать? В упор не вижу мастера во этой библиотечке.
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Feb 24 2011, 07:44
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Цитата(andrewlekar @ Feb 3 2011, 12:59) *
версию модбаса использовал 1.3 - может с 1.5 лучше покатит.

Собирал недавно проект ModbusTCP на Freemodbus 1.5 - с заголовками такой фигни не было, зато обнаружился другой небольшой глючок: не для всех функций корректно вычислялась длина возвращаемого пакета. Для большинства modbus-мастеров это не принципиально (там длина в пакете двух местах присутствует), но товарищ делал мастера на питоне под линуксом и у него мастер, собранный из готовой библиотеки, ругался на некорректность данных.
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 2 2011, 21:45
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



При сборке проекта были ошибки линкера, пока не подключил #include "mbfunc.h" в некоторых модулях.
Проект скомпилировал в IAR v.5.50.0.
Безуспешно пытаюсь запустить freemodbus-v1.5. Пробую на разных контроллерах (сейчас на Меге324P 20MHz).
Код
int
main( void )
{
    eMBErrorCode    eStatus;

    eStatus = eMBInit( MB_RTU, 0x01, 0, 9600UL, MB_PAR_NONE );

    __enable_interrupt();

    /* Enable the Modbus Protocol Stack. */
    eStatus = eMBEnable(  );

    for(;; )
    {
        ( void )eMBPoll(  );

        /* Here we simply count the number of poll cycles. */
        usRegInputBuf[0]++;
    }
На запрос чтения одного регистра по адресу 1000 отвечает ошибкой. В чем может быть проблема?

Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 2 2011, 22:15
Сообщение #12


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Цитата(alux @ Mar 3 2011, 00:45) *
На запрос чтения одного регистра по адресу 1000 отвечает ошибкой. В чем может быть проблема?

В возвращаемом пакете что передаёт? Там ведь пусть небогатая , но есть информация об ошибке.
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 06:31
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Код
01 83 02 C0

Это ответ на запрос чтения (код 0x03) с устройства №1 одного регистра по адресу 1000.
Почему, никак не могу понять? Проект компилируется, правда в IARе, без ошибок.
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 3 2011, 07:28
Сообщение #14


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Цитата(alux @ Mar 3 2011, 09:31) *
Код
01 83 02 C0

То есть возвращает код ошибки - 2. А это означает (см. рисунок), что вы пытаетесь прочитать несуществующий регистр. Обработчик у вас этот адрес обрабатывает?
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 07:44
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Это из примера freemodbus
Код
#define REG_INPUT_START 1000
#define REG_INPUT_NREGS 4

static USHORT   usRegInputStart = REG_INPUT_START;
static USHORT   usRegInputBuf[REG_INPUT_NREGS];

Со стороны мастера (ПК) периодически даю запрос на чтение:
Код
wError = mb.ReadOutputRegisters(1, 1000, 1, wTempData);
//адр. устройства, адрес считывания, кол-во считываемых регистров, буфер

Так где я не прав?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 3 2011, 08:28
Сообщение #16


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 3 2011, 10:44) *
Так где я не прав?

Покажите ещё СВ-функцию чтения регистров
Далее, ReadOutputRegisters - это какая функция? (код функции)
Вообще-то, при чтении Input регистров как бы нужна функция ReadInput, но точно можно определить по коду.
Ну или пакет запроса приведите.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 3 2011, 08:28
Сообщение #17


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



В разных реализациях по разному отсчитываются адреса. Holding начинаются с 40000 по терминологии modbus, а в вызове функции может быть отсчёт и от 0, и от 1. Попробуйте вот этой утилитой потестить:
http://www.chipkin.com/cas-modbus-scanner
В ней, например, для чтения holding register 9 нужно задать такие настройки (см аттач).
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 08:47
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Со стороны мастера (ПК)
Код
//Modbus Functions
const BYTE CModbus::READ_OUTPUT_REGISTERS      = 3;


из примера freemodbus:
Код
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;

    if( ( usAddress >= REG_INPUT_START )
        && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInputStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}


пакет запроса:
Код
01 03 03 E8 00 01 04 7A

ответ:
Код
01 83 04 40
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 3 2011, 09:14
Сообщение #19


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Сдаётся мне, вы холдинги хотите прочитать вместо инпутов.
Проверьте тогда ещё константы
REG_HOLDING_START и REG_HOLDING_NREGS

Для чтения Input регистров функция 04


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 09:59
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



со стороны мастера изменил запрос на
Код
01 04 03 E8 00 01 B1 BA


ответ уже без ошибки:
Код
01 04 02 00 00 B9 30


но это не то, что я ожидаю получить. Я должен получить инкрементированное значение usRegInputBuf[0]++;
Что еще не так?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 3 2011, 10:10
Сообщение #21


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 3 2011, 12:59) *
но это не то, что я ожидаю получить. Я должен получить инкрементированное значение usRegInputBuf[0]++;
Что еще не так?

А вот тут уже возможно играет смещение на 1.
Попробуйте ещё соседний регистр поменять.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 3 2011, 10:17
Сообщение #22


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Если я ничего не путаю, в ответе должно быть два байта ячейки usRegInputBuf[0]. Если вы её никак не инициализируете, то будет возвращаться неопределённое значение. Скорее всего именно нули.
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 3 2011, 10:27
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(Dimoza @ Mar 3 2011, 14:17) *
в ответе должно быть два байта ячейки usRegInputBuf[0]. Если вы её никак не инициализируете, то будет возвращаться неопределённое значение. Скорее всего именно нули.

Глобальная переменная инициализируется нулем. Дальше в цикле она инкрементируется:
Код
usRegInputBuf[0]++;

Т.е. я должен увидеть на приеме 0,1,2,3...

Цитата(MrYuran @ Mar 3 2011, 14:10) *
А вот тут уже возможно играет смещение на 1.
Попробуйте ещё соседний регистр поменять.

а вот так:
Код
usRegInputBuf[1]++;

уже отвечает то, что нужно!

А где необходимо добавить это смещение на 1 ?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 4 2011, 09:05
Сообщение #24


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 3 2011, 13:27) *
А где необходимо добавить это смещение на 1 ?

Ну, чтобы не лезть в глубины, можно в CB-функции подправить вычисление iRegIndex
Хотя, идеологически более правильно залезть внутрь и разобраться, почему так.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 4 2011, 22:35
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Вот ответ автора freemodbus на проблему смещения адреса:
Код
MODBUS protocol address (Base0) is Address 1 in the FreeMODBUS stack. The term PLC address is no longer correct.
The MODBUS PDU addresses registers at 0. The MODBUS application protocol start address at 1.
For MODBUS POLL testing simply add 1 to the register you set when you use Base 0 and you should get the address which FreeMODBUS uses.


т.е. нужно добавить 1 в определении
#define REG_HOLDING_START 1001

PS. А вопрос был такой:
Код
I’m using Modbus Poll to debug he FreeModbus programs. If REG_HOLDING_START is set to be 1000, the valid address of Modbus Poll looks like this:
PLC Addresses (Base1) = 31000
Protocol Addresses (Base0) = 00999
But if REG_HOLDING_START is set to be 0, the first address of Protocol Addresses cannot be found because the address cannot be -1.
Do you recommend not to use REG_HOLDING_START = 0 in this case?
Go to the top of the page
 
+Quote Post
Dimoza
сообщение Mar 4 2011, 23:00
Сообщение #26


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Насколько я уяснил это для себя, "по-простому", в modbus нумерация регистров и койлов начинается с 1. Так для пользователя оборудования будет проще: сложно обычному человеку понять, что такое нулевой датчик. А вот 1, 2, 3 и так далее - уже проще. НО! В передаваемом пакете modbus этому самому 1-му датчику будет соответствовать адрес 0.
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 5 2011, 10:26
Сообщение #27


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Как правильно передать код ошибки MB_EX_SLAVE_BUSY = 0х06 , в случае, если SLAVE занят вычислениями, т.е. результат еще не готов?
Функцию опроса ModBus я поместил в другую функцию, которую периодически вызываю по таймеру:
Код
void MBPoll()
{
  (void)eMBPoll();
}

Я вижу выход такой:
в функции eMBErrorCode eMBRegHoldingCB(...) по глобальному флагу Busy,
Код
if(Busy) eStatus = MB_ETIMEDOUT;
else
...
, возвращаемое значение из этой функции преобразуется в исключение MB_EX_SLAVE_BUSY;
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 5 2011, 11:29
Сообщение #28


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 5 2011, 13:26) *
Я вижу выход такой:

Ну да, как-то так.
Я, кстати, смещение на 1 тоже задал в дефайне, не долго думая sm.gif
(заглянул по случаю, освежил память)


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 7 2011, 11:47
Сообщение #29


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Еще для полного счастья нужно использовать функции для записи\чтения битов ForceSingleCoil (0x05), ReadSingleCoil(0x01).
Приведите, пожалуйста, пример с использованием этих функций. Флаги, битовое поле в области ввода-вывода ниже 0x1f.
Код
// Flags
typedef union
{
    unsigned char Complete;   // Access all 8 bits
    
    struct
    {
        bool IsTestCompleted   : 1;    
        bool IsDataReady      : 1;      
        bool IsRelayOn          : 1;  
        bool IsReset          : 1;  
        bool IsOverheat          : 1;  
        bool IsKeyPressed      : 1;
        bool IsOpenoff              : 1;  
        bool IsShortcut          : 1;  
    };
} FLAGS;
__no_init volatile FLAGS Flags@0x28; // Флаги, битовое поле в области ввода-вывода ниже 0x1f (ACSR Register)
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 7 2011, 16:14
Сообщение #30


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(alux @ Mar 7 2011, 14:47) *
Еще для полного счастья нужно использовать функции для записи\чтения битов ForceSingleCoil (0x05), ReadSingleCoil(0x01).

Не пробовал, т.к. особого смысла не вижу.
Не проще ли все флаги оптом передать в регистре статуса, например?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 7 2011, 16:50
Сообщение #31


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(alux @ Mar 7 2011, 14:47) *
Еще для полного счастья нужно использовать функции для записи\чтения битов ForceSingleCoil (0x05), ReadSingleCoil(0x01).
Приведите, пожалуйста, пример с использованием этих функций. Флаги, битовое поле в области ввода-вывода ниже 0x1f.

А какой гешефт их так описывать?
При адресации можно использовать offsetof()/8, биты задавать перечислениями. Получится
Код
extern
#ifdef CORE_32
#define CORE_WD 32
char
#else
#define CORE_WD 8
int
#endif
mb_coils[];
enum coils {foo,bar};
static inline bool coil_r(enum coils coil);
static inline void coil_w(enum coils coil , bool val);
bool coil_r(enum coils coil)
{
  return (mb_coils[coil / CORE_WD] & (1 << coil & (CORE_WD-1)))?true:false;
}
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 20 2011, 21:37
Сообщение #32


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



При использовании функции 0x10 PresetMultipleRegisters запрос от мастера идет как положено (проверяю в Serial Port Monitor), а ответа от слева не поступает. Функция 0x06 PresetSingleRegister работает как положено. В mbconfig.h функция 0x10 разрешена :
Код
#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED  (  1 )

В чем может быть проблема?
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Mar 21 2011, 05:29
Сообщение #33


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Callback написали для этой функции?
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 21 2011, 07:09
Сообщение #34


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



как выяснилось, проблема не в этой функции (0x10), а в адресе регистров, в которые нужно писать. У меня регистры (переменные типа int) упакованы в структуру :
Код
typedef struct
{
    int NumSensorsDS;            
    int TemperatureTC[NUM_SENSORS];
    int Parameter[2][NUM_SENSORS];
    int Temperature[2];      
    int NumSensorsTC;    
    int Cable;          
    int Average;              
    int Data;              
    long Accum;    
}TValue;

В регистры Cable, Average записываются значения и отдается нормальный ответ от устройства при помощи ф-ций PresetSingleRegister,PresetMultipleRegisters, а если указать адрес записываемого регистра в NumSensorsTC, то запрос остается без ответа. Почему, не пойму никак?..

PS. Callback-функции написаны и работают.

PS2. Вроде нашел... В Callback-функции использую ф-ции записи во флеш.
Код
                            WriteFlashByte(FLASH_PARAMETER_LOCATION + 2 + 1, *(pucRegBuffer));
                            WriteFlashByte(FLASH_PARAMETER_LOCATION + 2, *(pucRegBuffer + 1));

Если закоментировать эти строки, то ответ нормальный появляется. Наверно, правильно сделать так : в колбэк-функции устанавливать флаг, а в главном цикле по этому флагу писать во флеш.
Go to the top of the page
 
+Quote Post
ISK2010
сообщение Apr 19 2011, 04:45
Сообщение #35


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



Доброго времени суток!

Занимаюсь изучением МК STM32F105. У меня есть два устройства с RS485 полудуплексом. Хочу их связать, чтобы управлять первым и получать от него измерения с АЦП. Почитал и понял, что нужно применить ModBus как широко распространенный протокол. Велосипед изобретать не хочу, поэтому гляжу в сторону freeModBus. Скачал версию 1.5, но...без поллитра сока не разобраться. А сока нет...

Правильно ли я понял, что нужно свои функции приема-посылки написать?

Не могу понять, вот допустим я в фоне второго устройства хочу получить температуру с первого устройства, что делать? Какую функцию использовать?

Пожалуйста помогите разобраться. Может у кого-нибудь есть простенький пример приклеивания FreeModBus к STM32F10X?

Go to the top of the page
 
+Quote Post
MrYuran
сообщение Apr 19 2011, 13:52
Сообщение #36


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ISK2010 @ Apr 19 2011, 08:45) *
Не могу понять, вот допустим я в фоне второго устройства хочу получить температуру с первого устройства, что делать? Какую функцию использовать?
Пожалуйста помогите разобраться. Может у кого-нибудь есть простенький пример приклеивания FreeModBus к STM32F10X?

Это нужно писать мастер. (FreeModbus - это Slave)
То есть, необходимы функции, которые будут отправлять мастер-пакеты и ожидать ответа.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ISK2010
сообщение May 13 2011, 13:11
Сообщение #37


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



А как slave должен реагировать на прием пустого ADU? Т.е. который адресован ему и имеет правильный CRC, но не имеет ни функции, ни данных.
Go to the top of the page
 
+Quote Post
yashok
сообщение May 14 2011, 09:03
Сообщение #38


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203



Цитата
который адресован ему и имеет правильный CRC, но не имеет ни функции, ни данных


Если вместо функции и данных просто нули, то при проверки кода функции, если он данную ф-цию не поодерживает, должен вернуть ошибку с номером 1 (ILLEGAL FUNCTION).
Go to the top of the page
 
+Quote Post
ISK2010
сообщение May 17 2011, 04:40
Сообщение #39


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



А CRC всех принятых пакетов рассчитывается? Или только тех, которые адресованы нам?

В FreeModbus, я посмотрел, для всех принятых фреймов проверяется минимальная длина и CRC. Но не могу понять зачем. Ведь можно сначала проверять адрес, и тратить время на расчет CRC только "своих" фреймов.

Сообщение отредактировал ISK2010 - May 17 2011, 05:07
Go to the top of the page
 
+Quote Post
yashok
сообщение May 17 2011, 05:04
Сообщение #40


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203



По хорошему проверка должна идти в следующей очередности:
1. Длина пакета
2. CRC
3. Адрес
4. Функция
5. Данные
Go to the top of the page
 
+Quote Post
ISK2010
сообщение May 17 2011, 05:10
Сообщение #41


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



Цитата(yashok @ May 17 2011, 09:04) *
По хорошему проверка должна идти в следующей очередности:
1. Длина пакета
2. CRC
3. Адрес
4. Функция
5. Данные


Но почему? Только для того, чтобы вести статистику всех принятых фреймов с ошибкой CRC.


Go to the top of the page
 
+Quote Post
yashok
сообщение May 17 2011, 05:17
Сообщение #42


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203



Для простых случаев может и можно не проверять. А если сеть протяженная, с большим количеством слейвов, помеховая обстановка серьезная - вероятность ошибок в пакете приличная, проверка crc становится обязательной.
Go to the top of the page
 
+Quote Post
ISK2010
сообщение May 17 2011, 05:29
Сообщение #43


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



Бесспорно проверка CRC обязательна. Но только для тех фреймов, которые нам адресованы. А если уже для этих фреймов не сошелся crc, то игнорируем их и инкрементируем счетчик ошибок crc.
Go to the top of the page
 
+Quote Post
yashok
сообщение May 17 2011, 06:01
Сообщение #44


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203



Да согласен

Хотя у некторых есть счетчики которые считают ошибки в линии т.к. если есть ошибка, то не известно где именно и кому предназначен пакет.

Сообщение отредактировал yashok - May 17 2011, 05:39
Go to the top of the page
 
+Quote Post
leshij
сообщение Oct 17 2012, 07:26
Сообщение #45





Группа: Новичок
Сообщений: 3
Регистрация: 28-09-12
Из: Новосибирск
Пользователь №: 73 716



Доброго дня всем.
Пытаюсь поднять FreeRTOS(7.2)+lwip(1.4)+FreeModbus(1.5)(TCP), FreeRTOS+lwip на LM3S9B95(board EVB-9B95) худо-бедно справился, пинги идут, httpserver_raw запустился, пробную страничку получил.
А вот с modbus справится не могу. Для теста взял qModMaster, т.к. работать легко с ней(основные шаги connect->read data->disconnect я выполняю по кнопками, что упрощает тест), и параллельно для надежности нечто более сложное NI OPC Server.
Connect, Disconnect работают отлично, вызываются prvxMBTCPPortAccept() и prvxMBTCPPortReceive()(здесь он уходит в prvvMBPortReleaseClient и закрывает соединение).
А вот с чтением данных у меня возникли проблемы, при чтении попадаю я в prvxMBTCPPortReceive(), далее по функции доходит до (void)xMBPortEventPost(EV_FRAME_RECEIVED); и из нее не возвращается, ползу по ней дебагером
Код
//portevent.c
BOOL xMBPortEventPost( eMBEventType eEvent )
{
    eMailBoxEvent = eEvent;
    sys_mbox_post( xMailBox, &eMailBoxEvent );
    return TRUE;
}

он уходит в sys_mbox_post();
Код
//sys_arch.c
void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
    while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE );
}

и на сколько я понимаю крутится внутри xQueueGenericSend().
После чего отваливается ethernet, т.е. пинги не проходят вообще, да и походу роутер не видит плату, FreeRTOS в это время работает Task'и переключает исправно.
Я уже даже не знаю в какую сторону копать.
Порт modbus взят из демки MCF5235TCP, а LWIP где-то на просторах интернета

[attachment=72049:ports_lwip.zip]
[attachment=72050:port_modbus.zip]
Go to the top of the page
 
+Quote Post
leshij
сообщение Oct 18 2012, 06:25
Сообщение #46





Группа: Новичок
Сообщений: 3
Регистрация: 28-09-12
Из: Новосибирск
Пользователь №: 73 716



в sys_mbox_post() убрал цикл, заменил portMAX_DELAY на 1000(т.е. на 1 секунду). Ethernet перестал отваливаться, обнаружил, что функция xQueueSendToBack возвращает ошибку errQUEUE_FULL.
Go to the top of the page
 
+Quote Post
leshij
сообщение Oct 22 2012, 04:37
Сообщение #47





Группа: Новичок
Сообщений: 3
Регистрация: 28-09-12
Из: Новосибирск
Пользователь №: 73 716



обнаружил, что структура pxQueue не подгружалась при работе с модбасом
у меня еще не пришло полное понимание & и *, поэтому решил поиграться с ними в порте freemodbus (portevent.c)
Код
sys_mbox_post( xMailBox, &eMailBoxEvent );

заменил на
Код
sys_mbox_post( &xMailBox, &eMailBoxEvent );

структура подгрузилась и функция xQueueSendToBack перестала выдавать ошибку errQUEUE_FULL, но что-то я сильно сомневаюсь, что в порте была ошибка

Больше не сомневаюсь, это реально ошибка в порте, изменил на &xMailBox во всех функциях portevent.c и freemodbus заработал. Большое спасибо разработчикам freemodbus, так и без работы можно оставить, яж на испытательном сроке ещеsm.gif но все равно им спасибо за трудsm.gif

Сообщение отредактировал leshij - Oct 22 2012, 04:40
Go to the top of the page
 
+Quote Post
veskon
сообщение Sep 30 2013, 11:02
Сообщение #48





Группа: Новичок
Сообщений: 4
Регистрация: 30-09-13
Пользователь №: 78 547



Помогите реализовать Modbus-slave на базе Atmega32A. Условие: применяемый на freemodbus 16-разрядный таймер1 использовать нельзя - он нужен мне для реализации 16-разрядного аппаратного ШИМа.

Что уже сделано:
1) Материалы на freemodbus.org изучил (хотя и не во всем разобрался).
2) Нашел http://forum.easyelectronics.ru/viewtopic....mp;hilit=modbus - во втором посте выложено решение для 168й атмеги по замене таймера 1 на таймер 0. Скачал, собрал в свой проект, откомпилировал для 168й атмеги.
2) Заменил ссылки на таймер 0А (для 168й меги) на таймер 0 для 32й меги.
3) 2) Заменил ссылки на таймер 0В (для 168й меги) на таймер 2 для 32й меги.
4) Откомпилировал в AtmelStudio6 без ошибок.
5) Подключил контроллер через мах485 и конвертер i-7561 (485/usb) к компьютеру.
6) ОРС-сервером Lectus отправляю запрос 01 03 00 01 00 01 D5 CA, осциллографом наблюдаю соответствующую последовательность на ножке микроконтроллера, НО сам контроллер молчит и в ответ никаких сообщений не выдает.

Предполагаю два варианта проблемы:
1) Простая замена таймеров оказалась некорректной.
2) Неверно "привязаны" регистры usRegInputBuf и usRegHoldingBuf.

Помогите пожалуйста разобраться
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 30 2013, 11:31
Сообщение #49


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(veskon @ Sep 30 2013, 14:02) *
Помогите пожалуйста разобраться

Для начала, RTFM - Related Pages -> Porting for RTU/ASCII

Ну а дальше тщательная трассировка.
Самое простое, это банальный бит четности (проверка на четность по стандарту Modbus RTU/ASCII).
Если прерывания ловятся и пакет принимается, должен выставляться эвент и функция поллинга перенаправляет в нужный коллбэк.
Дальше убеждаемся, что формируется ответный пакет, и вот тут может всплыть 485-й с переключением потока.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Lagman
сообщение Sep 30 2013, 12:06
Сообщение #50


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(veskon @ Sep 30 2013, 15:02) *
Помогите пожалуйста разобраться

А может слейв адрес не тот?
Go to the top of the page
 
+Quote Post
veskon
сообщение Sep 30 2013, 12:12
Сообщение #51





Группа: Новичок
Сообщений: 4
Регистрация: 30-09-13
Пользователь №: 78 547



Цитата(Lagman @ Sep 30 2013, 15:06) *
А может слейв адрес не тот?


Спасибо. С принципом работы самого модбаса рту мне все ясно. Проблема возникла с его конкретной реализацией. В частности с заменой таймера в стандарном "австрийском" варианте.

Адрес тот, регистры те...
Go to the top of the page
 
+Quote Post
Lagman
сообщение Sep 30 2013, 13:05
Сообщение #52


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(veskon @ Sep 30 2013, 16:12) *
Спасибо. С принципом работы самого модбаса рту мне все ясно. Проблема возникла с его конкретной реализацией. В частности с заменой таймера в стандарном "австрийском" варианте.

Я с AVR не работал, но думаю если вы выложите свои исходники из /port то знающие люди помогут. А последовательность действий при отладке очень хорошо описал MrYuran.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 30 2013, 14:06
Сообщение #53


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(veskon @ Sep 30 2013, 14:02) *
Помогите пожалуйста разобраться

Дык покажите свой porttimer.c и portserial.c и еще чего там меняли по сравнению с базовой демкой. Там же всё элементарно... laughing.gif
Go to the top of the page
 
+Quote Post
veskon
сообщение Sep 30 2013, 14:21
Сообщение #54





Группа: Новичок
Сообщений: 4
Регистрация: 30-09-13
Пользователь №: 78 547



Цитата(_Pasha @ Sep 30 2013, 17:06) *
Дык покажите свой porttimer.c и portserial.c и еще чего там меняли по сравнению с базовой демкой. Там же всё элементарно... laughing.gif


файл добавить не получается, поэтому пишу сам листинг. Примечание: исходные строчки не удалены, а закомментированы. Следом идут мои.

/*
* FreeModbus Libary: ATMega168 Port
* Copyright © 2006 Christian Walter <wolti@sil.at>
* Modified in 2010 by drvlas:
* Only RTU mode.
* Use T0 instead of T1. Implemented only on ATmega168
*/

/* ----------------------- AVR includes -------------------------------------*/
#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>

/* ----------------------- Platform includes --------------------------------*/
#include "../include/port.h"

/* ----------------------- Modbus includes ----------------------------------*/
#include "../include/mb.h"
#include "../include/mbport.h"

/* ----------------------- Defines ------------------------------------------*/
#define MB_TIMER_PRESCALER ( 1024UL )
#define MB_TIMER_TICKS ( F_CPU / MB_TIMER_PRESCALER )
#define MB_50US_TICKS ( 20000UL )

/* ----------------------- Static variables ---------------------------------*/
static USHORT usTimerOCRADelta;
//static USHORT usTimerOCRBDelta;

/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit( USHORT usTimerout50us )
{
/* Calculate overflow counter an OCR values for Timer0. */
usTimerOCRADelta =
( MB_TIMER_TICKS * usTimerout50us ) / ( MB_50US_TICKS );
if( usTimerOCRADelta > 255) return FALSE;

//TCCR0A = 0x00; // Normal Mode + Output Compare interrupt
TCCR0 = 0x00; // Normal Mode + Output Compare interrupt
//TCCR0B = 0x00;
TCCR2 = 0x00;


// TCCR1C = 0x00;

vMBPortTimersDisable( );

return TRUE;
}


inline void
vMBPortTimersEnable( )
{
TCNT0 = 0x0000;
if( usTimerOCRADelta > 0 )
{
//TIMSK0 |= _BV( OCIE0A );
TIMSK |= _BV( OCIE0 );
//OCR0A = usTimerOCRADelta; // MUST be < 256
OCR0 = usTimerOCRADelta; // MUST be < 256
}

//TCCR0B |= _BV( CS12 ) | _BV( CS10 ); // Fosc/1024
TCCR2 |= _BV( CS12 ) | _BV( CS10 ); // Fosc/1024
}

inline void
vMBPortTimersDisable( )
{
/* Disable the timer. */
//TCCR0B &= ~( _BV( CS12 ) | _BV( CS10 ) );
TCCR2 &= ~( _BV( CS12 ) | _BV( CS10 ) );
/* Disable the output compare interrupts for channel A */
//TIMSK0 &= ~( _BV( OCIE0A ) );
TIMSK &= ~( _BV( OCIE0 ) );
/* Clear output compare flags for channel A/B. */
//TIFR0 |= _BV( OCF0A ) ;
TIFR |= _BV( OCF0 ) ;
}

//SIGNAL( SIG_OUTPUT_COMPARE0A )
SIGNAL( SIG_OUTPUT_COMPARE0 )
{
( void )pxMBPortCBTimerExpired( );
}

Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 30 2013, 16:36
Сообщение #55


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Помогать так уж буквально не буду. Почитайте стр.84 даташита
Ошибки:
1. TCCR2 тут никаким боком. Работаем с TCCR0. Это в тексте vMBPortTimersEnable( )
2. Стесняюсь спросить, чему у Вас равно F_CPU ?Очень может быть, тик 100мкс неправильно посчитан.
--
Вообще, при наличии протеуса хоть 7.8 - такие ошибки симулем выловить как два пальца. Даже рисовать ничего не надо - поставили МК, питания и виртуал терминал, настроили - и поехали. Имхо получше чем студия.
Go to the top of the page
 
+Quote Post
veskon
сообщение Oct 1 2013, 06:11
Сообщение #56





Группа: Новичок
Сообщений: 4
Регистрация: 30-09-13
Пользователь №: 78 547



Цитата(_Pasha @ Sep 30 2013, 19:36) *
Помогать так уж буквально не буду. Почитайте стр.84 даташита
Ошибки:
1. TCCR2 тут никаким боком. Работаем с TCCR0. Это в тексте vMBPortTimersEnable( )
2. Стесняюсь спросить, чему у Вас равно F_CPU ?Очень может быть, тик 100мкс неправильно посчитан.
--
Вообще, при наличии протеуса хоть 7.8 - такие ошибки симулем выловить как два пальца. Даже рисовать ничего не надо - поставили МК, питания и виртуал терминал, настроили - и поехали. Имхо получше чем студия.


Да, наверное Вы правы,- попробую разобраться с Протеусом.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Apr 18 2014, 13:01
Сообщение #57


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Ребят удалось портировать? Никак не могу разобраться как прерывание описать надо, чтобы либа поняла, что прерыание случилось (прерывание по приему я имею ввиду). Что нужно засунуть в обработчик прерывания, какую функцию либы? Вот тут что то вообще непонятное:
Код
static void prvvUARTTxReadyISR( void )
{
    CHAR cByte;
    ( void )xMBPortSerialGetByte( &cByte );
    /* Now cByte should contain the character received. */
}


Я пишу порт на IAR для at90can32. Перерыл весь manual, сказано надо описать прерывание, а что туда писать непонятно. Подскажите будьте добры
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Apr 22 2014, 05:14
Сообщение #58


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Вообщем портировать удалось, кажется все по правилам, но пока ничего не заработало. Буду крайне признателен, если поможете. Написал portserial.c и porttimer.c. Объявил eMBRegHoldingCB(), eMBRegCoilsCB(), eMBRegDiscreteCB(), eMBRegInputCB(). Компилю, зашиваю, запускаю и наблюдаю следующее: при запросе от мастера read holding register (0x03) вызывается функция eMBRegHoldingCB(), и после ее отработки стек перестает работать (в ответ мастер не получает ни ответа ни привета), прерывания по приему после этого перестают срабатывать (хотя первые 8 байт из первого запроса прерывание вызывают). Но проц не зависает, все продолжает крутиться, ошибок никаких eMBPoll() не возвращает. Я уже кажется перечитал все форумы и темы, чего то похоже не понимаю.
Запрос от мастера:
Код
01 03 03 E9 00 04 95 B9

portserial.c
porttimer.c
main.c

Сам проект, если что-то непонятно. Вот, надеюсь на вашу помощь...
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Apr 22 2014, 11:29
Сообщение #59


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Люди, я может чего не понимаю, но получается следующее: отправкой исходящих пакетов занимается функция pxMBFrameCBTransmitterEmpty(), которая по-сути переадресована в случае с протоколом modbus RTU на функцию xMBRTUTransmitFSM(). А поскольку эта функция вызывается из прерывания по окончанию отправки, то выходит, чтобы стек ответил на входящий запрос от мастера, нужно после того как входящий запрос был распарсен, нужно "пинуть" стек и один раз вызвать xMBRTUTransmitFSM(). Я добавил этот вызов в функции eMBRTUSend() в файле mbrtu.c. Когда я так сделал стек заработал.
CODE

eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
{
eMBErrorCode eStatus = MB_ENOERR;
USHORT usCRC16;

ENTER_CRITICAL_SECTION( );

/* Check if the receiver is still in idle state. If not we where to
* slow with processing the received frame and the master sent another
* frame on the network. We have to abort sending the frame.
*/
if( eRcvState == STATE_RX_IDLE )
{
/* First byte before the Modbus-PDU is the slave address. */
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
usSndBufferCount = 1;

/* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
usSndBufferCount += usLength;

/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );

/* Activate the transmitter. */
eSndState = STATE_TX_XMIT;
vMBPortSerialEnable( FALSE, TRUE );
fledGreen();


/**
* ВОТ ЭТО Я ДОБАВИЛ, ЧТОБЫ ПИНУТЬ СТЕК !
*/

xMBRTUTransmitFSM();





}
else
{
eStatus = MB_EIO;
}
EXIT_CRITICAL_SECTION( );
return eStatus;
}


Почему он сразу не работает?!!
P.S: В указанных выше исходниках у меня НЕ включено прерывание по отправке, сейчас это исправлено.
Go to the top of the page
 
+Quote Post
Сepгeй
сообщение Mar 24 2015, 06:40
Сообщение #60





Группа: Участник
Сообщений: 8
Регистрация: 2-07-10
Пользователь №: 58 255



Доброго всем дня. Портирую freemodbus на stm32. Holding регистры читаются и записываются нормально, но вот Discrete читаются только 8 бит. В чем может быть проблема?

Код
#define REG_DISCRETE_START 1
#define REG_DISC_SIZE      24

unsigned char ucRegDiscBuf[REG_DISC_SIZE / 8];

eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    short           iNDiscrete = ( short )usNDiscrete;
    unsigned short  usBitOffset = 0;

    if( ( usAddress >= REG_DISCRETE_START ) &&
        ( usAddress + usNDiscrete <= REG_DISCRETE_START + REG_DISC_SIZE ) )
    {
        usBitOffset = ( unsigned short )( usAddress - REG_DISCRETE_START );
        while( iNDiscrete > 0 )
        {
            *pucRegBuffer++ =
                xMBUtilGetBits( ucRegDiscBuf, usBitOffset,
                                ( unsigned char )( iNDiscrete >
                                                   8 ? 8 : iNDiscrete ) );
            iNDiscrete -= 8;
            usBitOffset += 8;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}
Go to the top of the page
 
+Quote Post
smalcom
сообщение Mar 24 2015, 13:04
Сообщение #61


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



сколько задаёте, столько и считывается.
Go to the top of the page
 
+Quote Post
Сepгeй
сообщение Mar 24 2015, 13:35
Сообщение #62





Группа: Участник
Сообщений: 8
Регистрация: 2-07-10
Пользователь №: 58 255



Цитата(smalcom @ Mar 24 2015, 16:04) *
сколько задаёте, столько и считывается.
Задано 24 бита. Пытаюсь считать 24, считывается только 8 бит, оставшиеся 16 считываются как false хотя имеют значение true. Считываю программой Modbus Master V2.2

Go to the top of the page
 
+Quote Post
smalcom
сообщение Mar 24 2015, 14:55
Сообщение #63


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



Цитата
оставшиеся 16 считываются как false хотя имеют значение true

вы разницу между "не считывается" и "считываются как false" не ощущаете что ли? ну так это повод грустить.

раз считываются как false значит так оно и есть. проверяйте свой код который обслуживает эти биты.
Go to the top of the page
 
+Quote Post
Сepгeй
сообщение Mar 25 2015, 05:42
Сообщение #64





Группа: Участник
Сообщений: 8
Регистрация: 2-07-10
Пользователь №: 58 255



Цитата(smalcom @ Mar 24 2015, 17:55) *
вы разницу между "не считывается" и "считываются как false" не ощущаете что ли? ну так это повод грустить.

раз считываются как false значит так оно и есть. проверяйте свой код который обслуживает эти биты.

В моем случае они все таки не считываются если длина больше чем 8. У меня 24 регистра начиная с 1 адреса. Если считывать их по 8 бит, то читаются все биты. То есть можно прочесть с 1 по 8, с 9 по 16 и с 17 по 24. Причем адрес можно выставить не кратный 8 и считать скажем с 13 по 20, но если читать с 13 по 21 то 21 уже будет читаться некорректно.
Go to the top of the page
 
+Quote Post
Cruz21
сообщение Jul 2 2015, 07:35
Сообщение #65


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 23-01-13
Пользователь №: 75 313



У кого нибудь есть описание реализации Freemodbus хотя бы бедно на русском, либо полное объяснение на английском?
Go to the top of the page
 
+Quote Post

5 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 23:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.02194 секунд с 7
ELECTRONIX ©2004-2016