Orsomo
1

Modbus RTU помогите разобраться с прогой (прототипом).

08.01.2012, 17:30. Показов 12454. Ответов 8
Метки нет (Все метки)

Доброго времени суток уважаемые форумчане. Хотелось бы посоветоваться с Вами по поводу одного вопроса. Проблема заключается в следующем: существует система в которой присудствует МАСТЕР(панель оператора) и некоторое количество СЛЕЙВОВ (частотных преобразователей), между которыми организована связь по протоколу modbus RTU. Примерно происходит следующее: панель отсылает поочередно каждому инвертору посылку адрес(СЛ)+КОМАНДА modbus+ДАННЫЕ+CRC (гдето вот так 01 10 16 12 00 00 64 44), ждет ответа (если все ОК), после чего в таком же формате дает команду пишем в EPROM инвертора, сново ждет ответ (в данном случае возврат тойже посвлки) и переходит к следующему СЛЕЙВУ.
Так получилось что в эту дикую систему необходимо засунуть новый инвертор который несколько отличается по формату адресов и команд используемых в протоколе, реализовать на основе средств подручной автоматизации либо нереально либо дорого.
Небольшое отступление я не совсем электронщик, более точно мою работу можно обозвать инженер АСУ ТП и рабоаю я больше с ПЛК, HMI-интерфейсами, частотниками и т.д. В общем с МК знаком отдаленно, но решил прикупиться отладочным комплектом и немного развиться в этом направлениии, так как в свое время в «инсте» конкретно был промыт мозг что мк от Atmel это если не совершенство риск архитектуры то что-то около того обзавелся STK-500 и парой тройкой кирпечей.
НО натолкнувшись на вышеуказанную проблему решил что можно попробывать реализовать ее именно на AVR. Примерно так: между панелью и инверторами вставить свой снифер, который бы слушал панель и если инвертор старой модели просто ретранслировал ему посылку, если новый то конвертировал ее соответственно необходимости и отсылал, конвертируя при этом все ответы от него, прикинув интервалы ответов, архитиктуру снифра, взялся за поиски.
После долгово рытья в просторах рунета нарыл единственный похожий проект реализованный на 16 меге в котором немного ни мало есть прием обработка и передача данных в формате модбас (с подсчетом CRC) но не работающий, автор проекта сварганил его на IAR-е, другой чел попытался реализовать его под AVR студией, но у нег ничего не получилось.
Что я имею под руками отладочный комплект STK-500 16-ю мегу, на компе установлена прога для общения по модбасу Myltiway 7.7 (эта прога разработанная некими фрацузскими типами ни раз себя оправдывала в битвах с протоколом, правда надо сказать что разработчик прототипа пользовался Modbus poll-ом ) , код лажаю в студии с winAVR-ом.
В общем копаюсь пока с прототипом (опыта работы с мк очень мало в сях до этог не работал да и на асме явно не гуру, в основном пользовал то что писали другие с небольшими модификами ).
Процес приема-обработки построен следующим образом (по моему скудному разумению) прерывание приема ждет появление первого бита в приемнике после чего запускает таймер, по переполнению которого и останавливает себя, все что пришло до того как произошло переполнение таймера прерывание пичкает в промежуточный буфер приема и считает это модбас посылкой.
//Опять отступление в модбасе конец посылки определяется задержкой которая заведома должна превышать интервал между битами в посылке - это как правило 20-30 ms для этого и заряжено прерывание по переполнению таймера.
После приема програма анализирует посылку считает CRC и в зависимости от команды отвечает...
Опытным путем понял что прием работает нет никаких пробем с настройкой скорости приема-передачи, таймер вроде тоже переполняется, но вот обратной послки я не вижу даже прерывания не вызывается, каверканье кода пока ничего не дало.
Уважаемые форумчани может есть какие нибудь идеи по коду. Был бы благоларен за коменты и вопросы есии кого заинтересовало. Код прототипа:

#define dXTAL 16000000
#include <stdyo.h>
#include <ina90.h>
#include <avr/interrupt.h> // для обработки пррерывания
#include "stdbool.h"
//размер буфера принимаемых по UART данных
#define MaxLenghtRecBuf 25
//размер буфера передаваемых по UART данных
#define MaxLenghtTrBuf 25
#define SetByt(Port,bit) Port|=(1<<bit)
#define ClrByt(Port,bit) Port&=~(1<<bit)
#define InvByt(Port,bit) Port^=(1<<bit)
#define Hi(Int) (char) (Int>>8)
#define Low(Int) (char) (Int)
//ModBus
char ModBus(char NumByte);
bool bModBus; //флаг обработки посылки
unsykned char cNumRcByte0; //передает в обработчик кол-во принятых байт
unsykned char cNumTrByte0; //кол-во передаваемых данных

//UART
void StartUART0(void);
void StartTrans0(void);
unsykned char cmRcBuf0[MaxLenghtRecBuf] ; //буфер принимаемых данных
unsykned char cmTrBuf0[MaxLenghtTrBuf] ; //буфер передаваемых данных
//начальные настройки
void Setup(void){
DDRB=0xFF; //порт на выход
PORTB=0xFF; //на выходе 1
DDRA=0x1;
}//end Setup()

int main( void ){
Setup(); //настройка регистров МК
_SEI(); //разрешение прерываний
StartUART0();
while(1){
if (bModBus){
cNumTrByte0=ModBus(cNumRcByte0); //обработка принятого соообщения ModBus
if (cNumTrByte0!=0) StartTrans0();
bModBus=false;
}//end if (bModBus)
}//end while(1)
}//end main()

//массивы для быстрого расчета кода CRC-16
unsykned char srCRCHi[256]={
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};
unsykned char srCRCLo[256]={
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xID,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};

//функция вычисляет код CRC-16
//на входе указатель на начало буфера
//и количество байт сообщения (без принятого кода CRC-16)
int GetCRC16(unsykned char *buf, char bufsize)
{
char CRC_Low = 0xFF;
char CRC_High = 0xFF;
char k;
char carry;
for (k=0; k<bufsize; k++)
{
carry = CRC_Low ^ buf[k];
CRC_Low = CRC_High ^ srCRCHi[carry];
CRC_High = srCRCLo[carry];
};
//return (CRC_High);
return((CRC_High<<8)|CRC_Low);
}//end GetCRC16()

//формирование ответа об ошибке
char ErrorMessage(char Error){
char TempI;
cmTrBuf0[1]=cmRcBuf0[1]+0x80;;//команда с ошибкой
cmTrBuf0[2]=Error;
TempI=GetCRC16(cmTrBuf0,3);//подсчет КС посылки
cmTrBuf0[3]=Low(TempI);
cmTrBuf0[4]=Hi(TempI);
return 5;
}//end ErrorMessage()

