Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FreeModbus
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Интерфейсы
Страницы: 1, 2
veskon
Цитата(Lagman @ Sep 30 2013, 15:06) *
А может слейв адрес не тот?


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

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

Я с AVR не работал, но думаю если вы выложите свои исходники из /port то знающие люди помогут. А последовательность действий при отладке очень хорошо описал MrYuran.
_Pasha
Цитата(veskon @ Sep 30 2013, 14:02) *
Помогите пожалуйста разобраться

Дык покажите свой porttimer.c и portserial.c и еще чего там меняли по сравнению с базовой демкой. Там же всё элементарно... laughing.gif
veskon
Цитата(_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( );
}

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


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


Я пишу порт на IAR для at90can32. Перерыл весь manual, сказано надо описать прерывание, а что туда писать непонятно. Подскажите будьте добры
yanvasiij
Вообщем портировать удалось, кажется все по правилам, но пока ничего не заработало. Буду крайне признателен, если поможете. Написал 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

Сам проект, если что-то непонятно. Вот, надеюсь на вашу помощь...
yanvasiij
Люди, я может чего не понимаю, но получается следующее: отправкой исходящих пакетов занимается функция 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: В указанных выше исходниках у меня НЕ включено прерывание по отправке, сейчас это исправлено.
Сepгeй
Доброго всем дня. Портирую 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;
}
smalcom
сколько задаёте, столько и считывается.
Сepгeй
Цитата(smalcom @ Mar 24 2015, 16:04) *
сколько задаёте, столько и считывается.
Задано 24 бита. Пытаюсь считать 24, считывается только 8 бит, оставшиеся 16 считываются как false хотя имеют значение true. Считываю программой Modbus Master V2.2

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

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

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

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

В моем случае они все таки не считываются если длина больше чем 8. У меня 24 регистра начиная с 1 адреса. Если считывать их по 8 бит, то читаются все биты. То есть можно прочесть с 1 по 8, с 9 по 16 и с 17 по 24. Причем адрес можно выставить не кратный 8 и считать скажем с 13 по 20, но если читать с 13 по 21 то 21 уже будет читаться некорректно.
Cruz21
У кого нибудь есть описание реализации Freemodbus хотя бы бедно на русском, либо полное объяснение на английском?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.