modbus RTU với pic cần giúp đỡ
chào các huynh, em viết chương trình modbus RTU slave trên pic16f877a nhưng crc gửi đi ko đúng, em có tham khảo cách tính crc trong tài liệu http://forums.ni.com/attachments/ni/...I_MBUS_300.pdf .
huynh nao làm rồi giúp em xem sai ở đâu. trình tự em test như sau : Modbus Master send: 0x01 address Slave 0x04 function 4 0x00 address start byte hight 0x01 address start byte low 0x00 0x04 quantity 0xA0 crc hight 0x09 crc low Modbus Sleve Respond: (pic16f877a) 01 04 08 00 00 00 00 00 00 00 00 40 0B huynh nào có cách tính crc khác chỉ giúp em với ạ |
còn đây là chương trình:
#include <16F877A.h> #fuses HS, NOWDT ,PROTECT ,NOBROWNOUT ,NOPUT #use delay(clock=20000000) #use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,bits=8, stop=2, parity=N) int1 modbus_flag_status; int8 modbus_index = 0; int8 modbus_data_transmit[10]; int8 modbus_data_reciever[10]; //--------------------------------------- int16 modbus_calcu_crc(int8 *puchMsg, int16 usDataLen); //--------------------------------------- void main() { int8 i ; int8 quantity ; int16 modbus_crc ; enable_interrupts(INT_RDA); enable_interrupts(GLOBAL); for(i=0;i<10;i++ ) { modbus_data_transmit[i] = 0; }; while(TRUE) { if( modbus_flag_status == 1 ) // test function 4 { modbus_flag_status = 0; putchar( modbus_data_reciever[0]); // adress slave putchar( modbus_data_reciever[1]); // function quantity = modbus_data_reciever[5]*2 ; putchar(quantity); // byte count for(i=0;i<quantity;i++) { putchar( modbus_data_transmit[i] ); // data byte }; modbus_crc = modbus_calcu_crc(modbus_data_transmit, quantity); // crc calculate putchar( modbus_crc >> 8 ); // crc hight byte putchar( modbus_crc); // crc low byte }; } } //----------------------------------------------------------- int16 modbus_calcu_crc(int8 *puchMsg, int16 usDataLen) { //--------------------------------------- /* Table of CRC values for high–order byte */ const unsigned char modbus_CRCHi[] = { 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 }; /* Table of CRC values for low–order byte */ const unsigned char modbus_CRCLo[] = { 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,0xED,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 }; int8 uchCRCHi, uchCRCLo ; int16 uIndex ; int16 i ; uchCRCHi = 0xFF ; uchCRCLo = 0xFF ; for(i=0;i < usDataLen ;i++ ) { uIndex = uchCRCHi ^ *puchMsg++ ; uchCRCHi = uchCRCLo ^ modbus_CRCHi[uIndex]; uchCRCLo = modbus_CRCLo[uIndex] ; }; i = uchCRCHi ; i = (i<<8) | uchCRCLo ; return(i); } //----------------------------------------------------------- #INT_RDA void interrupt_rs232(void) { char data ; data = getchar(); modbus_data_reciever[modbus_index] = data; modbus_index++ ; if( modbus_index >= 8 ) { modbus_flag_status = 1; modbus_index = 0; }; //putchar(data); } |
không ai trả lời cả!
|
Có 1 ví dụ khi viết trên C#:
Với chuỗi "01 03 00 01 00 04". Ta khai báo 1 mảng byte mang[]; Hãy gán giá trị cho mảng như sau: mang[0] = Convert.ToByte("01",16) ....và tiếp tục với các giá trị còn lại còn lại. chuỗi truyền có 6 byte nên "len = 6"; Khi sử dụng thì hãy gọi hàm ModRTU_CRC(mang,len); Code:
UInt16 ModRTU_CRC(byte[] buf, int len) |
Múi giờ GMT. Hiện tại là 01:18 PM. |
Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam