Хитрые, необычные алгоритмы и код
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Хитрые, необычные алгоритмы и код
честно говоря, вы тут слишком много понаписали и все запутали.
1 измерение АЦП это максимум 1023. 100 измерений в секунду за час дадут сумму максимум 1023*60*60*100=368280000 это unsigned long. эта переменная сможет накапливать ваши измерения в течение 11 часов максимум, потом переполнится.
нет никакой проблемы суммировать и сравнивать unsigned long для 8-битного МК.
1 измерение АЦП это максимум 1023. 100 измерений в секунду за час дадут сумму максимум 1023*60*60*100=368280000 это unsigned long. эта переменная сможет накапливать ваши измерения в течение 11 часов максимум, потом переполнится.
нет никакой проблемы суммировать и сравнивать unsigned long для 8-битного МК.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Хитрые, необычные алгоритмы и код
ARV писал(а):честно говоря, вы тут слишком много понаписали и все запутали.
возможно я виноват - признаюсь
попытаюсь еще раз объяснить
цифра которая видна на экране состоит из 2 переменных.
значение до запятой это 1-я переменная типа int - будет цифра на пределе инта = 65535
значение после запятой это 2-ая переменная типа char - будет цифра от 0 до 99
также в бэкграунде будет 3-ая переменная в которую будут суммироваться значения АЦП, значение этой переменной после каждого сложения с значением АЦП будет сравниваться с константой 360 000. Если значение 3-ей переменой перевалит за 360 000 тогда из нее вычитается 360 000, а 2-ая переменная инкрементируется.
Когда вторая переменная достигнет 100 она обнуляется, а первая переменная инкрементируется.
Вопрос был как лучше оптимизировать все потому что из-за большой константы 360 000 вынужден третью переменную сделать типа long. А это 100 раз в секунду работать с такой огромной переменной это нагрузка на MK который имеет еще кучу задач.
И понимаю чтоб уменьшить константу надо увеличить вторую переменную до уровня int и сделать ее в 10 раз больше то есть будут миллиамперы час. Таким образом константа сравнения будет в 10 раз меньше и смогу уместить 3-ю переменную в размер int.
А вторую переменную перед показом на экран буду делить на 10.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Хитрые, необычные алгоритмы и код
Госпадяяяя... какая же это нагрузка - сравнение, вычитание, сложение, ... ? Тем более с константамиamd9800 писал(а):с такой огромной переменной это нагрузка на MK
Делайте long и не парьтесь...
PS: Вы делаете проблему буквально из ничего. Что в этой теме, что в других. Вы, для начала, сделайте, а потом когда проблема появится - будете уже её решать.
Re: Хитрые, необычные алгоритмы и код
Немного отвлеку вас от текущего обсуждения...
В теме http://radiokot.ru/forum/viewtopic.php?f=61&t=119254 был поднят вопрос об инверсии порядка следования битов в слове на обратное (реверсия слова). Мне посоветовали продублировать ответ в этой теме, что я и делаю.
Первое, что приходит на ум, это реализовать такую функции с помощью цикла с побитовым просмотром исходного слова, однако в
книге Генри Уоррена "Алгоритмические трюки для программистов" можно найти вариант этой операции без использования цикла.
Для реверсии байта функция будет выглядеть следующим образом:
uint8_t ReverseByte(uint8_t b)
{
uint8_t ret;
ret = ((b & 0x55)<<1) | ((b & 0xAA)>>1);
ret = ((ret & 0x33)<<2) | ((ret & 0xCC)>>2);
ret = ((ret & 0x0F)<<4) | ((ret & 0xF0)>>4);
return ret;
}
В теме http://radiokot.ru/forum/viewtopic.php?f=61&t=119254 был поднят вопрос об инверсии порядка следования битов в слове на обратное (реверсия слова). Мне посоветовали продублировать ответ в этой теме, что я и делаю.
Первое, что приходит на ум, это реализовать такую функции с помощью цикла с побитовым просмотром исходного слова, однако в
книге Генри Уоррена "Алгоритмические трюки для программистов" можно найти вариант этой операции без использования цикла.
Для реверсии байта функция будет выглядеть следующим образом:
uint8_t ReverseByte(uint8_t b)
{
uint8_t ret;
ret = ((b & 0x55)<<1) | ((b & 0xAA)>>1);
ret = ((ret & 0x33)<<2) | ((ret & 0xCC)>>2);
ret = ((ret & 0x0F)<<4) | ((ret & 0xF0)>>4);
return ret;
}
Re: Хитрые, необычные алгоритмы и код
По мне, гораздо проще объявить 1 переменную ΣCODE как 32 разрядную и результат получать по выражению 100*RES=ΣCODE/K, гдеamd9800 писал(а):цифра которая видна на экране состоит из 2 переменных.
значение до запятой это 1-я переменная типа int - будет цифра на пределе инта = 65535
значение после запятой это 2-ая переменная типа char - будет цифра от 0 до 99
также в бэкграунде будет 3-ая переменная в которую будут суммироваться значения АЦП...
100 - число измерений в единицу времени
K - коэффициент преобразования.
Децимальную точку принудительно ставить после единиц. Например K=130, т.е. 1A соответствует значение 130 единиц АЦП и входном токе 7.86А в сумматоре ΣCODE должно накопиться
7.86*130*100=102180 и 100*RES=ΣCODE/K=102180/130=786
Можно избавиться от операции деления на константу, заменив её умножением. В данном случае разрядность ΣCODE не изменится.
Re: Хитрые, необычные алгоритмы и код
akl писал(а):...
я признателен за попытку помочь, но мне кажется что вы запутались и не заметили что перепутали ампер*часы с амперами.
Поэтому ваши расчеты получились не правильными.
Также у вас в расчетах появилось деление, наверное на фоне деления - long уже точно не проблема.
Я хочу разгрузить МК более оптимизированным кодом, а не загрузить дополнительно.
Все таки оптимизировал экономия скомпилированной программы примерно 40 байт.
Вместо 3 переменной unsigned long.
Будет 3 переменная unsigned int
и 4 переменная unsigned char.
Код: Выделить всё
Ah - первая (unsigned int)
cAh - вторая (unsigned char)
tempAh - третья (unsigned int)
tempAhz - четвертая (unsigned char)
Код: Выделить всё
tempAh=tempAh+Amp;
if (tempAh>35999)
{
tempAh=tempAh-36000;
tempAhz++;
if (tempAhz>9)
{
tempAhz=0;
cAh++;
if (cAh>99)
{
cAh=0;
Ah++;
}
}
}
- afz
- Опытный кот
- Сообщения: 744
- Зарегистрирован: Сб дек 22, 2012 08:17:42
- Откуда: Караганда, Казахстан
Re: Хитрые, необычные алгоритмы и код
Да, на Си оно выглядит довольно красиво. Однако, как мне кажется, реализация этого дела займет гораздо больше 16 машинных команд того же АВР. Тогда, как банальное повторение 8 раз пары команд rol r0 ror r1 легко и непринужденно вывернет наизнанку содержимое R0 и поместит его в R1. Про 8051 не скажу, не знаю я его, но, даже если у него есть сдвиги на заданное число разрядов, а не на один, все равно все это довольно сложно, в отличие отConst14 писал(а):Немного отвлеку вас от текущего обсуждения...
В теме http://radiokot.ru/forum/viewtopic.php?f=61&t=119254 был поднят вопрос об инверсии порядка следования битов в слове на обратное (реверсия слова). Мне посоветовали продублировать ответ в этой теме, что я и делаю.
Первое, что приходит на ум, это реализовать такую функции с помощью цикла с побитовым просмотром исходного слова, однако в
книге Генри Уоррена "Алгоритмические трюки для программистов" можно найти вариант этой операции без использования цикла.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Re: Хитрые, необычные алгоритмы и код
Вот так можно менять значения установки часов для серии DS1307 - DS3232M, не прибегая к таблицам, и BCD->HEX->BCD
В rab первое значение, все остальное в rab1 , кроме 0
В rab первое значение, все остальное в rab1 , кроме 0
Код: Выделить всё
;**************************************************
;* ;;/PLUS DATA;;* *
;**************************************************
Clock_Plus:
push temp
ld temp,X ;| Получаем значение
add temp,rab ;| Прибавляем константу для счёта в BCD
subi temp,-1 ;| Прибавляем единицу
brhc Plus_Chng ;| Проверяем переход с F->0 (перенос)
SAVE_PLUS:
sub temp,rab ;| Вычитаем константу и получаем упакованный BCD
cpse temp,rab1 ;| Сравниаем с максимально допустимым
rjmp END_PLUS ;|для этого значения часов
sbrc Flags1,fl_Chng_Way ;+ проверяем флаг направления
ldi temp,1 ;|Если флаг установлен загружаем (1-день,число,месяц)
sbrs Flags1,fl_Chng_Way ;+ проверяем флаг направления
clr temp ;|Если флаг сброшен загружаем (0-час,минута,год)
END_PLUS:
st X,temp ;| и возвращаем на место
rcall OUT_Clock_LCD ;/ Выводим на LCD новое значение
pop temp
ret
Plus_Chng:
subi temp,-6 ;|Если в младшей тетраде 0 прибавляем 6)
rjmp SAVE_PLUS
;**************************************************
;* ;;/MINUS DATA;;* *
;**************************************************
Clock_Minus:
push temp
ld temp,X ;| Получаем значение
cpse temp,zero ;| Проеряем на 0-час,минута,год
rjmp PC+2
MOVE_MINUS:
mov temp,rab1 ;| Равны , копируем в temp максимально допустимый предел
add temp,rab ;| Прибавляем константу для счёта в BCD
subi temp,1 ;| Вычитаем единицу
sub temp,rab ;| Вычитаем константу и получаем упакованный BCD
brhs Minus_Chng ;| Проверяем переход с 0->F (заём)
cpse temp,zero ;| Проверяем на 0-день,число,месяц
rjmp END_MINUS
sbrc Flags1,fl_Chng_Way ;+ проверяем флаг направления
;| Если при устан. флаге temp=0, меняем значение на максимально возможное и снова на математику
rjmp MOVE_MINUS
END_MINUS:
st X,temp
rcall OUT_Clock_LCD ;/ Выводим на LCD новое значение
pop temp
ret
Minus_Chng:
subi temp,6 ;| Куда же без числа 6
rjmp END_MINUS
Setting_Clock: .db 0x66,0x24,0x60,8,0x32,0x13,0xA0,00Re: Хитрые, необычные алгоритмы и код
Раз уж зашла речь о часах, во многих процессорах предусмотрены операции для BCD арифметики, что позволяет упростить код. Например, вот так можно увеличивать значения часов H (переменная определённая в RAM) на 1 по модулю 24 в архитектуре 8051 (уменьшение пишется аналогично). Собственно, хитрости в кодах ниже нет - скорее стандартная практика.
Oчень похоже это выглядит в HCS08 и подобных:
У MSP430 можно все сделать прямо в памяти, и, конечно, в регистрах:
Ну и для Кортексов M3/M4. У них нет команд для работы с BCD, но многие операции могут выполняться условно.
Код: Выделить всё
mov A, H ; load H into ACC
add A, #1 ; increment the value
da A ; decimal adjust to BCD
cjne A, #0x24, cont ; is maximum reached?
clr A ; YES - reset A to 0
cont: mov H, A ; save updated valueOчень похоже это выглядит в HCS08 и подобных:
Код: Выделить всё
lda H ; load H into ACC
add #1 ; increment the value
daa A ; decimal adjust to BCD
cbeqa #0x24, rest ; is maximum reached?
bra cont ; NO - continue
rest: clra ; YES - reset A to 0
cont: sta H ; save updated valueУ MSP430 можно все сделать прямо в памяти, и, конечно, в регистрах:
Код: Выделить всё
clrc ; reset C flag
dadd.b #1, &H ; increment H in BCD
cmp.b #0x24, &H ; is maximum reached?
jne cont ; NO - continue
clr.b &H ; YES - reset H to 0
cont: Ну и для Кортексов M3/M4. У них нет команд для работы с BCD, но многие операции могут выполняться условно.
Код: Выделить всё
ldr R1, =H ; R1 = address of H
ldrb R0, [R1] ; R0 = hours
add R0, #1 ; increment the value in R0 mod 24
tst R0, #0x0A ; need decimal adjust?
addne R0, #6 ; YES - do it
cmp R0, #0x24 ; is maximum reached?
moveq R0, #0 ; YES - reset R0 to 0
strb R0, [R1] ; save result in RAMRe: Хитрые, необычные алгоритмы и код
Ser60
Возможно есть смысл (как ранее предлагалось и в этой теме) открыть отдельный раздел, где выкладывать типовые алгоритмы без привязки к конкретной системе команд конкретного МК - в виде пошаговых текстовых описаний (подобия ранних схем алгоритмов начала эры МК/ПК).
А доводку такого шаблона пользователь сможет выполнить самостоятельно уже в привязке к собственному проекту (модель памяти и ресурсов в конкретной задаче с конкретным МК)..?
Весьма неплохая "копилка шаблон-алгоритмов" получиться может, особо если отредактировать в "дружественно-конструктивном" режиме базовые правила описания алгоритмов.

Возможно есть смысл (как ранее предлагалось и в этой теме) открыть отдельный раздел, где выкладывать типовые алгоритмы без привязки к конкретной системе команд конкретного МК - в виде пошаговых текстовых описаний (подобия ранних схем алгоритмов начала эры МК/ПК).
А доводку такого шаблона пользователь сможет выполнить самостоятельно уже в привязке к собственному проекту (модель памяти и ресурсов в конкретной задаче с конкретным МК)..?
Весьма неплохая "копилка шаблон-алгоритмов" получиться может, особо если отредактировать в "дружественно-конструктивном" режиме базовые правила описания алгоритмов.

Re: Хитрые, необычные алгоритмы и код
Неплохая идея. Думаю, будет полезно начинающим и не только. Но мне заниматься ведением этой темы некогда. Если возьмётесь, будет замечательно. Помимо описания алгоритмов может стоит будет привести наброски примеров их реализации под популярные архитектуры. В этом случае мой предыдущий пост будет уместно перенести туда.
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Хитрые, необычные алгоритмы и код
Не знаю, в чём затык с часами. Я сделал поразрядную установку с проверкой (отдельно время, отдельно дата):
десятки дней (0...3), единицы дней (0...9), десятки месяцев (0 или 1), ед. мес (0...9), года (0...99 поразрядно);
Десятки часов (0...2), ед.ч. (0...9), дес. мин. (0...5), ед. мин. (0...9).
десятки дней (0...3), единицы дней (0...9), десятки месяцев (0 или 1), ед. мес (0...9), года (0...99 поразрядно);
Десятки часов (0...2), ед.ч. (0...9), дес. мин. (0...5), ед. мин. (0...9).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- SIM31
- Это не хвост, это антенна
- Сообщения: 1363
- Зарегистрирован: Чт апр 04, 2013 22:22:57
- Откуда: Белгород, РФ
Re: Хитрые, необычные алгоритмы и код
Const14 писал(а):Немного отвлеку вас от текущего обсуждения...
В теме http://radiokot.ru/forum/viewtopic.php?f=61&t=119254 был поднят вопрос об инверсии порядка следования битов в слове на обратное (реверсия слова). Мне посоветовали продублировать ответ в этой теме, что я и делаю.
Первое, что приходит на ум, это реализовать такую функции с помощью цикла с побитовым просмотром исходного слова, однако в
книге Генри Уоррена "Алгоритмические трюки для программистов" можно найти вариант этой операции без использования цикла.
Для реверсии байта функция будет выглядеть следующим образом:Код: Выделить всё
uint8_t ReverseByte(uint8_t b)
{
uint8_t ret;
ret = ((b & 0x55)<<1) | ((b & 0xAA)>>1);
ret = ((ret & 0x33)<<2) | ((ret & 0xCC)>>2);
ret = ((ret & 0x0F)<<4) | ((ret & 0xF0)>>4);
return ret;
А где сдвиг третьего бита?! А ну понятно, он как-то сам хитро сдвигается. Код скорее головоломка забавная. Нагляднее в цикле написать или по простому
Код: Выделить всё
ret = (b<<8)
ret = ret | ((b & 10b)<<6)
ret = ret | ((b & 100b)<<4)
...Хоть в отладчике можно посмотреть что делается, а не каша из бит, но быстрее работает понятно, может на 20%
Re: Хитрые, необычные алгоритмы и код
А вот как это всё выглядит на Cortex M3 и выше...
ret = __REV(__RBIT(b));
Две команды МК... и только...
ret = __REV(__RBIT(b));
Две команды МК... и только...
"Я не даю готовых решений, я заставляю думать!"(С)
Re: Хитрые, необычные алгоритмы и код
А вот есть такой код , не упрощал , ну и если очень приспичит , как мне, то можно пользовать
Код: Выделить всё
add R18,temp
adc R18,R21
brhc yy
subi R18,0x10
sec
xx:
adc R19,temp1
adc R19,r21
brhc YYY
subi R19,0x10
sec
xxx:
adc R20,XL
rjmp xxxx
yy:
subi r18,6
rjmp XX
YYY:
subi r19,6
rjmp XXX Re: Хитрые, необычные алгоритмы и код
Вариант программной "безджиттерной" генерации интервалов на основе векторно - условных переходов.
Как частный случай - генерация пакета для ленты WS2812 c фазовой манипуляцией:
viewtopic.php?p=2858887#p2858887
В принципе позволяет стабилизировать период с точностью до одного командного цикла.
Альтернатива накапливаемой ошибке при применении стандартных команд перехода по условию, для которых существует правило разного времени исполнения в случаях истина или ложь.
Конструкция конечно более громоздкая по количеству команд, зато время выполнения весьма равномерно распределено.

Как частный случай - генерация пакета для ленты WS2812 c фазовой манипуляцией:
viewtopic.php?p=2858887#p2858887
В принципе позволяет стабилизировать период с точностью до одного командного цикла.
Альтернатива накапливаемой ошибке при применении стандартных команд перехода по условию, для которых существует правило разного времени исполнения в случаях истина или ложь.
Конструкция конечно более громоздкая по количеству команд, зато время выполнения весьма равномерно распределено.
- ptr128
- Вымогатель припоя
- Сообщения: 606
- Зарегистрирован: Чт окт 06, 2016 21:12:07
- Откуда: Южное Бутово
Re: Хитрые, необычные алгоритмы и код
Уж не знаю, насколько это хитро, но давно использую для математических вычислений на МК следующее свойство:
1. Если сдвинуть двоичное число на один разряд влево, то это равносильно умножению на два. Это общеизвестно.
2. Если сдвинуть двоичное число на один разряд вправо, то это равносильно делению на два. Это тоже общеизвестно.
3. Если сдвигать двоичное число на один разряд вправо столько раз, сколько нужно, чтобы результат стал равен единице, то это количество раз будет логарифмом по основанию 2 от нашего числа. А про это забывают.
Понятно, что целочисленное заначение логарифма весьма не точно, но когда точность не требуется, позволяет очень быстро выполнять операции возведения в степень или извлечения корня.
1. Если сдвинуть двоичное число на один разряд влево, то это равносильно умножению на два. Это общеизвестно.
2. Если сдвинуть двоичное число на один разряд вправо, то это равносильно делению на два. Это тоже общеизвестно.
3. Если сдвигать двоичное число на один разряд вправо столько раз, сколько нужно, чтобы результат стал равен единице, то это количество раз будет логарифмом по основанию 2 от нашего числа. А про это забывают.
Понятно, что целочисленное заначение логарифма весьма не точно, но когда точность не требуется, позволяет очень быстро выполнять операции возведения в степень или извлечения корня.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Re: Хитрые, необычные алгоритмы и код
Может уже было? Исключительно для собственных протоколов передачи данных.
Многим известно что для защиты целостности передачи данных используется контрольная сумма. В общем случае используют известные методы CRC8,CRC16,CRC32 с разными полиномами. В некоторых контроллерах есть уже встроенные блоки подсчета CRC, но часто нужно самому софтово ее считать. И мне тоже понадобилось.
Физический смысл CRC - циклическая сумма остатков от деления байта (слова) на известный полином (8,16,32 бит). Википедия все красиво описывает. Когда-то я при передаче пакетов USART по воздуху так и писал
crc = (crc+data)%POLINOM;
и в конце пакета добавлял в передачу CRC.
Сам расчет контрольной суммы занимает определенное время, особенно деление. Для ускорения процесса используют таблицы с частным для нужного полинома. Я сейчас использую STM32. Там тоже тратится время на деление, но вот умножение делается за один такт!
Пришла идея заменить деление умножением с отбрасыванием "целой" части и приведением результата к нужному типу данных.
Получилась такая строка для CRC8:
crc = (uint8_t)(0xff & (((uint8_t)(0xff & (crc+data)))*POL));
где POL полином контрольной суммы,задается в дефайнах, у меня 0х31.
Все это компилируется в 5 ассемблерных команд и выполняется примерно за 8 тактов.
Передача проходит четко.
Вот так выглядит обработчик прерывания USART для захвата пакета в 80 байт с преамбулой
void USART1_IRQHandler (void)
{
if (USART1->ISR & USART_ISR_RXNE) data = USART1->RDR;
if (rf_stat == 2)
{
rx_buf[r_ptr] = data;r_ptr++;
if(r_ptr > 80)
{
if (crc == rx_buf[80]) rx_buf_rdy = 1; else rx_buf_rdy = 0;
crc = 0,r_ptr = 0,rf_stat = 0;
} else crc = (uint8_t)(0xff & (((uint8_t)(0xff & (crc+data)))*POL));
} else
if ((rf_stat == 1) && (data == 0xD4)) rf_stat++; else
if ((rf_stat == 0) && (data == 0x2D)) rf_stat++;
};
0x2D и 0xD4 старт пакета,rx_buf_rdy-флаг готовности,rf_stat - статус разбора пакета.
Естественно от устройства с формированием CRC таким-же способом.
Многим известно что для защиты целостности передачи данных используется контрольная сумма. В общем случае используют известные методы CRC8,CRC16,CRC32 с разными полиномами. В некоторых контроллерах есть уже встроенные блоки подсчета CRC, но часто нужно самому софтово ее считать. И мне тоже понадобилось.
Физический смысл CRC - циклическая сумма остатков от деления байта (слова) на известный полином (8,16,32 бит). Википедия все красиво описывает. Когда-то я при передаче пакетов USART по воздуху так и писал
crc = (crc+data)%POLINOM;
и в конце пакета добавлял в передачу CRC.
Сам расчет контрольной суммы занимает определенное время, особенно деление. Для ускорения процесса используют таблицы с частным для нужного полинома. Я сейчас использую STM32. Там тоже тратится время на деление, но вот умножение делается за один такт!
Пришла идея заменить деление умножением с отбрасыванием "целой" части и приведением результата к нужному типу данных.
Получилась такая строка для CRC8:
crc = (uint8_t)(0xff & (((uint8_t)(0xff & (crc+data)))*POL));
где POL полином контрольной суммы,задается в дефайнах, у меня 0х31.
Все это компилируется в 5 ассемблерных команд и выполняется примерно за 8 тактов.
Передача проходит четко.
Вот так выглядит обработчик прерывания USART для захвата пакета в 80 байт с преамбулой
void USART1_IRQHandler (void)
{
if (USART1->ISR & USART_ISR_RXNE) data = USART1->RDR;
if (rf_stat == 2)
{
rx_buf[r_ptr] = data;r_ptr++;
if(r_ptr > 80)
{
if (crc == rx_buf[80]) rx_buf_rdy = 1; else rx_buf_rdy = 0;
crc = 0,r_ptr = 0,rf_stat = 0;
} else crc = (uint8_t)(0xff & (((uint8_t)(0xff & (crc+data)))*POL));
} else
if ((rf_stat == 1) && (data == 0xD4)) rf_stat++; else
if ((rf_stat == 0) && (data == 0x2D)) rf_stat++;
};
0x2D и 0xD4 старт пакета,rx_buf_rdy-флаг готовности,rf_stat - статус разбора пакета.
Естественно от устройства с формированием CRC таким-же способом.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Хитрые, необычные алгоритмы и код
вот здесь я рассказал о своем принципе создания массивов без массивов
ну, то есть когда вы не связаны по рукам и ногам тем, что статический массив целиком располагается в одном файле и невозможно никак задавать входящие в него элементы в разных местах проекта. если подобная проблема вас достала (я о желании перестать помнить о размере массива, о том, в каком файле он определен, о желании наполнять массив по частям в тех местах, где одна из частей понадобилась) - рекомендую почитать.
подход может быть полезен при разработке всяких парсеров или интерпретаторов строк, организации системы меню или иных случаев с обязательным перебором элементов массива для нахождения нужного из имеющихся элементов.
ну, то есть когда вы не связаны по рукам и ногам тем, что статический массив целиком располагается в одном файле и невозможно никак задавать входящие в него элементы в разных местах проекта. если подобная проблема вас достала (я о желании перестать помнить о размере массива, о том, в каком файле он определен, о желании наполнять массив по частям в тех местах, где одна из частей понадобилась) - рекомендую почитать.
подход может быть полезен при разработке всяких парсеров или интерпретаторов строк, организации системы меню или иных случаев с обязательным перебором элементов массива для нахождения нужного из имеющихся элементов.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- SIM31
- Это не хвост, это антенна
- Сообщения: 1363
- Зарегистрирован: Чт апр 04, 2013 22:22:57
- Откуда: Белгород, РФ
Re: Хитрые, необычные алгоритмы и код
[uquote="Sergi",url="/forum/viewtopic.php?p=3571426#p3571426"]Может уже было? Исключительно для собственных протоколов передачи данных.
Многим известно что для защиты целостности передачи данных используется контрольная сумма. В общем случае используют известные методы CRC8,CRC16,CRC32 с разными полиномами. В некоторых контроллерах есть уже встроенные блоки подсчета CRC, но часто нужно самому софтово ее считать. И мне тоже понадобилось.[/uquote]
Еще проще просто сумма, качество обнаружения ошибки падает, но не критично, я проверял, зато какая простота
https://habr.com/ru/post/278171/
CRC полноценная кстати не намного дольше считается. Там деление вырождается в 8 операций смещения бита вправо и 8 опраций XOR.
Как я понимаю смотрим младший бит, если он 1 то делаем XOR с полиномом. Потом смотрим предпоследний бит, и если он 1 то делаем XOR с полиномом.
https://ru.wikipedia.org/wiki/%D0%A6%D0 ... 0%BE%D0%B4

Вот если бы считали 16 или 32 бит контрольную сумму, тут выигрыш был бы значительным.
И проверки алгоритма у вас нет, нужно собрать статистику, имитируая передачу миллиона сбойных пакетов, с 1,2,3..10 сбойными битами. Может полином быть выбран неудачно.
Многим известно что для защиты целостности передачи данных используется контрольная сумма. В общем случае используют известные методы CRC8,CRC16,CRC32 с разными полиномами. В некоторых контроллерах есть уже встроенные блоки подсчета CRC, но часто нужно самому софтово ее считать. И мне тоже понадобилось.[/uquote]
Еще проще просто сумма, качество обнаружения ошибки падает, но не критично, я проверял, зато какая простота
https://habr.com/ru/post/278171/
CRC полноценная кстати не намного дольше считается. Там деление вырождается в 8 операций смещения бита вправо и 8 опраций XOR.
Как я понимаю смотрим младший бит, если он 1 то делаем XOR с полиномом. Потом смотрим предпоследний бит, и если он 1 то делаем XOR с полиномом.
https://ru.wikipedia.org/wiki/%D0%A6%D0 ... 0%BE%D0%B4

Вот если бы считали 16 или 32 бит контрольную сумму, тут выигрыш был бы значительным.
И проверки алгоритма у вас нет, нужно собрать статистику, имитируая передачу миллиона сбойных пакетов, с 1,2,3..10 сбойными битами. Может полином быть выбран неудачно.