Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы
Непрочитано 09.02.2010, 22:40  
CMP_SYS
Частый гость
 
Регистрация: 22.07.2007
Сообщений: 21
Сказал спасибо: 1
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
CMP_SYS на пути к лучшему
По умолчанию Modbus RTU

Здравствуйте! Кто может помочь с примером рабочей программой с использованием Modbus RTU для AVR на языке С желательно адаптированной для AVR Studio . Заранее благодарен.
Реклама:
CMP_SYS вне форума  
Непрочитано 10.02.2010, 19:19  
woroba
Гражданин KAZUS.RU
 
Регистрация: 13.06.2005
Адрес: РК г.Павлодар
Сообщений: 866
Сказал спасибо: 99
Сказали Спасибо 216 раз(а) в 140 сообщении(ях)
woroba на пути к лучшему
По умолчанию Re: Modbus RTU

UART поможет плюс расчет CRC(а сети куча примеров CRC)
__________________
Не ошибается лишь тот, кто ни чего не делает!
woroba вне форума  
Непрочитано 10.02.2010, 20:38  
CMP_SYS
Частый гость
 
Регистрация: 22.07.2007
Сообщений: 21
Сказал спасибо: 1
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
CMP_SYS на пути к лучшему
По умолчанию Re: Modbus RTU

Да с CRC проблем нет, а как отследить в UART 3,5 бита
CMP_SYS вне форума  
Непрочитано 10.02.2010, 20:40  
baiderin
Почётный гражданин KAZUS.RU
 
Аватар для baiderin
 
Регистрация: 10.12.2007
Адрес: Екатеринбург
Сообщений: 2,729
Сказал спасибо: 2,435
Сказали Спасибо 893 раз(а) в 580 сообщении(ях)
baiderin на пути к лучшему
По умолчанию Re: Modbus RTU

Таймером.Запускать по каждому импульсу.
baiderin вне форума  
Непрочитано 11.02.2010, 00:36  
meteor
Прохожий
 
Регистрация: 19.11.2006
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
meteor на пути к лучшему
По умолчанию Re: Modbus RTU

// Расчет контрольной суммы для MODBUS протокола
//---------------------------------------------------------------------------
unsigned int CRC16Total(volatile unsigned char *pBuffer, unsigned int usBufferSize)
{
unsigned int usResult = 0xFFFF;
unsigned int j;
unsigned char i;

for(j = 0; j ‹ usBufferSize; j++)
{
usResult = usResult ^ pBuffer[j];

for(i = 0; i ‹ 8; i++)
{
if((usResult & 0x01) == 0x01)
{
usResult = usResult ›› 1;
usResult = usResult ^ 0xA001;
}
else
usResult = usResult ›› 1;
}
}
return usResult;
}
meteor вне форума  
Непрочитано 11.02.2010, 00:39  
meteor
Прохожий
 
Регистрация: 19.11.2006
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
meteor на пути к лучшему
По умолчанию Re: Modbus RTU

Кусок из реального живого проекта под PIC18

// Проверка диапазона и формирование выходного пакета данных
//--------------------------------------------------------------------------------------
unsigned char move_read (unsigned char *ptr, unsigned short size, unsigned short addr)
{
unsigned char i,j;

addr = (addr-1)*2;
if(offset ›= addr) //
if((offset+nbyte)‹= (addr + size)) // запрос настроек ПИН
{
out_buf[2]=nbyte;
offset = offset-addr;
for(i=0;i‹nbyte;i++)
{
if(i&1) // в MODBUS старший байт идет первым в пакете
j=i-1;
else
j=i+1;
out_buf[j+3]=*(ptr+offset+i);
}

tx_len = nbyte + 5;
return (1);
}
return(0);
}


// Проверка диапазона, сохранение принятых данных и формирование выходного пакета отчета
//------------------------------------------------------------------------------------------
unsigned char move_write (unsigned char *ptr, unsigned short size, unsigned short addr)
{
unsigned char i,j;

addr = (addr-1)*2;
if(offset ›= addr)
if((offset+nbyte)‹= (addr+ size)) // запись
{
offset = offset-addr;
for(i=0;i‹nbyte;i++)
{
if(i&1) // в MODBUS старший байт идет первым в пакете
j=i-1;
else
j=i+1;
*(ptr+offset+i)=in_buf[j+7];
}

for(i=2;i‹6;i++)
out_buf[i]=in_buf[i]; // формируем ответное сообщение
tx_len=8;
return (1);
}
return(0);
}


//------------------------------- Основной цикл ------------------------------------
void main(void)
{

unsigned int tmp,tmp2,n;
unsigned char i;




Init();
while (1)
{
CLRWDT();
led_control();
in_main_cycle (); // операции которые должны повторяться

if (tmr_check_rs232==0)
{
tmr_check_rs232 = 5; // 5 мс


if (flg.rx_pack)
{
flg.rx_pack=0;
rx_len= nrx;
nrx=0;
}

if (rx_len ›=5) // если длина достаточна
{
in.crc = CRC16Total(in_buf,(rx_len-2));
if ((in.crcbyte[0]==in_buf[rx_len-2])&&(in.crcbyte[1]==in_buf[rx_len-1])) // если CRC совпала
if (in_buf[0]==1) // если адрес совпал
{
out_buf[0]=1;
out_buf[1]=in_buf[1];

if (in_buf[1]==4)
in_buf[1]=3;

switch (in_buf[1]) // проверка типа функции
{
case 3: // чтение данных

offset=(in_buf[2]*256+in_buf[3])*2;
nbyte=in_buf[5]*2;
if ((in_buf[4]==0)&&(in_buf[5] ‹= DATA_MAX_LEN)) // читать не более 240 байт за 1 раз
{
if (move_read ((unsigned char *)&VarData, sizeof(VarData), ADDR_VarData))
break;

if (move_read ((unsigned char *)&State, sizeof(State), ADDR_State))
break;

/*
if (move_read ((unsigned char *)&Set, sizeof(Set), ADDR_Set))
break;
*/

if (move_read ((unsigned char *)&pu_const[0][0], sizeof(pu_const), ADDR_PuConst))
break;

if (move_read ((unsigned char *)PuComm, sizeof(PuComm), ADDR_PuComm))
break;

if (move_read ((unsigned char *)&Control[0], sizeof(Control), ADDR_Contr))
break;

if (move_read ((unsigned char *)&Rxbuf_eedata[0], sizeof(Rxbuf_eedata), ADDR_ReadSet))
{
Rxbuf_eedata[0] = Rxbuf_eedata[0]&0xf0; // Rxbuf_eedata.code = 0; // сбросить флаг получения ответа
break;
}

if (move_read ((unsigned char *)&Txbuf_eedata[0], sizeof(Txbuf_eedata), ADDR_WriteSet))
break;
}

out_buf[1]=in_buf[1]|0x80;
out_buf[2]=2; // код ошибки - адрес или количество не поддерживается
tx_len=5;

break;

case 16: // запись данных

offset=(in_buf[2]*256+in_buf[3])*2;
nbyte=in_buf[5]*2;
if ((in_buf[4]==0)&&(in_buf[5] ‹= DATA_MAX_LEN)) // писать не более 240 байт за 1 раз
{
/*
if(move_write ((unsigned char *)&Set, sizeof(Set), ADDR_Set))
{
n=sizeof(Set); // число байт настроек
for(i=0; i‹ n ;i++)
{
tmp=*((unsigned char *) &Set+i); // полученные настройки
tmp2 = eeprom_read(SETUP_EEADR + i); // сохраненная в EEPROM версия настроек
if(tmp!=tmp2) // если отличаются, обновить
write_eeprom (SETUP_EEADR +i,tmp);
}
break;
}
*/

if (move_write ((unsigned char *)&Txbuf_eedata[0], sizeof(Txbuf_eedata), ADDR_WriteSet))
{
Rxbuf_eedata[0] = Rxbuf_eedata[0]&0xf0; // Rxbuf_eedata.code = 0; // сбросить флаг получения ответа
break;
}


if(move_write ((unsigned char *)&Set.password, sizeof(Set.password), ADDR_Write_Password))
{
n=sizeof(Set.password); // число байт
for(i=0; i‹ n ;i++)
{
tmp=*((unsigned char *) &Set.password+i); // полученные настройки
tmp2 = eeprom_read(PASSW_EEADR + i); // сохраненная в EEPROM версия настроек
if(tmp!=tmp2) // если отличаются, обновить
write_eeprom (PASSW_EEADR +i,tmp);
}
break;
}


if (move_write ((unsigned char *)&WritePassw, sizeof(WritePassw), ADDR_CheckPassw))
{
if(cnt_err_psw ‹3) // если прием пароля не заблокирован 3 неверными попытками
{
if(WritePassw == Set.password) // если принятый пароль совпал с заданным в ПИН
{
cnt_wrt = 1; // разрешить однократную запись в ПИН
cnt_err_psw = 0; // сбросить счетчик неудачных попыток передачи пароля
}
else
cnt_err_psw ++; // инкремент счетчика ошибок пароля
}
break;
}

if(cnt_wrt) // если разрешена запись в переменные ПИН
{

if (move_write ((unsigned char *)PuComm, sizeof(PuComm), ADDR_PuComm))
{
cnt_wrt--;
break;
}

if (move_write ((unsigned char *)&Control[0], sizeof(Control), ADDR_Contr))
{
cnt_wrt--;
break;
}
}
}

out_buf[1]=in_buf[1]|0x80;
out_buf[2]=2; // код ошибки - адрес или количество не поддерживается
tx_len=5;

break;

default: // функция не поддерживается
out_buf[1]=in_buf[1]|0x80;
out_buf[2]=1; // код ошибки
tx_len=5;
break;
}

out.crc=CRC16Total(out_buf,(tx_len-2));
out_buf[tx_len-2]=out.crcbyte[0];
out_buf[tx_len-1]=out.crcbyte[1];

ntx = tx_len; // число передаваемых байт
T0CS=0; // Переход на тактирование от ядра - старт передачи данных

tmr_err_modbus = 0; // Сброс ошибки модбас (нет обмена более 1 мин)
State.Pin.err_modbus =0;
flg.rs232_red =0;
}
}
rx_len=0;
}
}
}
meteor вне форума  
Сказали "Спасибо" meteor
alexgap (11.02.2010)
Непрочитано 11.02.2010, 00:41  
meteor
Прохожий
 
