Например TDA7294

Форум РадиоКот • Просмотр темы - Хитрые, необычные алгоритмы и код
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Чт мар 28, 2024 18:58:55

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 210 ]     ... , , , 7, , , ,  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вс авг 09, 2015 15:21:57 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2057
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18024
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
честно говоря, вы тут слишком много понаписали и все запутали.

1 измерение АЦП это максимум 1023. 100 измерений в секунду за час дадут сумму максимум 1023*60*60*100=368280000 это unsigned long. эта переменная сможет накапливать ваши измерения в течение 11 часов максимум, потом переполнится.

нет никакой проблемы суммировать и сравнивать unsigned long для 8-битного МК.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

скушно, бабоньки!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн авг 10, 2015 05:03:36 
Опытный кот

Карма: -3
Рейтинг сообщений: 13
Зарегистрирован: Вс июн 02, 2013 12:23:03
Сообщений: 822
Рейтинг сообщения: 0
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.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн авг 10, 2015 07:00:31 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4510
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
amd9800 писал(а):
с такой огромной переменной это нагрузка на MK
Госпадяяяя... какая же это нагрузка - сравнение, вычитание, сложение, ... ? Тем более с константами :facepalm:
Делайте long и не парьтесь...

PS: Вы делаете проблему буквально из ничего. Что в этой теме, что в других. Вы, для начала, сделайте, а потом когда проблема появится - будете уже её решать.


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн авг 10, 2015 08:57:41 
Родился

Зарегистрирован: Чт авг 06, 2015 09:38:22
Сообщений: 17
Рейтинг сообщения: 0
Немного отвлеку вас от текущего обсуждения...

В теме 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;
}


Вернуться наверх
 
Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн авг 10, 2015 11:32:58 
Друг Кота

Карма: 64
Рейтинг сообщений: 964
Зарегистрирован: Пт мар 07, 2008 06:54:43
Сообщений: 4210
Откуда: Ижевск
Рейтинг сообщения: 0
amd9800 писал(а):
цифра которая видна на экране состоит из 2 переменных.
значение до запятой это 1-я переменная типа int - будет цифра на пределе инта = 65535
значение после запятой это 2-ая переменная типа char - будет цифра от 0 до 99
также в бэкграунде будет 3-ая переменная в которую будут суммироваться значения АЦП...
По мне, гораздо проще объявить 1 переменную ΣCODE как 32 разрядную и результат получать по выражению 100*RES=ΣCODE/K, где
100 - число измерений в единицу времени
K - коэффициент преобразования.
Децимальную точку принудительно ставить после единиц. Например K=130, т.е. 1A соответствует значение 130 единиц АЦП и входном токе 7.86А в сумматоре ΣCODE должно накопиться
7.86*130*100=102180 и 100*RES=ΣCODE/K=102180/130=786
Можно избавиться от операции деления на константу, заменив её умножением. В данном случае разрядность ΣCODE не изменится.


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн авг 10, 2015 21:20:30 
Опытный кот

Карма: -3
Рейтинг сообщений: 13
Зарегистрирован: Вс июн 02, 2013 12:23:03
Сообщений: 822
Рейтинг сообщения: 0
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++;
             }
          }   
         }


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Сб авг 15, 2015 05:08:08 
Опытный кот
Аватар пользователя

Карма: 13
Рейтинг сообщений: 163
Зарегистрирован: Сб дек 22, 2012 08:17:42
Сообщений: 744
Откуда: Караганда, Казахстан
Рейтинг сообщения: 2
Const14 писал(а):
Немного отвлеку вас от текущего обсуждения...

В теме http://radiokot.ru/forum/viewtopic.php?f=61&t=119254 был поднят вопрос об инверсии порядка следования битов в слове на обратное (реверсия слова). Мне посоветовали продублировать ответ в этой теме, что я и делаю.

Первое, что приходит на ум, это реализовать такую функции с помощью цикла с побитовым просмотром исходного слова, однако в
книге Генри Уоррена "Алгоритмические трюки для программистов" можно найти вариант этой операции без использования цикла.
Да, на Си оно выглядит довольно красиво. Однако, как мне кажется, реализация этого дела займет гораздо больше 16 машинных команд того же АВР. Тогда, как банальное повторение 8 раз пары команд rol r0 ror r1 легко и непринужденно вывернет наизнанку содержимое R0 и поместит его в R1. Про 8051 не скажу, не знаю я его, но, даже если у него есть сдвиги на заданное число разрядов, а не на один, все равно все это довольно сложно, в отличие от

