Цитата(FxMODE @ Nov 13 2008, 08:38)

Приветствую.
Нужно сделать запрос к СКС-3 по протоколу M-Bus. Опыта работы с протоколами не было, да и примеров найти не могу. Есть стандартный мануал, эт конечно хорошо. Но нужен любой пример запроса, просто покажите как это делать.
Заранее спасибо
Пример modbus, по крайней мере у нас реализован был так:
CODE
uchar ReadRegs(uchar RegAddr, uint* Data, uchar WaitTime)
{
uchar LRC;
uchar SlaveAddr;
uint RegCount;
uchar OutCount;
uchar ErrCount=0;
Repeat:
SlaveAddr = 2;
RegCount = 1;
OutCount = 0;
FrameBuffer[0]=':';
/* поле адреса ведомого */
FrameBuffer[1]=NumToChar(SlaveAddr>>4);
FrameBuffer[2]=NumToChar(SlaveAddr&0x0F);
/* поле финкции */
FrameBuffer[3]=NumToChar(READ_REGS>>4);
FrameBuffer[4]=NumToChar(READ_REGS&0x0F);
/* поле адреса регистра */
FrameBuffer[7]=NumToChar((RegAddr&0x00F0)>>4);
FrameBuffer[8]=NumToChar(RegAddr&0x0F);
RegAddr>>=8;
FrameBuffer[5]=NumToChar((RegAddr&0x00F0)>>4);
FrameBuffer[6]=NumToChar(RegAddr&0x0F);
/* количество регистров */
FrameBuffer[11]=NumToChar((RegCount&0x00F0)>>4);
FrameBuffer[12]=NumToChar(RegCount&0x0F);
RegCount>>=8;
FrameBuffer[9]=NumToChar((RegCount&0x00F0)>>4);
FrameBuffer[10]=NumToChar(RegCount&0x0F);
/* контрольная сумма LRC */
LRC = Calc_LRC((uchar*)&FrameBuffer[1], 12);
FrameBuffer[13]=NumToChar((LRC&0xF0)>>4);
FrameBuffer[14]=NumToChar(LRC&0x0F);
/* признак конца пакета */
FrameBuffer[15]='\r';
FrameBuffer[16]='\n';
FrameBuffer[17]='\0';
// отправляем готовый пакет
do
{
while(UCSRA_UDRE == false);
UDR = FrameBuffer[OutCount++];
}
while(FrameBuffer[OutCount] != '\0');
// ждём ответа
SetTimeOut(WaitTime);
PackedReady = false;
FrameLen = 0;
while(PackedReady==false && TimeOut>0);
if(TimeOut == 0)
{
if( ++ErrCount == 4 )
{
return TIME_OUT_ERR;
}
else goto Repeat;
}
RemoveTimeOut();
FrameLen -= 4;
LRC = CharToNum(FrameBuffer[FrameLen]); // декодируем LRC ASCII -> число
LRC <<= 4;
LRC |= CharToNum(FrameBuffer[FrameLen+1]);
if(LRC == Calc_LRC((uchar*)&FrameBuffer[1], FrameLen-1)) // проверяем LRC
{
// забираем содержимое регистра
*Data = StrToInt((uchar*)&FrameBuffer[RESPOND_FIELD_DATA], WORD);
return NORMAL;
}
else
{
if( ++ErrCount == 4 )
{
return CRC_ERR;
}
else goto Repeat;
}
}
//--------------------------------------------------------------------------------
uchar WriteRegs(uchar RegAddr, uint Data, uchar WaitTime)
{
uchar LRC;
uchar SlaveAddr;
uint RegCount;
uchar OutCount;
uchar ByteCount;
uchar ErrCount = 0;
Repeat:
SlaveAddr = 2;
RegCount = 1;
OutCount=0;
ByteCount=2;
FrameBuffer[0]=':';
/* поле адреса ведомого */
FrameBuffer[1]=NumToChar(SlaveAddr>>4);
FrameBuffer[2]=NumToChar(SlaveAddr&0x0F);
/* поле финкции */
FrameBuffer[3]=NumToChar(WRITE_REGS>>4);
FrameBuffer[4]=NumToChar(WRITE_REGS&0x0F);
/* поле адреса регистра */
FrameBuffer[7]=NumToChar((RegAddr&0x00F0)>>4);
FrameBuffer[8]=NumToChar(RegAddr&0x0F);
RegAddr>>=8;
FrameBuffer[5]=NumToChar((RegAddr&0x00F0)>>4);
FrameBuffer[6]=NumToChar(RegAddr&0x0F);
/* количество регистров */
FrameBuffer[11]=NumToChar((RegCount&0x00F0)>>4);
FrameBuffer[12]=NumToChar(RegCount&0x0F);
RegCount>>=8;
FrameBuffer[9]=NumToChar((RegCount&0x00F0)>>4);
FrameBuffer[10]=NumToChar(RegCount&0x0F);
/* количество байт */
FrameBuffer[13]=NumToChar((ByteCount&0x00F0)>>4);
FrameBuffer[14]=NumToChar(ByteCount&0x0F);
/* данные регистра */
FrameBuffer[17]=NumToChar((Data&0xF0)>>4);;
FrameBuffer[18]=NumToChar(Data&0x0F);
Data >>= 8;
FrameBuffer[15]=NumToChar((Data&0xF0)>>4);
FrameBuffer[16]=NumToChar(Data&0x0F);
/* контрольная сумма LRC */
LRC = Calc_LRC((uchar*)&FrameBuffer[1], 18);
FrameBuffer[19]=NumToChar((LRC&0xF0)>>4);
FrameBuffer[20]=NumToChar(LRC&0x0F);
/* признак конца пакета */
FrameBuffer[21]='\r';
FrameBuffer[22]='\n';
FrameBuffer[23]='\0';
// отправляем готовый пакет
do
{
while(UCSRA_UDRE == false);
UDR = FrameBuffer[OutCount++];
}
while(FrameBuffer[OutCount] != '\0');
// ждём ответа
SetTimeOut(WaitTime);
PackedReady = false;
FrameLen = 0;
while(PackedReady == false && TimeOut>0);
if(TimeOut == 0)
{
if( ++ErrCount == 4 )
{
return TIME_OUT_ERR;
}
else goto Repeat;
}
RemoveTimeOut();
FrameLen -= 4;
LRC = CharToNum(FrameBuffer[FrameLen]); // декодируем LRC ASCII -> число
LRC <<= 4;
LRC |= CharToNum(FrameBuffer[FrameLen+1]);
if(LRC == Calc_LRC((uchar*)&FrameBuffer[1], FrameLen-1)) // проверяем LRC
{
return NORMAL;
}
else
{
if( ++ErrCount == 4 )
{
return CRC_ERR;
}
else goto Repeat;
}
}
uchar Calc_LRC(uchar *Msg, uchar DataLen)
{
unsigned char uchLRC=0; /* Инициализация LRC */
unsigned char Byte;
DataLen>>=1;
while(DataLen--)
{
Byte=CharToNum(*Msg++);
Byte<<=4;
Byte|=CharToNum(*Msg++);
uchLRC+=Byte;
}
uchLRC=(0xFF-uchLRC); //первое дополнение
uchLRC++; // второе дополнение
return (uchLRC);
}
Под Си не нашел ещё есть вот это (под Delphi)
Причина редактирования: Использование [codebox]