Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
29.10.2016, 22:24
|
|
Частый гость
Регистрация: 10.09.2009
Сообщений: 19
Сказал спасибо: 7
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
расчет CRC16 X-25 и ХMODEM на dspIC33EP со встроеным модулем
Всем Привет.
Может кот поможет, у меня проблема с расчетом CRC-16 X-25, а вот XMODEM работает корректно. вычисление идет частично при помочи встроенного модуль CRC на dsPIC33EP.
Вот данные для вычисления CRC16:
name="X-25" width=16 poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff
name="XMODEM" width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000
вот кусок программы, вызов функции:
Код:
|
unsigned char messageString[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
// CRC-16 X-25, не работает, но вот он мне как раз и нужен,
// должно возвращаться 0x6DD4, приходит другое значение 0x8DDF
crcResult = CRC_ChecksumByte( messageString, 8, 0xFFFF, 0xFFFF, 1, 1);
// CRC-16 XMODEM, работает и получаем CRC=0x76AC
crcResult = CRC_ChecksumByte( messageString, 8, 0x0000, 0x0000, 0, 0); |
сама функция вычисления:
Код:
|
unsigned int CRC_ChecksumByte( unsigned char *data, unsigned char Number_of_bytes, unsigned int initCRC, unsigned int xorOut, unsigned int refIn, unsigned int refOut)
{
unsigned char volatile *dest = ( unsigned char * ) &CRCDATL;
unsigned int crc = 0; unsigned char c = 0;
CRCWDATL = initCRC;
IFS4bits.CRCIF=0; //CRC status Flag is Cleared
CRCCON1bits.CRCGO = 1;
do
{
while(1 != CRCCON1bits.CRCMPT);
while( (0 == CRCCON1bits.CRCFUL) && (0 ‹ Number_of_bytes) )
{
c = (unsigned char)*data++;
if (refIn==1) {c = reflect(c, 8);}
*dest = c;
Number_of_bytes--;
}
} while( 0 ‹ Number_of_bytes );
while(!IFS4bits.CRCIF)
Nop();
CRCDATL = 0x0000; /* Do this to shift the last word out of the CRC shift register */
while( CRCCON1bits.CRCFUL == 1 );
while(CRCCON1bits.CRCMPT!=1);
CRCCON1bits.CRCGO=0;
crc = CRCWDATL;
if (refOut==1) {crc=reflect(crc, 16);}
return ( crc ^ xorOut);
}
unsigned int reflect (unsigned int crc, int bitnum) {
// reflects the lower 'bitnum' bits of 'crc'
unsigned int i, j=1, crcout=0;
for (i=(unsigned int)1‹‹(bitnum-1); i; i››=1) {
if (crc & i) crcout|=j;
j‹‹= 1;
}
return (crcout);
} |
CRC-16 ХMODEM, работает и получаем CRC=0x76AC, вот здесь он совпадает, тестировал тремя разными программами.
CRC-16 X-25, не работает, но вот он мне как раз и нужен, Результат должен быть 0x6DD4, приходит другое значение 0x8DDF.
|
|
|
|
30.10.2016, 11:46
|
|
Гражданин KAZUS.RU
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
|
Re: расчет CRC16 X-25 и ХMODEM на dspIC33EP со встроеным модулем
для RefIn/RefOut = true полином должен быть зеркальным + смещение данных в другую сторону. Ваша железка так умеет? Софт режим, если что:
Код:
|
int Crc16x25 (char *Buffer, int Size)
{
int Crc = 0xFFFF;
while (Size--)
{
Crc = Crc ^ (*Buffer++);
for (int i = 0; i ‹ 8; i++)
{
if (Crc & 1) { Crc = (Crc ›› 1) ^ 0x8408; }
else { Crc = Crc ›› 1; }
}
}
return (Crc ^ 0xFFFF);
}
//--------------------------------------------------------------------------- |
|
|
|
|
30.10.2016, 11:57
|
|
Частый гость
Регистрация: 10.09.2009
Сообщений: 19
Сказал спасибо: 7
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: расчет CRC16 X-25 и ХMODEM на dspIC33EP со встроеным модулем
Сообщение от Hives
|
для RefIn/RefOut = true полином должен быть зеркальным + смещение данных в другую сторону. Ваша железка так умеет? Софт режим, если что:
Код:
|
int Crc16x25 (char *Buffer, int Size)
{
int Crc = 0xFFFF;
while (Size--)
{
Crc = Crc ^ (*Buffer++);
for (int i = 0; i ‹ 8; i++)
{
if (Crc & 1) { Crc = (Crc ›› 1) ^ 0x8408; }
else { Crc = Crc ›› 1; }
}
}
return (Crc ^ 0xFFFF);
}
//--------------------------------------------------------------------------- |
|
полином я не зеркальный брал 0х1021, данные по входу все "зеркалил" 8бит и по выходу один раз тоже (16бит). надо будет с полиномом поиграться спасибо.
|
|
|
|
30.10.2016, 12:25
|
|
Гражданин KAZUS.RU
Регистрация: 25.11.2010
Сообщений: 516
Сказал спасибо: 1
Сказали Спасибо 126 раз(а) в 109 сообщении(ях)
|
Re: расчет CRC16 X-25 и ХMODEM на dspIC33EP со встроеным модулем
зеркалить данные - это сильно но делать так не надо. зайди на вики, посмотри как оно вообще считается, в теории и с картинками.
|
|
|
|
30.10.2016, 21:51
|
|
Частый гость
Регистрация: 10.09.2009
Сообщений: 19
Сказал спасибо: 7
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: расчет CRC16 X-25 и ХMODEM на dspIC33EP со встроеным модулем
Сообщение от Hives
|
зеркалить данные - это сильно
|
я понимаю, и даже смысла нету пользоваться CRC железом.
но в теории должно было сработать
Проверить пока не могу, но днях отпишусь...
|
|
|
|
02.11.2016, 18:34
|
|
Частый гость
Регистрация: 10.09.2009
Сообщений: 19
Сказал спасибо: 7
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: расчет CRC16 X-25 и ХMODEM на dspIC33EP со встроеным модулем
Х25 CRC заработал, Пришлось маленько поеб*ться !
если кому интересно вот рабочий пример на X25 CRC, работает на железе:
Инициализация:
Код:
|
void CRC_Init_X25( void )
{
CRCCON1bits.CRCEN = 0;
CRCXORL = 0x0000;
Nop();
Nop();
CRCWDATL = 0x0000;
CRCWDATH = 0x0000; // NOTE:Non-direct Initial value fed to CRCWDAT
CRCXORL = 0x1021; // Reflected polynomial for 0x8408
CRCXORH = 0x0000;
CRCCON1bits.CRCISEL = 0;
CRCCON2bits.PLEN = POLYLEN; // Length of polynomial-1"
CRCCON2bits.DWIDTH = 7;
CRCCON1bits.LENDIAN = 0x1;
CRCCON1bits.CRCEN = 1;
} |
сама функция:
Код:
|
unsigned int CRC_ChecksumByte_X25( unsigned char *data, unsigned char Number_of_bytes)
{
unsigned char volatile *dest = ( unsigned char * ) &CRCDATL;
unsigned int crc = 0;
CRCWDATL = 0x84CF; // Non-direct CRC initial value for 0xFFFF
IFS4bits.CRCIF=0; //CRC status Flag is Cleared
CRCCON1bits.CRCGO = 1;
do
{
while(1 != CRCCON1bits.CRCMPT);
while( (0 == CRCCON1bits.CRCFUL) && (0 ‹ Number_of_bytes) )
{
*dest = *data;
data++;
Number_of_bytes--;
}
} while( 0 ‹ Number_of_bytes );
while(!IFS4bits.CRCIF)
Nop();
while( CRCCON1bits.CRCFUL == 1 );
*((unsigned char *)&CRCDATL) = (unsigned char)0; // Load 2-bytes to shift out final value
*((unsigned char *)&CRCDATL) = (unsigned char)0;
while(CRCCON1bits.CRCMPT!=1);
CRCCON1bits.CRCGO=0;
crc = CRCWDATL;
// efficient bit reversal for 16 bit int
crc = (((crc & 0xAAAA)››1) | ((crc & 0x5555)‹‹1));
crc = (((crc & 0xCCCC)››2) | ((crc & 0x3333)‹‹2));
crc = (((crc & 0xF0F0)››4) | ((crc & 0x0F0F)‹‹4));
crc = ((crc››8) | (crc‹‹8));
return (crc^0xFFFF);
} |
Код:
|
unsigned char messageString[9] = {'1','2','3','4','5','6','7','8','9'};
CRC_Init_X25(); // This function configures CRC module
crcResult = CRC_ChecksumByte_X25( messageString, 9); |
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 02:57.
|
|