Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/68: Рейтинг темы: голосов - 68, средняя оценка - 4.72
Orsomo

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

08.01.2012, 17:30. Показов 13768. Ответов 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
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.01.2012, 17:30
Ответы с готовыми решениями:

Нет связи между модулем ввода (modbus rtu slave) и программой modbus poll на ноутбуке
Добрый день форумчанам. Сконфигурирован модуль modbus rtu slave в Ovation system. Опыт работы с modbus rtu master в овации есть, со slave...

Преобразование modbus rtu в modbus tcp
Суть проблемы: есть устройство, оно работает по протоколу modbus rtu, но нужно подключиться к нему по tcp. Подскажите, можно ли как-то...

Modbus RTU. Запись в modbus регистр
Доброго всем времени суток. qt5.15 Из приложения должен формироваться запрос — &quot;01 06 00 00 00 05 49 C9&quot;, по факту же...

8
0 / 0 / 0
Регистрация: 11.02.2011
Сообщений: 287
08.01.2012, 18:31
Цитата Сообщение от 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
Раз в секунду это лихо, раз в сутки, а то и раз в неделю примерно так(при 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
В общем то меня не особо интересуют АСУ ТП-шные вопросы в данной теме.
Ну как бы АСУТэПэшники отлаживают программы по кускам и уже потом со всеми реальными взаимосвязями.
Используешь RS232 ?
Напиши и отладь процедуру посылки тестового байта в RS232 по нажатию кнопки.
Затем телеграмму с CRC.
Потом свяжи работающие куски... = от простого к сложному.
Разбираться в нецветном неформатированном коде многим муторно :(
Code
1
2
3
while(1){
if (bModBus){
cNumTrByte0=ModBus(cNumRcByte0); //обработка принятого соообщения ModBus
0
Orsomo
08.01.2012, 20:38
За неформат пока сори, бьютифилировать было нечем(общаюсь с работы посему малость ограничен). Прерывание передачи уже пытался искаверкать, пока ничего не вышло. О проге с чистого листа уже начинаю задумываться просто на мой неискушенный взгляд идеология прототипа показалась достойной.
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
09.01.2012, 00:49
Цитата Сообщение от Orsomo
За неформат пока сори,
Выделяешь прогу и кликаешь Code (см. рядок выше редактируемого текста). Будет тебе бьюти :)

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

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

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

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

вот кусок с приемом/проверкой пакета и генерацией ответа: [2.3 Кб]
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.04.2012, 00:04
Помогаю со студенческими работами здесь

Ребят помогите с разобраться прогой
378. В экзаменационной ведомости можно выделить сведения о ведомости (предмет, номер группы, дата экзамена), сведения о человеке (фамилия,...

Modbus RTU
Здравствуйте, пытаюсь решить задачу. Нужно послать значение какой-либо переменной с микроконтроллера на панель по протоколу modbus. ...

Modbus RTU - разобрать сформированный запрос к Slave
Добрый день Не могу разобраться с работой modbus rtu что значит запрос 024600e260? 02 - номер модуля 46 - функция и нет нигде...

Modbus rtu wincc
Добрый день. Есть wincc advanced v13. Необходимо проверить наличие/отсутствие связи по канала modbus rtu. По modbus идет обмен между...

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


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru