Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F0 и CRC16
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
toweroff
Всем привет

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

Включил в AHB
Полином (при считывании - все верно, 0x8005)
Прописал 0 в INIT
Дернул по ИЛИ RESET в CR

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

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

Как вообще правильно работать с CRC? Данные должны быть соразмерны полиному?
spf
Цитата(toweroff @ Dec 22 2015, 01:14) *
Как вообще правильно работать с CRC? Данные должны быть соразмерны полиному?


Теории на счёт CRC предостаточно, как вариант - Циклический избыточный код и т.д. и т.п.
VAI
А я всегда думал, что блок расчета CRC в STM32 считает CRC32...
Вот здесь я выкладывал 2 функции, программную и железную для STM32. Результат их работы одинаков. И да, на вход блока CRC32 должны подаваться 32-х битные слова.
В "железной" функции по ссылке применена "uint32_t __rbit( uint32_t )", Кеил её прекрасно понимает. Она реверсирует слово. И, похоже, в Cortex-M0 такой команды нету...
А здесь я сейчас нашел статейку про аппаратный блок расчета CRC в STM32...
А CRC16 я считаю программно.
CODE

/* --- 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
}

slavokhire5
Если вы пишете расчет контрольной суммы для передающей и принимающей стороны, то вы можете написать что угодно, лишь бы одинаково с обоих сторон) допустим использовать 16 байт из CRC32 sm.gif
для всяких "ручных" расчетов сумм я обычно использую сумму флетчера - намного меньше процессорного времени хавает. особенно на каких-нибудь чахлых контроллерах с 8 битами и низкой тактовой частото =)
Сергей Борщ
Цитата(VAI @ Dec 22 2015, 08:23) *
А я всегда думал, что блок расчета CRC в STM32 считает CRC32...
В STM32F - да, в STM32L сделали возможность грузить любой полином.
toweroff
Цитата(spf @ Dec 22 2015, 06:41) *

Цитата(slavokhire5 @ Dec 22 2015, 09:42) *

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

Цитата(VAI @ Dec 22 2015, 08:23) *
А я всегда думал, что блок расчета CRC в STM32 считает CRC32...
Вот здесь я выкладывал 2 функции, программную и железную для STM32. Результат их работы одинаков. И да, на вход блока CRC32 должны подаваться 32-х битные слова.
В "железной" функции по ссылке применена "uint32_t __rbit( uint32_t )", Кеил её прекрасно понимает. Она реверсирует слово. И, похоже, в Cortex-M0 такой команды нету...
А здесь я сейчас нашел статейку про аппаратный блок расчета CRC в STM32...


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

а у F0 таки да, можно менять и полином, и размер полинома и начальное значение
spf
Цитата(toweroff @ Dec 22 2015, 12:45) *
разве я спрашивал о сути CRC или программной реализации? вопрос только об аппаратном модуле CRC у STM32F0


Теоретическую часть нужно знать хотя бы для того, чтобы вопросы задавать хоть на минимальном базисе. Это касается вопроса "Данные должны быть соразмерны полиному?".
toweroff
Цитата(spf @ Dec 22 2015, 10:55) *
Теоретическую часть нужно знать хотя бы для того, чтобы вопросы задавать хоть на минимальном базисе. Это касается вопроса "Данные должны быть соразмерны полиному?".


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

Сергей Борщ
Цитата(toweroff @ Dec 22 2015, 10:45) *
а у F0 таки да, можно менять и полином, и размер полинома и начальное значение
У F0x0 - нельзя. Впрочем, там кроме разрядности и собственно полинома еще и зеркалирование данных задается. Может нужно отзеркалировать ваш полином и входные/выходные данные?
SSerge
Цитата(Сергей Борщ @ Dec 22 2015, 15:23) *
У F0x0 - нельзя.

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

Хорошо бы код посмотреть повнимательнее, потому что DR описан как __IO uint32_t DR;
и если просто писать в CRC->DR то запись всегда будет происходить словами.
toweroff
Цитата(SSerge @ Dec 22 2015, 11:42) *
Вы оба правы wink.gif
У F030 и F070 полином не изменяемый, а у остальных: F0x1, F0x2 и F0x8 можно дополнительно грузить полином и настраивать его длину 7, 8, 16, 32 бита.
Для обоих в реф. мануалах пишут что можно писать байтами, полусловами или словами.

Хорошо бы код посмотреть повнимательнее, потому что DR описан как __IO uint32_t DR;
и если просто писать в CRC->DR то запись всегда будет происходить словами.

именно так, у меня 071 и мне можно wink.gif

да только толку-то... да, результат разный, если к DR обращаться напрямую или как *(uint8_t), да только все равно не совпадает sad.gif
ViKo
Вот здесь погоняйте свои байты в хвост и в гриву, пока не получите CRC, совпадающую с аппаратной в STM. Мне помогло.
http://depa.usst.edu.cn/chenjq/www2/softwa...calculation.htm
http://www.zorc.breitbandkatze.de/crc.html
toweroff
Цитата(ViKo @ Dec 22 2015, 15:56) *
Вот здесь погоняйте свои байты в хвост и в гриву, пока не получите CRC, совпадающую с аппаратной в STM. Мне помогло.
http://depa.usst.edu.cn/chenjq/www2/softwa...calculation.htm
http://www.zorc.breitbandkatze.de/crc.html

угу.. доберусь только до железки
спсибо
toweroff
Все, заработало.

Скармливаю побайтно, обращение к регистру данных через
Код
    *(__IO uint8_t *)((uint32_t)&(CRC->DR)) = data8;


всем спасибо!
Сергей Борщ
Цитата(toweroff @ Dec 22 2015, 19:41) *
Все, заработало.
И? В чем была проблема?

Цитата(toweroff @ Dec 22 2015, 19:41) *
обращение к регистру данных через
Код
    *(__IO uint8_t *)((uint32_t)&(CRC->DR)) = data8;
Ужас. Зачем указатель явно приводить к 32-битному целому, чтобы потом его привести обратно к указателю? *(__IO uint8_t *)&CRC->DR было бы достаточно. Если уж хочется приводить к целому - то для этого есть специально заточенный uintptr_t, но здесь он не нужен. Совсем.
toweroff
Цитата(Сергей Борщ @ Dec 22 2015, 19:54) *
И? В чем была проблема?

не поверите - сам не понял sm.gif
просто получилось ожидаемое...

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

я это выражение вытащил из SPI, тоже на просторах нашел, когда бодался с uSD картой. Похоже, у STM это нормально, в порядке вещей. У NXP таких извращений не наблюдалось
Сергей Борщ
Цитата(toweroff @ Dec 22 2015, 20:08) *
Похоже, у STM это нормально, в порядке вещей. У NXP таких извращений не наблюдалось
ST или NXP тут совершенно не причем. Это квалификация автора - его знание языка и понимание того, что он пишет.
toweroff
Цитата(Сергей Борщ @ Dec 22 2015, 22:04) *
ST или NXP тут совершенно не причем. Это квалификация автора - его знание языка и понимание того, что он пишет.

в плане языка - согласен, конечно. Я имел ввиду именно обращение к регистру как n-битному с явным приведением
у филипсов, при настройке какого-то модуля в другую разрядность, ничего делать не приходилось
Ruslan1
Цитата(SSerge @ Dec 22 2015, 10:42) *
Вы оба правы wink.gif
У F030 и F070 полином не изменяемый, а у остальных: F0x1, F0x2 и F0x8 можно дополнительно грузить полином и настраивать его длину 7, 8, 16, 32 бита.
Для обоих в реф. мануалах пишут что можно писать байтами, полусловами или словами.

Подниму тему, у меня вопрос именно про CRC в STM32F070.

Хочу использовать CRC 16-битный. Можно ли для этого задействовать аппаратный модуль данного МК ?

Очень мутно написано в рефмануале про возможность выбора длины и вида полинома, в тексте есть такое:
Цитата
Uses CRC-32 (Ethernet) polynomial: 0x4C11DB7
X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1
• Alternatively uses a fully programmable polynomial with programmable size (7, 8, 16,
32 bits).
• Handles 8-,16-, 32-bit data size
• Programmable CRC initial value

Но в списке регистров не вижу ничего, позволяющего "Alternatively uses a fully programmable polynomial with programmable size".
То есть только CRC32 с полиномом 0x4C11DB7 ?

И что будет считать быстрее: использовать имеющийся табличный расчет CRC16, или все-таки можно пробовать приспособить этот аппаратный модуль под что-то, дающее на выходе циклически рассчитанное 16-битное значение?
Вопрос именно в скорости вычислений, нужно минимизировать задержку от момента появления данных до их отправки.

Хм.Или вообще уйти от CRC на что-то ксоровидное, канал довольно чистый (межплатное соединение внутри корпуса), если аппаратный модуль не приклеивается...
toweroff
Там все просто, пишем данные в регистр и после записи последнего слова имеем рассчитанную CRC
Если еще быстрее - попробовать настроить DMA из куска памяти в регистр, по окончании работы DMA вычитать регистр CRC
esaulenka
Цитата(Ruslan1 @ Feb 5 2016, 10:20) *
Хм.Или вообще уйти от CRC на что-то ксоровидное, канал довольно чистый (межплатное соединение внутри корпуса), если аппаратный модуль не приклеивается...


Скажу банальность, но XOR - плохо.
Лично наступал на грабли "при отвалившемся проводе принимаем 0xFF, контрольная сумма сходится". Хотя б байты складывать...


(дополнил)

Цитата(toweroff @ Feb 5 2016, 16:04) *
Там все просто, пишем данные в регистр и после записи последнего слова имеем рассчитанную CRC

Вот интересно мне, сиё для кого написано было?..

Цитата(SSerge @ Dec 22 2015, 11:42) *
У F030 и F070 полином не изменяемый, а у остальных: F0x1, F0x2 и F0x8 можно дополнительно грузить полином и настраивать его длину 7, 8, 16, 32 бита.

Цитата(Ruslan1 @ Feb 5 2016, 10:20) *
Подниму тему, у меня вопрос именно про CRC в STM32F070.
Хочу использовать CRC 16-битный.
toweroff
Цитата(esaulenka @ Feb 5 2016, 16:19) *
Вот интересно мне, сиё для кого написано было?..

а ведь и правда...
пятница...
Ruslan1
Цитата(esaulenka @ Feb 5 2016, 15:19) *
Скажу банальность, но XOR - плохо.
Лично наступал на грабли "при отвалившемся проводе принимаем 0xFF, контрольная сумма сходится". Хотя б байты складывать...

Да, понимаю, спасибо.
Кстати, у меня было как-то, что CRC16 у разных пакетов данных сходились: делал базу на всего-то пару тысяч записей (примерно по 260 байт), и делал индексирование для быстрого поиска, индексом(сигнатурой) была CRC16 блока. И данные заведомо разные (там в том числе и дата-время были в блоке, и номер записи). Но вот повторяющиеся сигнатуры встречались, и нередко. Пришлось дополнительно еще и дату-время проверять у вытащенной по индексу записи, CRC16 в качестве уникальной сигнатуры не хватало sm.gif

Но у меня условия будут тепличные (длина линии связи сантиметров пять), да и просто не придет такой тривиальный пакет (у меня там SLIP фреймы принимать будет), ну и на уровне приложения тоже есть некоторая проверка кроме контрольной суммы.

Цитата(toweroff @ Feb 5 2016, 17:20) *
а ведь и правда...
пятница...

sm.gif
Я почитал- там и CRC32 как-то по-странному нужно задействовать, чтобы совпало с софтовой реализацией (инверсия битов подсовываемого байта ?), то есть не все так просто как хочется.
Чистый маркетинг. Оно есть, но подходит совсем далеко не всем.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.