Jump to content

    

STM32F0 и CRC16

Всем привет

 

Сабж и непонятное подсчитывание

 

Включил в AHB

Полином (при считывании - все верно, 0x8005)

Прописал 0 в INIT

Дернул по ИЛИ RESET в CR

 

Далее скармливаю ему в DR байты (иначе не получится по поступлению данных)

 

Ну и не сходится

 

Как вообще правильно работать с CRC? Данные должны быть соразмерны полиному?

Share this post


Link to post
Share on other sites
Как вообще правильно работать с CRC? Данные должны быть соразмерны полиному?

 

Теории на счёт CRC предостаточно, как вариант - Циклический избыточный код и т.д. и т.п.

Share this post


Link to post
Share on other sites

А я всегда думал, что блок расчета CRC в STM32 считает CRC32...

Вот здесь я выкладывал 2 функции, программную и железную для STM32. Результат их работы одинаков. И да, на вход блока CRC32 должны подаваться 32-х битные слова.

В "железной" функции по ссылке применена "uint32_t __rbit( uint32_t )", Кеил её прекрасно понимает. Она реверсирует слово. И, похоже, в Cortex-M0 такой команды нету...

А здесь я сейчас нашел статейку про аппаратный блок расчета CRC в STM32...

А CRC16 я считаю программно.

/* --- crc16() -------------------------------------------------------------------------------------------- **
*  Контрольная сумма crc16
*    BYTE *buf - указатель на байтовый буфер
*    short num - размер буфера в байтах
*  Возвращает
*    unsigned short crc16 буфера
* -------------------------------------------------------------------------------------------------------- */
unsigned short crc16( BYTE *buf, unsigned short num )
{
#define POLINOM   0xa001
int i;
WORD crc = 0xffff;

 while ( num-- )
 { crc ^= *buf++;
   i = 8;
   do
   { if ( crc & 1 )
       crc = ( crc >> 1 ) ^ POLINOM;
     else
       crc >>= 1;
   } while ( --i );
 }
 return( crc );
#undef POLINOM
}

Share this post


Link to post
Share on other sites

Если вы пишете расчет контрольной суммы для передающей и принимающей стороны, то вы можете написать что угодно, лишь бы одинаково с обоих сторон) допустим использовать 16 байт из CRC32 :)

для всяких "ручных" расчетов сумм я обычно использую сумму флетчера - намного меньше процессорного времени хавает. особенно на каких-нибудь чахлых контроллерах с 8 битами и низкой тактовой частото =)

Share this post


Link to post
Share on other sites
А я всегда думал, что блок расчета CRC в STM32 считает CRC32...
В STM32F - да, в STM32L сделали возможность грузить любой полином.

Share this post


Link to post
Share on other sites

разве я спрашивал о сути CRC или программной реализации? вопрос только об аппаратном модуле CRC у STM32F0

 

А я всегда думал, что блок расчета CRC в STM32 считает CRC32...

Вот здесь я выкладывал 2 функции, программную и железную для STM32. Результат их работы одинаков. И да, на вход блока CRC32 должны подаваться 32-х битные слова.

В "железной" функции по ссылке применена "uint32_t __rbit( uint32_t )", Кеил её прекрасно понимает. Она реверсирует слово. И, похоже, в Cortex-M0 такой команды нету...

А здесь я сейчас нашел статейку про аппаратный блок расчета CRC в STM32...

 

спасибо, буду посмотреть

 

а у F0 таки да, можно менять и полином, и размер полинома и начальное значение

 

Share this post


Link to post
Share on other sites
разве я спрашивал о сути CRC или программной реализации? вопрос только об аппаратном модуле CRC у STM32F0

 

Теоретическую часть нужно знать хотя бы для того, чтобы вопросы задавать хоть на минимальном базисе. Это касается вопроса "Данные должны быть соразмерны полиному?".

Share this post


Link to post
Share on other sites
Теоретическую часть нужно знать хотя бы для того, чтобы вопросы задавать хоть на минимальном базисе. Это касается вопроса "Данные должны быть соразмерны полиному?".

 

да вы хоть поняли, что я спрашивал?

 

 

Share this post


Link to post
Share on other sites
а у F0 таки да, можно менять и полином, и размер полинома и начальное значение
У F0x0 - нельзя. Впрочем, там кроме разрядности и собственно полинома еще и зеркалирование данных задается. Может нужно отзеркалировать ваш полином и входные/выходные данные?

 

Share this post


Link to post
Share on other sites
У F0x0 - нельзя.

Вы оба правы ;)

У F030 и F070 полином не изменяемый, а у остальных: F0x1, F0x2 и F0x8 можно дополнительно грузить полином и настраивать его длину 7, 8, 16, 32 бита.

Для обоих в реф. мануалах пишут что можно писать байтами, полусловами или словами.

 

Хорошо бы код посмотреть повнимательнее, потому что DR описан как __IO uint32_t DR;

и если просто писать в CRC->DR то запись всегда будет происходить словами.

Share this post


Link to post
Share on other sites
Вы оба правы ;)

У F030 и F070 полином не изменяемый, а у остальных: F0x1, F0x2 и F0x8 можно дополнительно грузить полином и настраивать его длину 7, 8, 16, 32 бита.

Для обоих в реф. мануалах пишут что можно писать байтами, полусловами или словами.

 

Хорошо бы код посмотреть повнимательнее, потому что DR описан как __IO uint32_t DR;

и если просто писать в CRC->DR то запись всегда будет происходить словами.

именно так, у меня 071 и мне можно ;)

 

да только толку-то... да, результат разный, если к DR обращаться напрямую или как *(uint8_t), да только все равно не совпадает :(

Share this post


Link to post
Share on other sites

Вот здесь погоняйте свои байты в хвост и в гриву, пока не получите CRC, совпадающую с аппаратной в STM. Мне помогло.

http://depa.usst.edu.cn/chenjq/www2/softwa...calculation.htm

http://www.zorc.breitbandkatze.de/crc.html

Share this post


Link to post
Share on other sites
Вот здесь погоняйте свои байты в хвост и в гриву, пока не получите CRC, совпадающую с аппаратной в STM. Мне помогло.

http://depa.usst.edu.cn/chenjq/www2/softwa...calculation.htm

http://www.zorc.breitbandkatze.de/crc.html

угу.. доберусь только до железки

спсибо

Share this post


Link to post
Share on other sites

Все, заработало.

 

Скармливаю побайтно, обращение к регистру данных через

    *(__IO uint8_t *)((uint32_t)&(CRC->DR)) = data8;

 

всем спасибо!

Share this post


Link to post
Share on other sites
Все, заработало.
И? В чем была проблема?

 

обращение к регистру данных через

    *(__IO uint8_t *)((uint32_t)&(CRC->DR)) = data8;

Ужас. Зачем указатель явно приводить к 32-битному целому, чтобы потом его привести обратно к указателю? *(__IO uint8_t *)&CRC->DR было бы достаточно. Если уж хочется приводить к целому - то для этого есть специально заточенный uintptr_t, но здесь он не нужен. Совсем.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this