_________________
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Сб сен 05, 2015 20:22:04 
Держит паяльник хвостом
Аватар пользователя

Карма: 15
Рейтинг сообщений: 70
Зарегистрирован: Ср мар 28, 2012 21:45:24
Сообщений: 904
Откуда: ВО
Рейтинг сообщения: 0
Вот так можно менять значения установки часов для серии DS1307 - DS3232M, не прибегая к таблицам, и BCD->HEX->BCD
В 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,00


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Сб сен 05, 2015 23:41:46 
Друг Кота
Аватар пользователя

Карма: 74
Рейтинг сообщений: 607
Зарегистрирован: Ср дек 24, 2008 09:58:58
Сообщений: 3707
Рейтинг сообщения: 0
Медали: 3
Мявтор 1-й степени (1) Мявтор 2-й степени (1) Мявтор 3-й степени (1)
Раз уж зашла речь о часах, во многих процессорах предусмотрены операции для BCD арифметики, что позволяет упростить код. Например, вот так можно увеличивать значения часов H (переменная определённая в RAM) на 1 по модулю 24 в архитектуре 8051 (уменьшение пишется аналогично). Собственно, хитрости в кодах ниже нет - скорее стандартная практика.
Код:
      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 value

Oчень похоже это выглядит в 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 RAM


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вс сен 06, 2015 06:36:16 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1349
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14018
Откуда: ДОНЕЦК
Рейтинг сообщения: 1
Ser60
Возможно есть смысл (как ранее предлагалось и в этой теме) открыть отдельный раздел, где выкладывать типовые алгоритмы без привязки к конкретной системе команд конкретного МК - в виде пошаговых текстовых описаний (подобия ранних схем алгоритмов начала эры МК/ПК).
А доводку такого шаблона пользователь сможет выполнить самостоятельно уже в привязке к собственному проекту (модель памяти и ресурсов в конкретной задаче с конкретным МК)..?
:roll:
Весьма неплохая "копилка шаблон-алгоритмов" получиться может, особо если отредактировать в "дружественно-конструктивном" режиме базовые правила описания алгоритмов.
:beer:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вс сен 06, 2015 07:08:48 
Друг Кота
Аватар пользователя

Карма: 74
Рейтинг сообщений: 607
Зарегистрирован: Ср дек 24, 2008 09:58:58
Сообщений: 3707
Рейтинг сообщения: 0
Медали: 3
Мявтор 1-й степени (1) Мявтор 2-й степени (1) Мявтор 3-й степени (1)
Неплохая идея. Думаю, будет полезно начинающим и не только. Но мне заниматься ведением этой темы некогда. Если возьмётесь, будет замечательно. Помимо описания алгоритмов может стоит будет привести наброски примеров их реализации под популярные архитектуры. В этом случае мой предыдущий пост будет уместно перенести туда.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн сен 07, 2015 09:28:00 
Друг Кота
Аватар пользователя

Карма: 67
Рейтинг сообщений: 1012
Зарегистрирован: Чт сен 18, 2008 12:27:21
Сообщений: 18778
Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Не знаю, в чём затык с часами. Я сделал поразрядную установку с проверкой (отдельно время, отдельно дата):
десятки дней (0...3), единицы дней (0...9), десятки месяцев (0 или 1), ед. мес (0...9), года (0...99 поразрядно);
Десятки часов (0...2), ед.ч. (0...9), дес. мин. (0...5), ед. мин. (0...9).

_________________
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Измерить нннада?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вс окт 11, 2015 21:09:01 
Это не хвост, это антенна
Аватар пользователя

Карма: 17
Рейтинг сообщений: 12
Зарегистрирован: Чт апр 04, 2013 22:22:57
Сообщений: 1356
Откуда: Белгород, РФ
Рейтинг сообщения: 0
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: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пт дек 25, 2015 17:09:47 
Друг Кота

Карма: -18
Рейтинг сообщений: 29
Зарегистрирован: Вс дек 05, 2010 06:10:34
Сообщений: 4583
Откуда: ЮВ
Рейтинг сообщения: 0
А вот как это всё выглядит на Cortex M3 и выше...

ret = __REV(__RBIT(b));

Две команды МК... и только...

_________________
"Я не даю готовых решений, я заставляю думать!"(С)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн дек 28, 2015 22:32:45 
Держит паяльник хвостом
Аватар пользователя

Карма: 15
Рейтинг сообщений: 70
Зарегистрирован: Ср мар 28, 2012 21:45:24
Сообщений: 904
Откуда: ВО
Рейтинг сообщения: 0
А вот есть такой код , не упрощал , ну и если очень приспичит , как мне, то можно пользовать
Код:
   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: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Чт сен 15, 2016 23:38:20 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1349
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14018
Откуда: ДОНЕЦК
Рейтинг сообщения: 3
Вариант программной "безджиттерной" генерации интервалов на основе векторно - условных переходов.
Как частный случай - генерация пакета для ленты WS2812 c фазовой манипуляцией:
viewtopic.php?p=2858887#p2858887
В принципе позволяет стабилизировать период с точностью до одного командного цикла.
Альтернатива накапливаемой ошибке при применении стандартных команд перехода по условию, для которых существует правило разного времени исполнения в случаях истина или ложь.
Конструкция конечно более громоздкая по количеству команд, зато время выполнения весьма равномерно распределено.
:roll:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Ср окт 12, 2016 09:12:39 
Вымогатель припоя
Аватар пользователя

Карма: 19
Рейтинг сообщений: 230
Зарегистрирован: Чт окт 06, 2016 21:12:07
Сообщений: 606
Откуда: Южное Бутово
Рейтинг сообщения: 3
Уж не знаю, насколько это хитро, но давно использую для математических вычислений на МК следующее свойство:
1. Если сдвинуть двоичное число на один разряд влево, то это равносильно умножению на два. Это общеизвестно.
2. Если сдвинуть двоичное число на один разряд вправо, то это равносильно делению на два. Это тоже общеизвестно.
3. Если сдвигать двоичное число на один разряд вправо столько раз, сколько нужно, чтобы результат стал равен единице, то это количество раз будет логарифмом по основанию 2 от нашего числа. А про это забывают.

Понятно, что целочисленное заначение логарифма весьма не точно, но когда точность не требуется, позволяет очень быстро выполнять операции возведения в степень или извлечения корня.

_________________
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Сб фев 16, 2019 15:32:24 
Потрогал лапой паяльник

Карма: 5
Рейтинг сообщений: 44
Зарегистрирован: Ср янв 04, 2012 11:57:40
Сообщений: 394
Откуда: Алчевск
Рейтинг сообщения: 2
Может уже было? Исключительно для собственных протоколов передачи данных.
Многим известно что для защиты целостности передачи данных используется контрольная сумма. В общем случае используют известные методы 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 таким-же способом.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вт фев 26, 2019 07:02:59 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2057
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18024
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
вот здесь я рассказал о своем принципе создания массивов без массивов :)
ну, то есть когда вы не связаны по рукам и ногам тем, что статический массив целиком располагается в одном файле и невозможно никак задавать входящие в него элементы в разных местах проекта. если подобная проблема вас достала (я о желании перестать помнить о размере массива, о том, в каком файле он определен, о желании наполнять массив по частям в тех местах, где одна из частей понадобилась) - рекомендую почитать.

подход может быть полезен при разработке всяких парсеров или интерпретаторов строк, организации системы меню или иных случаев с обязательным перебором элементов массива для нахождения нужного из имеющихся элементов.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

скушно, бабоньки!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вт фев 26, 2019 11:43:48 
Это не хвост, это антенна
Аватар пользователя

Карма: 17
Рейтинг сообщений: 12
Зарегистрирован: Чт апр 04, 2013 22:22:57
Сообщений: 1356
Откуда: Белгород, РФ
Рейтинг сообщения: 0
Может уже было? Исключительно для собственных протоколов передачи данных.
Многим известно что для защиты целостности передачи данных используется контрольная сумма. В общем случае используют известные методы CRC8,CRC16,CRC32 с разными полиномами. В некоторых контроллерах есть уже встроенные блоки подсчета CRC, но часто нужно самому софтово ее считать. И мне тоже понадобилось.


Еще проще просто сумма, качество обнаружения ошибки падает, но не критично, я проверял, зато какая простота
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 сбойными битами. Может полином быть выбран неудачно.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 210 ]     ... , , , 7, , , ,  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y