Регистрация: 19.11.2006
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
meteor на пути к лучшему
По умолчанию Re: Modbus RTU

Ну и переменные имеющие к нему отношение

//--------------------------- программный UART для MODBUS -----------------------------------


volatile unsigned char nrx,ntx; // счетчик принятых, еще непереданных байт
volatile unsigned char rx_pack_timer; // счетчик межбайтн. интервала

volatile unsigned char rx_len,tx_len;
volatile unsigned short offset; // смещение первого читаемого байта
volatile unsigned char nbyte; // запрошенное количество байт
volatile unsigned char * ptr;


volatile unsigned char in_buf[RX_MAX_LEN]; // Входной буфер MODBUS
volatile unsigned char out_buf[TX_MAX_LEN]; // Выходной буфер MODBUS

volatile union
{
unsigned int crc; // контрольная сумма. Союз описан для удобного доступа к младшему и старшему байтам.
unsigned char crcbyte[2]; // crcbyte[0] - мл. байт, crcbyte[1] - ст. байт
} in,out;
meteor вне форума  
Непрочитано 11.02.2010, 13:09  
SuperBot
Прохожий
 
Регистрация: 29.01.2010
Сообщений: 2
Сказал спасибо: 1
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
SuperBot на пути к лучшему
По умолчанию Re: Modbus RTU

есть бесплатные библиотеки, например http://freemodbus.berlios.de
SuperBot вне форума  
Непрочитано 12.02.2010, 11:37  
SasaVitebsk
Гражданин KAZUS.RU
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: Modbus RTU

Сообщение от CMP_SYS Посмотреть сообщение
Да с CRC проблем нет, а как отследить в UART 3,5 бита
Да не делает никто 3.5 бита. В AVR, придётся заводить прерывание на RxD. Иначе этого вообще никак не увидишь. Ну и под Виндой эта хрень не будет работать. Там менее 20мс сделать устойчивые задержки весьма затруднительно, если не сказать - невозможно.

Обычно делают 1.5 байта.
SasaVitebsk вне форума  
Непрочитано 12.02.2010, 16:45  
=GM=
Прописка
 
Регистрация: 21.09.2009
Сообщений: 218
Сказал спасибо: 1
Сказали Спасибо 29 раз(а) в 27 сообщении(ях)
=GM= на пути к лучшему
По умолчанию Re: Modbus RTU

Подправлю малёк, не 3.5 бита, а 3.5 байта, в смысле интервал
=GM= вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
управление по modbus antibiotic0000 Микроконтроллеры, АЦП, память и т.д 1 17.11.2009 13:23


Часовой пояс GMT +4, время: 13:53.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot