Ðăng Nhập

View Full Version : Giúp mình về MODBUS...


stupid11
06-04-2011, 10:18 AM
Bạn nào đã từng làm truyền thông với MODBUS thì giúp mình với...tại vì mình được giao đề tài này mà chưa biết phải bắt đầu từ đâu..mong các bạn chia sẻ.chân thành cảm ơn.

manhlong
07-05-2011, 03:04 PM
Bạn nào đã từng làm truyền thông với MODBUS thì giúp mình với...tại vì mình được giao đề tài này mà chưa biết phải bắt đầu từ đâu..mong các bạn chia sẻ.chân thành cảm ơn.

mình cũng đang tìm hiểu cái này ? cậu làm được có thể cho mình tham khảo

tanbka
08-05-2011, 12:42 AM
Trước tiên các bạn search tài liệu trên internet ấy, nhiều lắm, Quan trọng nhất là là tìm được form truyền của nó. Về cơ bản nó cũng giống như truyền 485 thôi mà.

stupid11
08-05-2011, 10:44 AM
-MODBUS là giao thức,còn RS485 là chuẩn vật lý...Mình đang làm truyền thông với MODBUS qua RS485 ,tuy nhiên còn vướng mắc ở chỗ mã kiểm tra lổi CRC..Về lý thuyết thì mã CRC mình có thể tính toán được..nhưng lập trình code C thì mình vẫn chưa biết cách viết sao...
-Tuy nhiên nếu các bạn mới bắt tay vào làm thì có thể bỏ qua byte checksum..tự quy định 1 frame truyền riêng,trong đó gồm "start+địa chỉ+data+kết thúc"..Khi đã truyền nhận tốt thì chèn thêm byte checksum vào...

nhuythuy
21-05-2011, 01:13 PM
Đúng là với Modbus RTU thì phần tính CRC là có vẻ phức tạp hơn cả. Còn lại, nếu cứ theo Modbus chuẩn thì tài liệu về nó rất nhiều do Modbus khad đơn giản và lại là chuẩn mở. Giờ các thiết bị hỗ trợ Modbus TCP còn thực hiện dễ hơn nữa.

Để gửi 1 command tới 1 Slave, bắt buộc phải tính CRC, nếu không Slave sẽ ko trả lại Respond.

Có thể tính CRC rất đơn giản như sau (mình tham khảo được)

//-----------------------------------------------------------------------
HiTable: array[0..255] of Byte = (
$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80,
$41, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1,
$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $01,
$C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40,
$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80,
$41, $01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0,
$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01,
$C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41,
$01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81,
$40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1,
$81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, $00,
$C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41,
$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80,
$41, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0,
$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01,
$C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40,
$01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81,
$40, $01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0,
$80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, $01,
$C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40,
$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81,
$40, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1,
$81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00,
$C1, $81, $40);

LoTable: array[0..255] of Byte = (
$00, $C0, $C1, $01, $C3, $03, $02, $C2, $C6, $06, $07,
$C7, $05, $C5, $C4, $04, $CC, $0C, $0D, $CD, $0F, $CF,
$CE, $0E, $0A, $CA, $CB, $0B, $C9, $09, $08, $C8, $D8,
$18, $19, $D9, $1B, $DB, $DA, $1A, $1E, $DE, $DF, $1F,
$DD, $1D, $1C, $DC, $14, $D4, $D5, $15, $D7, $17, $16,
$D6, $D2, $12, $13, $D3, $11, $D1, $D0, $10, $F0, $30,
$31, $F1, $33, $F3, $F2, $32, $36, $F6, $F7, $37, $F5,
$35, $34, $F4, $3C, $FC, $FD, $3D, $FF, $3F, $3E, $FE,
$FA, $3A, $3B, $FB, $39, $F9, $F8, $38, $28, $E8, $E9,
$29, $EB, $2B, $2A, $EA, $EE, $2E, $2F, $EF, $2D, $ED,
$EC, $2C, $E4, $24, $25, $E5, $27, $E7, $E6, $26, $22,
$E2, $E3, $23, $E1, $21, $20, $E0, $A0, $60, $61, $A1,
$63, $A3, $A2, $62, $66, $A6, $A7, $67, $A5, $65, $64,
$A4, $6C, $AC, $AD, $6D, $AF, $6F, $6E, $AE, $AA, $6A,
$6B, $AB, $69, $A9, $A8, $68, $78, $B8, $B9, $79, $BB,
$7B, $7A, $BA, $BE, $7E, $7F, $BF, $7D, $BD, $BC, $7C,
$B4, $74, $75, $B5, $77, $B7, $B6, $76, $72, $B2, $B3,
$73, $B1, $71, $70, $B0, $50, $90, $91, $51, $93, $53,
$52, $92, $96, $56, $57, $97, $55, $95, $94, $54, $9C,
$5C, $5D, $9D, $5F, $9F, $9E, $5E, $5A, $9A, $9B, $5B,
$99, $59, $58, $98, $88, $48, $49, $89, $4B, $8B, $8A,
$4A, $4E, $8E, $8F, $4F, $8D, $4D, $4C, $8C, $44, $84,
$85, $45, $87, $47, $46, $86, $82, $42, $43, $83, $41,
$81, $80, $40);


function AnsiDataCRC16(sData: AnsiString; iLength: integer): Word;
var
HiCRC: byte;
LoCRC: byte;
iCount: integer;
iIndex: Word;
begin
HiCRC := $FF;
LoCRC := $FF;

for iCount := 1 to iLength do
begin
iIndex := HiCRC xor byte(sData[iCount]);
HiCRC := LoCRC xor HiTable[iIndex];
LoCRC := LoTable[iIndex];
end;

Result := (HiCRC shl 8 or LoCRC);
end;

//-----------------------------------------------------------------------

PS. Sorry, mình code trên Delphi nên hơi khác tí xíu, nhưng chắc ai cũng có thể chuyển sang C dc nhỉ :)