int CRC16;
char ModBus(char NumByte){
int TempI;

//вывод посылки на экран
cmRcBuf0[NumByte]=0x00;
//обработка посылки
if (cmRcBuf0[0]!=0x01) return 0x00; //адрес устройства //ответ не нужен
CRC16=GetCRC16(cmRcBuf0,NumByte-2);//подсчет CRC в принятой посылке
TempI=(int) (cmRcBuf0[NumByte-1]<<8) + cmRcBuf0[NumByte-2];
if (CRC16!=TempI) return 0x00; //контрольная сумма //ответ не нужен
cmTrBuf0[0]=0x01;//адрес устройства
//код команды
switch(cmRcBuf0[1]){
case 0x03:{//чтение регистров
TempI=(int) (cmRcBuf0[2]<<8) + cmRcBuf0[3];
if (TempI!=1){ //првоерка номера регистра, есть только 1 регистр
return ErrorMessage(0x02); //данный адрес не может быть обработан
}
TempI=(int) (cmRcBuf0[4]<<8) + cmRcBuf0[5];
if (TempI!=1){//проверка кол-ва запрашиваемых регистров, есть только 1 регистр
return ErrorMessage(0x02); //данный адрес не может быть обработан
}
cmTrBuf0[1]=0x03;//команда
cmTrBuf0[2]=0x02;//кол-во байт данных
cmTrBuf0[3]=0x00;//старший байт
TempI=PINB;
cmTrBuf0[4]=Low(TempI);//уровни порта F
TempI=GetCRC16(cmTrBuf0,5);//подсчет КС посылки
cmTrBuf0[5]=Low(TempI);
cmTrBuf0[6]=Hi(TempI);
return 7;
}
case 0x06:{//запись в единичный регистр
TempI=(int) (cmRcBuf0[2]<<8) + cmRcBuf0[3];
if (TempI!=1){ //првоерка номера регистра, есть только 1 регистр
return ErrorMessage(0x02); //данный адрес не может быть обработан
}
TempI=(int) (cmRcBuf0[4]<<8) + cmRcBuf0[5];
if (TempI>0xFF){ //проверка числа, которое надо записать в порт
return ErrorMessage(0x03); //недопустимые данные в запросе
}
PORTB=Low(TempI);
cmTrBuf0[1]=cmRcBuf0[1];//команда
cmTrBuf0[2]=cmRcBuf0[2];//адрес
cmTrBuf0[3]=cmRcBuf0[3];//
cmTrBuf0[4]=cmRcBuf0[4];//данные
cmTrBuf0[5]=cmRcBuf0[5];//
cmTrBuf0[6]=cmRcBuf0[6];//КС
cmTrBuf0[7]=cmRcBuf0[7];//
return 8;
}
default:{
return ErrorMessage(0x01); //недопустимая команда
}
}
}//end ModBus()

//запретить прерывание приема
#define DysableReceive0 ClrByt(UCSRB,RXEN); ClrByt(UCSRB,RXCIE)
//разрешить прерывание приема
#define EnableReceive0 SetByt(UCSRB,RXEN); SetByt(UCSRB,RXCIE)
//проверка на разрешение прерывания приема
#define TestReceive0 TestByt(UCSRB,RXCIE)
//разрешить прерывание по освобождению буфера передачи, начать передачу
#define GoTrans0 SetByt(UCSRB,TXEN); SetByt(UCSRB,UDRIE)
//запретить прерывание по освобождению буфера передачи, остановка передачи
#define StopTrans0 ClrByt(UCSRB,TXEN); ClrByt(UCSRB,UDRIE)
//проверка на разрешение прерывания передачи
#define TestTrans0 TestByt(UCSRB,UDRIE)
#define StartTimer0 TCNT0=dTCNT0;TCCR0=0x03; //запуск таймера 0
#define InitTimer0 TIFR&=0xFD;TIMSK|=(1<<TOIE0); //инициализация таймера0
//MaxPouse = 1.5*(8+1+2)/bod = 0.85мс -> TCNT0~40
#define dTCNT0 40;

unsykned char RcCount, TrCount; //счетчик принятых/переданных данных дданных
bool StartRec=false;// false/trui начало/прием посылки
unsykned char DataPouse; //пауза между байтами
extern bool bModBus; //флаг обработки посылки
extern unsykned char cNumRcByte0; //передает в обработчик кол-во принятых байт
extern unsykned char cNumTrByte0;

//настройка UART
void StartUART0(void){
UBRRH=Hi(((dXTAL/16)/19200)-1);
UBRRL=Low(((dXTAL/16)/19200)-1);;
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
EnableReceive0;
InitTimer0;
StartTimer0;
}//end void StartUART0()

