PIC Vietnam

Go Back   PIC Vietnam > Truyền thông > Giao tiếp USB, CAN, I2C, SPI, USART...

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Giao tiếp USB, CAN, I2C, SPI, USART... Những giao tiếp được tích hợp trên PIC

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 26-04-2012, 02:49 PM   #1
hoc_picpicpic
Đệ tử 6 túi
 
Tham gia ngày: Feb 2009
Bài gửi: 127
:
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 ạ
hoc_picpicpic vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-04-2012, 02:50 PM   #2
hoc_picpicpic
Đệ tử 6 túi
 
Tham gia ngày: Feb 2009
Bài gửi: 127
:
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);


}
hoc_picpicpic vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 25-11-2012, 02:02 AM   #3
lovedt
Nhập môn đệ tử
 
Tham gia ngày: Mar 2010
Bài gửi: 5
:
không ai trả lời cả!
lovedt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 01-02-2015, 10:43 PM   #4
SLPRV
Nhập môn đệ tử
 
Tham gia ngày: Jun 2012
Bài gửi: 3
:
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)
{
UInt16 crc = 0xFFFF;

for (int pos = 0; pos < len; pos++) {
crc ^= (UInt16)buf[pos]; // XOR byte into least sig. byte of crc

for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
return crc;
SLPRV vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 02:02 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam