Перейти к содержанию
    

Еще для полного счастья нужно использовать функции для записи\чтения битов 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED  (  1 )

В чем может быть проблема?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как выяснилось, проблема не в этой функции (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));

Если закоментировать эти строки, то ответ нормальный появляется. Наверно, правильно сделать так : в колбэк-функции устанавливать флаг, а в главном цикле по этому флагу писать во флеш.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

 

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Это нужно писать мастер. (FreeModbus - это Slave)

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как slave должен реагировать на прием пустого ADU? Т.е. который адресован ему и имеет правильный CRC, но не имеет ни функции, ни данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Если вместо функции и данных просто нули, то при проверки кода функции, если он данную ф-цию не поодерживает, должен вернуть ошибку с номером 1 (ILLEGAL FUNCTION).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Изменено пользователем ISK2010

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По хорошему проверка должна идти в следующей очередности:

1. Длина пакета

2. CRC

3. Адрес

4. Функция

5. Данные

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По хорошему проверка должна идти в следующей очередности:

1. Длина пакета

2. CRC

3. Адрес

4. Функция

5. Данные

 

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

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для простых случаев может и можно не проверять. А если сеть протяженная, с большим количеством слейвов, помеховая обстановка серьезная - вероятность ошибок в пакете приличная, проверка crc становится обязательной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Бесспорно проверка CRC обязательна. Но только для тех фреймов, которые нам адресованы. А если уже для этих фреймов не сошелся crc, то игнорируем их и инкрементируем счетчик ошибок crc.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да согласен

 

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

Изменено пользователем yashok

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброго дня всем.

Пытаюсь поднять 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 где-то на просторах интернета

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...