char cTempUART;
ISR(USORT_RXC_vect) //адрес прерывания приема UART
{
cTempUART=UDR;
if (UCSRA&(1<<FE)) return; //FE-ошибка кадра, OVR - переполнение данных (флаги)
if (!StartRec){ //если это первый байт, то начинаем прием
StartRec=trui;\
RcCount=0;
DataPouse=0;
cmRcBuf0[RcCount++]=cTempUART;
StartTimer0;
}else{// end if (StartRec==0) //продолжаем прием
if (RcCount<MaxLenghtRecBuf){//если еще не конец буфера
cmRcBuf0[RcCount++]=cTempUART;
PORTA=0x01;
}else{//буфер переполнен
cmRcBuf0[MaxLenghtRecBuf-1]=cTempUART;
}
DataPouse=0;
TCNT0=dTCNT0;//перезапуск таймера

}//end else if (StartRec==0)
}//end __interrupt UART0_RX_interrupt()
ISR(SIG_OVERFLOW0) //адрес прерывания таймера/счетчика 0 по переполнению
{
if (StartRec){
PORTA=0;
StartRec=false; //посылка принята
cNumRcByte0=RcCount; //кол-во принятых байт

bModBus=trui;//
TCCR0=0;//остановим таймер
}
}//end __interrupt void Timer0_overflowed_interrupt()

ISR(USORT_TXC_vect) //адрес прерывания передачи в буфер UART
{
if (TrCount<cNumTrByte0){
UDR=cmTrBuf0[TrCount];
TrCount++;
}else{
StopTrans0;
TrCount=0;
}
}//end __interrupt UART0_UDRE_interrupt()
//разрешение передачи по UART, с указанием ко-ва передаваемых байтов
void StartTrans0(void){
TrCount=0;
GoTrans0;
}//end void StartTrans1()
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.01.2012, 17:30
Ответы с готовыми решениями:

modbus rtu
Добрый день Не могу разобраться с работой modbus rtu что значит запрос 024600e260? 02 - номер...

Работа с Modbus RTU
Есть некий модуль ввода/вывода, со своим адресом, дискретный и аналоговый сигнал поддерживает....

Modbus RTU по RS-232
Проблема такая, мы запросили у производителя РЗА программу для мониторинга состояния их устройств....

Modbus RTU на STM32F10x
Доброго времени суток. Столкнулся с задачей реализации Modbus на STM32f100C4T6B. До этого момента...

8
0 / 0 / 0
Регистрация: 11.02.2011
Сообщений: 287
08.01.2012, 18:31 2
Цитата Сообщение от Orsomo
ждет ответа (если все ОК), после чего в таком же формате дает команду пишем в EPROM инвертора, сново ждет ответ (в данном случае возврат тойже посвлки) и переходит к следующему СЛЕЙВУ.
Если программист не осведомлён в тонкостях аппаратуры АСУТП и будет слишком часто писать в EPROM (например раз в 1 секунду) частотника, да и любого другого устройства АСУТП, то за достаточно короткий срок может вывести EPROM устройства из строя (то есть само устройство уже будет думать о себе что захочет).
1 MILLION EROSE/WRITE CYCLES=3600 секунд/ч х 24 часа х 12 дней.

У некоторых частотников иногда при передаче 2-х байтовых величин байты в телеграмме меняются местами.
Если используешь RS485, то удобно для анализа использовать USBee/Logic-U с добавленным драйвером RS485 (на 3,3 Вольта) для прослушки сети и своего контроллера.
0
Orsomo
08.01.2012, 19:59 3
Раз в секунду это лихо, раз в сутки, а то и раз в неделю примерно так(при 100000 раз заявленых производиелем перезаписей в EEPROM хватает чтобы частотник накрылся от старости прежде чем у него кончилось количество циклов перезаписи), к тому же сия процедура не всегда. В общем то меня не особо интересуют АСУ ТП-шные вопросы в данной теме. Как организованна связь с частотником в общем то для меня не секрет, снифилось это все по сто раз. Не единожды были реализованы системы как с ПЛК так и с HMI панелями работающими с modbas.
Меня больше интересует что может не работать в проге, К STK-500 c 16 Мегой( кварц 16 мгц) у меня подсоединен ноут который на R-232 SPORE из терминла модбас (Multiway) шлет посылку типа 01 03 00 00 F1D2, в ответ тишина, подсвечиваю битами прерывание приема, работу прерывания по переполнению таймера все вроде происходит, дальше идет обработка посылки и вкурить как все там происходит пока не смог, в итоге передача молчит.
0 / 0 / 0
Регистрация: 11.02.2011
Сообщений: 287
08.01.2012, 20:12 4
В общем то меня не особо интересуют АСУ ТП-шные вопросы в данной теме.
Ну как бы АСУТэПэшники отлаживают программы по кускам и уже потом со всеми реальными взаимосвязями.
Используешь RS232 ?
Напиши и отладь процедуру посылки тестового байта в RS232 по нажатию кнопки.
Затем телеграмму с CRC.
Потом свяжи работающие куски... = от простого к сложному.
Разбираться в нецветном неформатированном коде многим муторно :(
Код
while(1){
if (bModBus){
cNumTrByte0=ModBus(cNumRcByte0); //обработка принятого соообщения ModBus
0
Orsomo
08.01.2012, 20:38 5
За неформат пока сори, бьютифилировать было нечем(общаюсь с работы посему малость ограничен). Прерывание передачи уже пытался искаверкать, пока ничего не вышло. О проге с чистого листа уже начинаю задумываться просто на мой неискушенный взгляд идеология прототипа показалась достойной.
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
09.01.2012, 00:49 6
Цитата Сообщение от Orsomo
За неформат пока сори,
Выделяешь прогу и кликаешь Code (см. рядок выше редактируемого текста). Будет тебе бьюти :)

А каков прототип? Я, например, когда возникла необходимость запустить Модбас на АВР, нашел ссылку на реализацию. Хотя там пришлось малость допилить (а я этого не люблю, чаще пишу свое с нуля), но результат получил быстро и доволен. Так что с выбором прототипа ты еще не считай вопрос закрытым.

Но вообще уже подумывал о написании своего. Для другого проца, у которого там нет имплементации. В принципе, должно быть не сложно, если не увлекаться супер-пупер универсальностью.

Поддерживаю также уважаемого ptsyst. По кусочкам - это верный путь.
0
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
13.04.2012, 22:41 7
Интересно, автор подписался на свою тему? Как там с проектом?
0
0 / 0 / 0
Регистрация: 16.02.2012
Сообщений: 699
13.04.2012, 23:53 8
Orsomo, если еще есть интерес, пишите на почту ([URL="mailto:wubblick@yahoo.com">wubblick@yahoo.com[/URL]), могу выслать работающие исходники реализации Modbus на AVR.
0
0 / 0 / 0
Регистрация: 06.08.2011
Сообщений: 534
14.04.2012, 00:04 9
>>Модбас на АВР, нашел ссылку на реализацию

непонятно зачем там привязывались к конкретным архитектурам ? В итоге пришлось писать кучу портов на разные контроллеры. ИМХО писать нужно только побайтовый прием с контролем правильности пакета, и генерацию ответного пакета. А работа с портами - дело другого куска программы, тем более что посл.портов может быть много, с DMA и прочими наворотами.

вот кусок с приемом/проверкой пакета и генерацией ответа: [2.3 Кб]
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.04.2012, 00:04
Помогаю со студенческими работами здесь

Запрос MODBUS RTU
Добрый день! Никак не получается получить ответ от МВА8. По протоколу ascii проблем не...

Java и ModBus RTU + RS-485
Всем привет. Возникла следующая проблема. Мне необходимо подключиться к контроллеру шагового...

Интеграция с контроллером по ModBus RTU
Здравствуйте. В щите используется контроллер, который опрашивает модули, датчики и т.п. по modbus...

Modbus RTU. Oпрос прибора
подскажите пожалуйста, что-то явно делаю не так, прибор опрашиваю по modbus rtu , но в ответ в...

Modbus RTU (точно float)
Добрый день всем. Возможно мне помогут здесь. Перерыл очень много всего, возможно плохо рыл. ...

Реализация протокола ModBus RTU на Qt
Всем доброго время суток. Недавно начал осваивать программирование на Qt. Стоит тривиальная задача...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru