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

 
 
5 страниц V  « < 2 3 4 5 >  
Reply to this topicStart new topic
> FreeModbus
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

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 01:04
Рейтинг@Mail.ru


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