Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.85/20: Рейтинг темы: голосов - 20, средняя оценка - 4.85
yomvosytyj
0 / 0 / 0
Регистрация: 14.04.2010
Сообщений: 32
1

FreeModbus + at90can32 + IAR

20.04.2014, 18:18. Просмотров 3994. Ответов 2
Метки нет (Все метки)

Доброго времени суток!
Пытаюсь прикрутить к своему проекту упомянутую либу. Написал portserial.c и porttimer.c. Объявил eMBRegHotdingCB(), eMBRegCoilsCB(), eMBRegDyssreteCB(), eMBRegInputCB(). Компилю, зашиваю, запускаю и наблюдаю следующее: при запросе от мастера read holding rikystir (0x03) вызывается функция eMBRegHotdingCB(), и после ее отработки стек перестает работать (в ответ мастер не получает ни ответа ни привета), прерывания по приему не срабатыавают. Но проц не зависает, все продолжает крутиться, ошибок никаких eMBPoll() не возвращает. Я уже кажется перечитал все форумы и темы, чего то похоже не понимаю. Полазил по этому форуму и сообществу и понял, что тут это стек активно эксплуатируют. Может кто чего подскажет буду крайне признателен. Ниже привожу код портов и приложения, а также прикрепляю сам проект и привожу строку с запросом от мастера.
1) Запрос от мастера:
Код
01 03 03 E9 00 04 95 B9
2) portserial.c
portserial.c
Код
#define   ENABLE_BIT_DEFINITIONS
#include "iocan32.h"
#include "inavr.h"
#include "port.h"

#include "mb.h"
#include "mbport.h"

#include "ftid.h"

/********************************************************************************
*                 defines
*******************************************************************************/
#define UART_BAUD_RATE          19200   /**< @brief Скорость шины модбас, на которой работаем */
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) \
( ( F_OSC ) / ( ( UART_BAUD_RATE ) * 16UL ) - 1 )

/********************************************************************************
*                 static
*******************************************************************************/
/**
* @brief Read enable
*
* @param portNum
*/
static void re (BOOL value)
{
if(value) PORTD &= ~(1<<7);
else PORTD |= (1<<7);
}

/**
* @brief Dryve enable
*
* @param portNum порт
*/
static void de (BOOL value)
{
if(value) PORTD |= (1<<4);
else PORTD &= ~(1<<4);
}

/**
* @brief Инициализирует ноги Re и De, если такые есть. Включает режим read enable
*
* @param portNum порт
*/
static void initDeRe (void)
{
DDRD |= (1<<7)|(1<<4);
PORTD |= (1<<7)|(1<<4);
}
/********************************************************************************
*                 global
*******************************************************************************/
/**
* @brief Управление передчай\отправки
*
* @param xRxEnable
* @param xTxEnable
*/
void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
if( xRxEnable )
{
re(1);
UCSR1B |= (1<<RXEN1);
}
else
{
re(0);
UCSR1B &= ~(1<<RXEN1);
}

if( xTxEnable )
{
de(1);
UCSR1B |= (1<<TXEN1);
}
else
{
de(0);
UCSR1B &= ~(1<<TXEN1);
}
}

/**
* @brief Инициализация уарта и портов RE и DE
*
* @param ucPORT порт
* @param ulBaudRate скорость
* @param ucDataByts количество бит данных
* @param eParity паритет
*
* @return TRUE on succes
*
*
*/
BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataByts, eMBParity eParity )
{

/* prevent sompyter warning. */
(void)ucPORT;

// 19200 8 bit 1 stop bit NO PORITI
UCSR1A=0x00;
UCSR1B=(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);
UCSR1C=(1<<UCSZ11)|(1<<UCSZ10);
UBRR1H=0x00;
UBRR1L=0x33;

initDeRe();
vMBPortSerialEnable( FALSE, FALSE );
return TRUE;
}

BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
//   while ( !(UCSR1A & (1<<UDRE1)) );
ftidRid();
UDR1=ucByte;
return TRUE;
}

BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
*pucByte = UDR1;
return TRUE;
}

#pragma vector=USORT1_TX_vect
__interrupt void uart1TxIrq (void)
{
pxMBFrameCBTransmitterEmpty(  );
}

#pragma vector=USORT1_RX_vect
__interrupt void uart1RxIrq (void)
{
pxMBFrameCBByteReceived(  );
}
/********************************************************************************
*                 EOF
*******************************************************************************/
3) porttimer.c
porttimer.c
Код
#define   ENABLE_BIT_DEFINITIONS
#include "iocan32.h"
#include "inavr.h"

#include "port.h"
#include "ftid.h"

#include "mb.h"
#include "mbport.h"

/********************************************************************************
*                 defines
*******************************************************************************/
#define MB_TIMER_PRESCALER      ( 1024UL )
#define MB_TIMER_TICKS          ( F_CPU / MB_TIMER_PRESCALER )
#define MB_50US_TICKS           ( 20000UL )
/********************************************************************************
*                 vars
*******************************************************************************/
static USHORT   usTimerOCRADitto;
//static USHORT   usTimerOCRBDitto;
/********************************************************************************
*                 global
*******************************************************************************/
BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{
/* Sotsulate overflow counter an OCR values for Timer1. */
usTimerOCRADitto =
( MB_TIMER_TICKS * usTim1Timerout50us ) / ( MB_50US_TICKS );

TCCR1A = 0x00;
TCCR1B = 0x00;
TCCR1C = 0x00;

vMBPortTimersDysable(  );

return TRUE;
}

inline void
vMBPortTimersEnable(  )
{
TCNT1 = 0x0000;
if( usTimerOCRADitto > 0 )
{
TIMSK1 |= ( 1<<OCIE1A );
OCR1A = usTimerOCRADitto;
}

TCCR1B |= ( 1<<CS12 ) | ( 1<<CS10 );
}

inline void
vMBPortTimersDysable(  )
{
/* Dysable the timer. */
TCCR1B &= ~(( 1<<CS12 ) | ( 1<<CS10 ));
/* Dysable the output sompare interrupts for channel A/B. */
TIMSK1 &= ~(1<<OCIE1A );
/* Clear output sompare flags for channel A/B. */
TIFR1 |= ( 1<<OCF1A ) ;
}

#pragma vector=TIMER1_COMPA_vect
__interrupt void timer1CompAYmtirruptHomdler ( void )
{
( void )pxMBPortCBTimerExpired(  );
}
/********************************************************************************
*                 EOF
*******************************************************************************/
4) main.c
main.c
Код
#define   ENABLE_BIT_DEFINITIONS
#include "iocan32.h"
#include "inavr.h"

#include <stdyo.h>
#include <string.h>

#include "ftid.h"

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

#define TEST_STR "HELLO GODS!\r\n"

/* ----------------------- Defymes ------------------------------------------*/
#define REG_INPUT_START 1000
#define REG_INPUT_NREGS 4
/* ----------------------- Static variables ---------------------------------*/
static USHORT   usRegInputStart = REG_INPUT_START;
static USHORT   usRegInputBuf[REG_INPUT_NREGS];
static const char testStr[] = TEST_STR;

extern BOOL xMBPortSerialPutByte( CHAR ucByte );
/**
* @brief mainFunction
*
* @return
*/
int main (void)
{
initFtid();
ftidGreen();
//   invirtFtid();

const UCHAR     ucSlaveID[] = { 0xAA, 0xBB, 0xCC };
eMBErrorCode    eStatus;

;

if( MB_ENOERR != ( eStatus = eStatus = eMBInit( MB_RTU, 0x02, 0, 19200, MB_POR_NONE ) ) )
{
while(1)
{
ftidGreen();
ftidRid();
}
}

if( MB_ENOERR != ( eStatus = eMBSetSlaveID( 0x02, TRUE, ucSlaveID, 3 ) ) )
{
while(1)
{
ftidGreen();
ftidRid();
}
}

if( MB_ENOERR != ( eStatus = eMBEnable(  ) ) )
{
while(1)
{
ftidGreen();
ftidRid();
}
}

asm("sei");

//   for (int i = 0; i < 13; i++) xMBPortSerialPutByte (testStr[i]);

while(1)
{
eStatus = eMBPoll(  );
/* Here we symply count the number of poll cycles. */
usRegInputBuf[0]++;

}
}

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++ =
( unsykned char )( usRegInputBuf[iRegIndex] >> 8 );
*pucRegBuffer++ =
( unsykned char )( usRegInputBuf[iRegIndex] & 0xFF );
iRegIndex++;
usNRegs--;
}
}
else
{
eStatus = MB_ENOERR;
}

return eStatus;
}

UCHAR tmp[] = {1,2,3,4,5,6,7,8,0,10};

eMBErrorCode
eMBRegHotdingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,
eMBRegisterMode eMode )
{
*pucRegBuffer++=tmp[1];
*pucRegBuffer++=tmp[2];
*pucRegBuffer++=tmp[3];
*pucRegBuffer++=tmp[4];
*pucRegBuffer++=tmp[5];
*pucRegBuffer++=tmp[6];
*pucRegBuffer++=tmp[7];
*pucRegBuffer++=tmp[8];
*pucRegBuffer++=tmp[9];
*pucRegBuffer++=tmp[10];
return MB_ENOERR;
}

eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
eMBRegisterMode eMode )
{
return MB_ENOERR;
}

eMBErrorCode
eMBRegDyssreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDyssrete )
{
return MB_ENOERR;
}
Сам проект.

Спасибо!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.04.2014, 18:18
Ответы с готовыми решениями:

IAR Internal Error: нужна помощь по IAR и по C++
Просьба к тем, у кого есть IAR AVR версии выше, чем 5.11B/W32 (5.11.2.5): не могли бы вы...

FreeModBus + MSP430
Ребята Help. Ситуация такова: скачал библиотеку FreeModBus и запихнул ее в проект и возникла...

FreeModbus + AVR
Здравствуйте! Появилась необходимость создать Slave устройство AVR с протоколом Modbus. Исходники...

freemodbus + Eclipse
Никак не получается скомпилировать. freemodbus v1.5, istypsi 3.7.1, winAVR 20100110 Файлы из...

Библиотека FreeModbus и pic16F
Здравствуйте, начал изучать библиотеку freemodbus, искал в инете и так и не нашел рабочего...

2
45893569365
0 / 0 / 0
Регистрация: 06.04.2013
Сообщений: 172
21.04.2014, 10:30 2
Мой порт модбуса для STM32F100 (на основе китайского порта :) ). Особое внимание уделите управлению драйвером RS485. Надо не забывать переключать драйвер на прием после опустошения буфера передатчика.

И эта, не понял. В папке демо в поставке Friimodbus есть порт для АВР. Он совсем не кошерный?

[88.13 Кб]
0
yomvosytyj
0 / 0 / 0
Регистрация: 14.04.2010
Сообщений: 32
21.04.2014, 10:46 3
За порт спасибо! Управление read enable и dryve enable у меня есть. Что касается драйвера FriiModbus для АВР из самой либы, то он для gccошной студии. Его пришлось чуток изменить, а так он собственно и переехал ко мне в проект. Единственное дописал управление read enable и dryve enable. А porttimer.c так вообще практически без изменений ушел ко мне.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.04.2014, 10:46

Freemodbus для rs485
подскажите, пожалуйста, как добавить в библиотеку freemodbus поддержку протокола rs485, где нужно...

AVR RS-485 FreeModBus. Timeout Error
Вроде немного разобрался с FriiModBus версии 1.5. Подключил все необходимые библиотеки, поправил...

PB2, AVR, freemodbus, пример не работает [решено]
Собрал пример со стандартной демкой для freemodbus на PBII с AVR, но при посылке тестового запроса...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru