Например TDA7294

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





Текущее время: Вт апр 16, 2024 21:33:32

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


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



Начать новую тему Ответить на тему  [ Сообщений: 210 ]    , , , , 5, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вс сен 08, 2013 17:03:09 
Мудрый кот
Аватар пользователя

Карма: 24
Рейтинг сообщений: 286
Зарегистрирован: Чт июн 10, 2010 08:55:35
Сообщений: 1810
Откуда: Сибирские Афины
Рейтинг сообщения: 0
*Trigger*, способ получить ещё одно внешнее прерывание, конечно, не "прямой" :) , но интересный.
Однако, в вашем случае больше ни для чего нельзя использовать таймер. Что может быть весьма неудобно.
Я бы сказал, есть путь "прямее" :) и, к тому же, таймер можно использовать для чего-то другого.
Цитата из спека на мегу8:
Цитата:
Bit 6 – ICES1: Input Capture Edge Select
This bit selects which edge on the Input Capture Pin (ICP1) that is used to trigger a capture
event. When the ICES1 bit is written to zero, a falling (negative) edge is used as trigger, and
when the ICES1 bit is written to one, a rising (positive) edge will trigger the capture.
When a capture is triggered according to the ICES1 setting, the counter value is copied into the
Input Capture Register (ICR1). The event will also set the Input Capture Flag (ICF1), and this
can be used to cause an Input Capture Interrupt, if this interrupt is enabled.

Т.е. на основе Input Capture можно получить ещё одно внешнее прерывание с сохранением, так сказать, таймера.
Прерывание будет Timer/Counter1 Capture Event (TIMER1 CAPT).

_________________
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)


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

Карма: 81
Рейтинг сообщений: 1377
Зарегистрирован: Пн май 11, 2009 14:15:00
Сообщений: 3059
Откуда: СПб
Рейтинг сообщения: 0
Медали: 1
Мявтор 3-й степени (1)
Да, действительно. Что-то я про захват забыл. Но можно использовать их одновременно, получив ещё два прерывания.

_________________
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Сб окт 12, 2013 19:36:30 
Друг Кота

Карма: 64
Рейтинг сообщений: 966
Зарегистрирован: Пт мар 07, 2008 06:54:43
Сообщений: 4220
Откуда: Ижевск
Рейтинг сообщения: 0
Месяц прошёл - можно поднять тему :wink: На неделе понадобился большой-пребольшой линейный счётчик с выводом на индикатор. Как нельзя лучше подошёл алгоритм ILYAUL приведённый в этой теме. Может ещё кому понадобится.
Вложение:
count_bcd.asm


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

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

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Ср фев 12, 2014 03:18:18 
Друг Кота

Карма: 64
Рейтинг сообщений: 966
Зарегистрирован: Пт мар 07, 2008 06:54:43
Сообщений: 4220
Откуда: Ижевск
Рейтинг сообщения: 0
Здравствуйте. Недавно, на соседнем форуме был задан вопрос о быстром умножении 24-разрядных чисел. Было предложено использование алгоритма Дональда Кнута. В результате появился код, который выполняет
Умножение 24р*24р=48р выполняется за 75 тактов и занимает 65 слов
Умножение 32р*32р=64р выполняется за 134 такта и занимает 117 слов
Формат представления чисел старший-младший
Вложение:
MULT_KNUTH.zip


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пт фев 14, 2014 12:18:45 
Друг Кота
Аватар пользователя

Карма: 67
Рейтинг сообщений: 1012
Зарегистрирован: Чт сен 18, 2008 12:27:21
Сообщений: 18798
Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Задумался я о выводе текста на графическом дисплее (например, WS0010).
Например, нарисовали шрифты 5×8 точек (5 байт на символ) — 32 буквы (без "ё") или 31 (без "ё" и "ъ", но с пробелом) чтобы уложиться в 5 бит.
Или нарисовать весь алфавит, цифры и символы — всего 64 знака, т.е. 6 бит кодируют символ. Куда применить остальные 2 или 3 бита?
СпойлерМожно, конечно, извратиться и кодировать текст, пихая биты подряд, не привязываясь к байтам:
0b11111122 0b22223333 0b33444444
Но это сложно как с точки зрения кодирования, так и с т.з. реализации функции вывода. Очевидно, проще так:
0b00111111 0b00222222 0b00333333 0b00444444,
где 1, 2, 3 и 4 — соответственно первый, второй, третий и четвёртый символ (буква)

Ответ прост: «архивировать» (кодировать) ещё один символ! Но не любой, а только 3 или 7 наиболее часто встречающихся. В русском языке (согласно http://ru.wikipedia.org/wiki/Частотность ) это (в порядке убывания частоты) «О», «Е», «А», «И», «Н», «Т», «С».
Например, сделаем в таблице шрифтов (32 символа, т.е. 5 информационных бит и 3 дополнительных) так, чтобы у буквы «О» было условное смещение в таблице = 1, у «Е» = 2 и т.д., т.е. вынесем их в начало таблицы. Тогда слово «НЕТ» в памяти программ без «архивации» будет занимать 3 байта:
0b00000101 0b00000010 0b00000110,
а с данным алгоритмом — всего 2:
0b01000101 0b00000110,
здесь буква «Е» переехала в старшие 2 бита буквы «Н». Экономия места в памяти программ (ПП)!
Причём сама функция вывода усложнилась совсем чуть-чуть. Если раньше было (5+3 бит)
Код:
1. считали байт из ПП
2. вызвали процедуру печати символа
3. уменьшили (декремент) счётчик
4. переход к п.1, если не ноль

, то стало
Код:
1. считали байт из ПП
2. скопировали его
3. маскируем его (лог. «И») с 0b00011111
4. вызвали процедуру печати символа
5. проверили копию на наличие ещё одного символа
// если все 3 старшие биты нулевые — второго символа в данном байте нет
// проще всего организовать через сравнение с константой 0b00011111
6. переход к п.10, если второго символа нет
7. иначе переместили старшие 3 бита в младшие
// например, через обмен тетрадами и сдвиг вправо
8. маскировали его (лог. «И») с 0b00000111
9. вызвали процедуру печати символа
10. уменьшили (декремент) счётчик
11. переход к п.1, если не ноль

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


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

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

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Сб май 03, 2014 17:44:19 
Открыл глаза
Аватар пользователя

Карма: 1
Рейтинг сообщений: 10
Зарегистрирован: Пт янв 10, 2014 02:05:13
Сообщений: 52
Откуда: Воронеж
Рейтинг сообщения: 0
Рисование линий. Улучшенный алгоритм Брезенхема. В зависимости от направления рисования код делится на восемь подалгоритмов. Но сами по себе они проще, чем у Брезенхема, операций в цикле меньше, а значит, должно работать быстрее. Функцию plot() реализуем сами, как хочется.

Спойлер
Код:
#define DIR_LRTB   0   // LEFT  to RIGHT, TOP    to BOTTOM
#define DIR_RLTB   1   // RIGHT to LEFT,  TOP    to BOTTOM
#define DIR_LRBT   2   // LEFT  to RIGHT, BOTTOM to TOP
#define DIR_RLBT   3   // RIGHT to LEFT,  BOTTOM to TOP

void draw_line(int x0, int y0, int x1, int y1, int c)
{
   int x,y,dx,dy,s;
   char d=0;
   x=x0; y=y0;
   if(x0>x1){d|=1;dx=x0-x1;}else{dx=x1-x0;}
   if(y0>y1){d|=2;dy=y0-y1;}else{dy=y1-y0;}
   switch(d)
   {
   case DIR_LRTB:
         if(dy>dx)
         {
            for(s=dx;y<=y1;y++)
            {
               plot(x,y,c);
               s+=dx;
               if(s>=dy){x++;s-=dy;}
            }
         } else
         {
            for(s=dy;x<=x1;x++)
            {
               plot(x,y,c);
               s+=dy;
               if(s>=dx){y++;s-=dx;}
            }
         }
         break;
   case DIR_RLTB:
         if(dy>dx)
         {
            for(s=dx;y<=y1;y++)
            {
               plot(x,y,c);
               s+=dx;
               if(s>=dy){x--;s-=dy;}
            }
         } else
         {
            for(s=dy;x>=x0;x--)
            {
               plot(x,y,c);
               s+=dy;
               if(s>=dx){y++;s-=dx;}
            }
         }
         break;
   case DIR_LRBT:
         if(dy>dx)
         {
            for(s=dx;y>=y0;y--)
            {
               plot(x,y,c);
               s+=dx;
               if(s>=dy){x++;s-=dy;}
            }
         } else
         {
            for(s=dy;x<=x1;x++)
            {
               plot(x,y,c);
               s+=dy;
               if(s>=dx){y--;s-=dx;}
            }
         }
         break;
   case DIR_RLBT:
         if(dy>dx)
         {
            for(s=dx;y>=y0;y--)
            {
               plot(x,y,c);
               s+=dx;
               if(s>=dy){x--;s-=dy;}
            }
         } else
         {
            for(s=dy;x>=x0;x--)
            {
               plot(x,y,c);
               s+=dy;
               if(s>=dx){y--;s-=dx;}
            }
         }
         break;
   }
}


P.S. Код ещё будет дорабатываться.


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

Карма: 28
Рейтинг сообщений: 756
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Сообщений: 2893
Откуда: приходит весна?
Рейтинг сообщения: 5
Небольшое исхищрение на тему экономии регистров МК.

Идея возникла в связи вот с какой задачей. Есть внешний цикл на 12 итераций (12 = 0x0C). Счётчик итераций умещается в пол-байта. И есть внутренний цикл на чуть более, чем 256 итераций (в моём случае 484 = 0x01E4). Счётчик итераций внутреннего цикла в байт ну никак не умещается, а второй регистр заводить для него жаба давит. Какой выход? Правильно! Уместить неуместившиеся разряды внутреннего счётчика в свободные разряды внешнего счётчика.

Сначала вариант "цивилизованного" кода, использующего все 3 регистра для счётчиков:
Код:
;               {...}
;               {делаем что-нибудь}
;               {...}
                ldi     r20,    0x0C    ;   Инициализация внешнего счётчика
outer_loop:
;               {...}
;               {содержимое внешнего цикла}
;               {...}
                ldi     r18,    0xE4    ;   Инициализация внутреннего счётчика
                ldi     r19,    0x01    ;   То, что не поместилось в байт
inner_loop:
;               {...}
;               {содержимое внутреннего цикла}
;               {...}
                dec     r18             ;   Уменьшаем внутренний счётчик
                brne    inner_loop
                dec     r19             ;   Тоже внутренний счётчик
                brne    inner_loop
                dec     r20             ;   Уменьшаем внешний счётчик
                brne    outer_loop
;               {...}
;               {делаем ещё что-нибудь}
;               {...}


А теперь экономный вариант с использованием всего 2-х регистров:
Код:
;               {...}
;               {делаем что-нибудь}
;               {...}
                ldi     r19,    0x0C    ;   Инициализация внешнего счётчика
outer_loop:
;               {...}
;               {содержимое внешнего цикла}
;               {...}
                ldi     r18,    0xE4    ;   Инициализация внутреннего счётчика
                ori     r19,    0xE0    ;   То, что не поместилось в байт
                                        ;   Величина, помещаемая в старший полубайт
                                        ;   вычисляется по формуле y = 0xF - x
                                        ;   В моём случае x=0x1, поэтому y=0xE
inner_loop:
;               {...}
;               {содержимое внутреннего цикла}
;               {...}
                dec     r18             ;   Уменьшаем внутренний счётчик
                brne    inner_loop
                subi    r19,    0xF0    ;   Тоже внутренний счётчик
                                        ;   Выполнение этой команды увеличивает
                                        ;   старший полубайт регистра r16 на 0x1,
                                        ;   при этом флаг переноса уставлен, кроме случая,
                                        ;   когда старший полубайт оказывается равным 0x0
                brcs    inner_loop
                dec     r19             ;   Уменьшаем внешний счётчик
                brne    outer_loop
;               {...}
;               {делаем ещё что-нибудь}
;               {...}

Как можно заметить, количество инструкций не увеличилось, за то уменьшилось число используемых разрядов. Правда, достигнуто это ценой усложнения программы для понимания. Однако, есть и другая, эстетическая сторона: разнообразился состав используемых инструкций МК. То была связка ldi / dec / brne, а теперь к ним добавились команды ori / subi / brcs.

Это ухищрение обладает достаточно большой гибкостью. Если бы количество итераций внешнего цикла умещалось бы в 3 бита, то целых 13 бит можно было бы использовать для счётчика внутреннего цикла. С другой стороны, если когда для внутреннего цикла требуется 9 бит как в моём случае, то для счётчика внешнего цикла можно использовать целых 7 бит сдвоенного регистра. Модификация требует всего лишь правильно задать значения констант.

Более того, в случае 7/9 (как у меня) можно сэкономить ещё и на одной инструкции МК — на инициализации самого старшего бита внутреннего счётчика, так как его инвертированное значение на входе во внутренний цикл всегда равно нулю, что и требуется. Я же в своей программе этого делать не стал, так как у меня может возникнуть необходимость увеличить число итераций внутреннего цикла.

Вот ещё один, чуть более человечный вариант:
Спойлер
Код:
;               {...}
;               {делаем что-нибудь}
;               {...}
                ldi     r19,    0x0C    ;   Инициализация внешнего счётчика
outer_loop:
;               {...}
;               {содержимое внешнего цикла}
;               {...}
                ldi     r18,    0xE4    ;   Инициализация внутреннего счётчика
                ori     r19,    0x10    ;   То, что не поместилось в байт
inner_loop:
;               {...}
;               {содержимое внутреннего цикла}
;               {...}
                dec     r18             ;   Уменьшаем внутренний счётчик
                brne    inner_loop
                subi    r19,    0x10    ;   Тоже внутренний счётчик
                brcс    inner_loop
                subi    r19,    0xF1    ;   Уменьшаем внешний счётчик
                brne    outer_loop
;               {...}
;               {делаем ещё что-нибудь}
;               {...}

Интересно, а компилятор Си умеет делать такую оптимизацию?


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

Карма: 4
Рейтинг сообщений: 6
Зарегистрирован: Вт май 08, 2012 23:15:45
Сообщений: 81
Откуда: Санкт - Петербург
Рейтинг сообщения: 0
Цитата:
внутренний цикл на чуть более, чем 256 итераций (в моём случае 484 = 0x01E4).

Расположить две итерации внутреннего цикла друг за другом, тем более что у Вас количество чётное. Счетчик станет 242.


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

Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52
Сообщений: 4470
Откуда: Главный Улей России (Moscow)
Рейтинг сообщения: 1
Когда нужно вернуться из процедуры или прерывания в другую точку программы,
можно сделать так:

Код:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; STACK HACK FOR AVR                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.include "m8def.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dseg
.org         (RAMEND - 1)
st_ret_h:    .byte     1
st_ret_l:    .byte     1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.cseg
.org 0x0000
            rjmp    RESET

.org         INT_VECTORS_SIZE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RESET:        ldi        r16,            Low(RAMEND)
            ldi        r17,            High(RAMEND)
            out        SPL,            r16
            out        SPH,            r17

            rcall    TEST

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LX:            rjmp    LX

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LOOP:        rjmp    LOOP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TEST:        ldi     r16,             Low(LOOP)
            sts     st_ret_l,         r16
            ldi        r16,            High(LOOP)
            sts        st_ret_h,        r16
            ret



После возвращения из процедуры TEST, мы должны попасть в цикл LX, если не шаманить со стеком.
Но мы попадаем в цикл LOOP, так как переписали в стеке адрес возврата напрямую.
То есть, без использования инструкций PUSH / POP. Единственное, что не надо забывать при таком
приеме, это вытащить предварительно все данные, вручную помещенные в стек.

_________________
I am DX168B and this is my favourite forum on internet!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пн авг 25, 2014 07:24:49 
Ум, честь и совесть. И скромность.
Аватар пользователя

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

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

Мой уютный бложик... заходите!


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

Карма: 32
Рейтинг сообщений: 234
Зарегистрирован: Пт янв 29, 2010 10:27:40
Сообщений: 3851
Откуда: Москва
Рейтинг сообщения: 1
...причем в случае с AVR можно задать 7 различных делителей тактовой для АЦП и получить "нестандартные" для обычных таймеров (кроме режимов CTC) периоды в 13, 26, 52, 104, 208, 416, 832 и 1664 такта.

_________________
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Вт авг 26, 2014 10:34:32 
Друг Кота
Аватар пользователя

Карма: 67
Рейтинг сообщений: 1012
Зарегистрирован: Чт сен 18, 2008 12:27:21
Сообщений: 18798
Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
ARV писал(а):
АЦП отлично может функционировать в качестве дополнительного таймера с фиксированным периодом счета...

Хм... А какой-нить УАРТ/И²С/СПИ тоже ведь так можно настроить?

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


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

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Gudd-Head писал(а):
ARV писал(а):
АЦП отлично может функционировать в качестве дополнительного таймера с фиксированным периодом счета...

Хм... А какой-нить УАРТ/И²С/СПИ тоже ведь так можно настроить?
:))) можно, но...
...это будет "однократный" таймер, который в обработчике прерываний придется перезапускать
...этот "таймер" будет гадить на внешних линиях ввода-вывода

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

Мой уютный бложик... заходите!


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

Карма: 67
Рейтинг сообщений: 1012
Зарегистрирован: Чт сен 18, 2008 12:27:21
Сообщений: 18798
Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
ARV писал(а):
...это будет "однократный" таймер, который в обработчике прерываний придется перезапускать

Ну, 1-2 команды для запуска, думаю, не критично.
ARV писал(а):
...этот "таймер" будет гадить на внешних линиях ввода-вывода

Это да. А вот у АЦП, если мультиплексором выбрать такую комбинацию бит, которым ничего не соответствует в ДШ будет нормально работать? И не задействует никакую ногу? (напр., MUX3:0 = 1000...1101 для 8-й меги). Если так, то это преимущество использования АЦП.

Зато УАРТ более гибкий в плане временного периода прерывания: ≈ Fтакт/(16*UBRR), где UBRR 12 бит у 8-й меги, т.е. можно получить частоту Fтакт/32 000.

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


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

Карма: 32
Рейтинг сообщений: 234
Зарегистрирован: Пт янв 29, 2010 10:27:40
Сообщений: 3851
Откуда: Москва
Рейтинг сообщения: 0
Gudd-Head писал(а):
А вот у АЦП, если мультиплексором выбрать такую комбинацию бит, которым ничего не соответствует в ДШ будет нормально работать? И не задействует никакую ногу?

Практически у всех AVR (ну может кроме t13) есть комбинации для подключения мультиплексора на землю/опорное напряжение/внутренний термодатчик, так что думаю прокатит. Хотя я, как раз когда использовал этот прием в t13 тупо скоммутировал ногу, которая была цифровым входом...

_________________
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)


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

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

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

Мой уютный бложик... заходите!


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

Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52
Сообщений: 4470
Откуда: Главный Улей России (Moscow)
Рейтинг сообщения: 0
Еще один прием.
Допустим, у нас есть 100 команд и 100 действий.
Команды идут подряд (от нуля до 99)
К примеру приняли пакет по UART с адресом, командой, данными и CRC.
Команду надо как-то обработать. Длинный swith в Си или cpi r16, CMDx не канает, так как ест много тактов и памяти.
Но есть другое решение.

Вариант на Си:
Код:


#include <avr\io.h>
#include <util\delay.h>
#include <avr\pgmspace.h>

typedef int(*myFunc)(void);

int func1(void);
int func2(void);
int func3(void);

myFunc fArr[3] = {func1, func2, func3};

//----------
int main()
    {
        while(1)
        {
            for(int i = 0; i < 3; i++)
            {
                fArr[i]();
            }
        }
    }
//----------
int func1(void)
{
    PORTB=0x01;
    return 0;
}

int func2(void)
{
    PORTB=0x02;
    return 0;
}

int func3(void)
{
    PORTB=0x04;
    return 0;
}
 


В данном примере вызываются три функции по очереди. Если вместо индекса i
подставить значение команды, то вызовется соответствующая функция.

То же самое на АСМе: (выдран из рабочего проекта)

Код:
;---------- Адреса процедур
HANDLERS:
.dw MPT, RSTCFG, OPNCFG, MENUCFG, LIGHT_CFG, US_OV, STAT_CFG, SENS_CFG, CLR_CFG, MASTERCFG


;---------- конфигурации
CONFIG:
rcall         KEYREQ ;Опрос клавиатуры
cpi           temp0,            _NO_BT ; ничего не нажато (0xFF)
breq          CONFIG
cpi           temp0,            _CLR ;нажата кнопка "Сброс" (0x0F)
breq          CFGEND
cpi           temp0,            _A ; нажаты кнопки от А до Enter (всего 16 кнопок. 0...9, A, B, C, D, Enter, CLR) = (0x00...0x0F)
brsh          CFGERR
ldi           ZL,               Low(HANDLERS*2) ; нажаты кнопки от 0 до 9
ldi           ZH,               High(HANDLERS*2) ; соответственно, выбран один из пунктов меню. Загружаем адрес начала массива адресов процедур
lsl           temp0 ; Из-за типичной для AVR организации памяти, приходится домножать номер процедуры на два простым сдвигом влево.
clr           temp1
add           ZL,               temp0 ;смещаемся до нужного элемента массива
adc           ZH,               temp1
lpm           dx2,              Z ; грузим адрес из массива
adiw          Z,                0x01
lpm           dx3,              Z
mov           ZL,               dx2
mov           ZH,               dx3
icall ; вызываем процедуру
rjmp          CONFIG
CFGERR:
rcall         ERR ; индикация ошибки
rjmp          CONFIG
;---------- Выход из меню
CFGEND:
rcall         INIT
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----------
MPT:
;процедура номер ноль
ret

;----------
RSTCFG:
;процедура номер раз
ret

;----------
OPNCFG:
;процедура номер два
ret

;----------
MENUCFG:
; процедура номер три
ret

;----------
LIGHT_CFG:
;процедура номер четыре
ret

;----------
US_OV:
;процедура номер пять
ret

;----------
STAT_CFG:
;процедура номер шесть
ret

;----------
SENS_CFG:
;процедура номер семь
ret

;----------
CLR_CFG:
;процедура номер восемь
ret

;----------
MASTERCFG:
;процедура номер девять
ret



В семействе MEGA код можно упростить, но этот пример писался для семейства TINY с урезанными набором инструкций.

Данные приемы экономят как память, так и такты.

_________________
I am DX168B and this is my favourite forum on internet!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Хитрые, необычные алгоритмы и код
СообщениеДобавлено: Пт сен 05, 2014 17:53:37 
Вымогатель припоя
Аватар пользователя

Карма: 7
Рейтинг сообщений: 56
Зарегистрирован: Вт авг 28, 2012 22:21:33
Сообщений: 535
Рейтинг сообщения: 0
Скорее, предыдущий совет - это то, как не надо делать. Точнее так. Использования обработчиков и таблицы переходов само по себе не плохо, но не в случае оптимизации switch, потому что:
1. Мы экономим на семечках. В подавляющем большинстве случаев обработка команд происходит в фоне и выигрыш в несколько тактов не стоит усложнения кода. Иначе стоит задуматься об архитектуре приложения, а не заниматься бесполезной оптимизацией.
2. Конструкция switch с более-менее равномерным диапазоном значений с большой долей вероятности преобразуется компилятором в ту же самую таблицу переходов. Зачем делать за компилятор то, что он может сделать лучше?


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

Карма: 7
Рейтинг сообщений: 56
Зарегистрирован: Вт авг 28, 2012 22:21:33
Сообщений: 535
Рейтинг сообщения: 0
Намного проще и правильней выглядит вот такой вариант:
Код:
void Handle(Command cmd)
{
    case Command1: Handle1(); break;
    case Command2: Handle2(); break;
    case Command3: Handle3(); break;
    case Command4: Handle4(); break;
    case Command5: Handle5(); break;
    case Command6: Handle6(); break;
    case Command7: Handle7(); break;
    case Command8: Handle8(); break;
    case Command9: Handle9(); break;
    case CommandA: HandleA(); break;
    case CommandB: HandleB(); break;
    case CommandC: HandleC(); break;
    case CommandD: HandleD(); break;
    case CommandE: HandleE(); break;
    case CommandF: HandleF(); break;

    default: Handle0(); break;
}


Весь код из switch так же выносится в обработчики. Ориентироваться в таком switch очень легко, даже если он длинный. Не надо смотреть в таблицу, чтобы понять какая команда какому обработчику соответствует. Не надо шерстить таблицу, чтобы заменить один на другой, удалить, или добавить обработчик. Легко реализуется обработчик по умолчанию. Нет проблем, если команды имеют большие номера. Нет проблем, если номера команд стоят далеко друг от друга. Компилятор оперирует на уровне отдельных инструкций, у него гораздо больше возможностей оптимизировать всё это.

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


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

Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52
Сообщений: 4470
Откуда: Главный Улей России (Moscow)
Рейтинг сообщения: 0
mezonda ладно. Пусть пример на Си останется для тех, кто плохо понимает ассемблер или только начал изучать его (но уже был знаком с Си).
То есть, пример на Си описывает принцип работы примера на ассемблере.
Но на АСМе оно пригодится. У меня так в одном девайсе клавиатуная менюшка реализована. По примеру охранных устройств от компаний DSC и Cerber.
У крупных ППКОП от DSC количество пунктов в главном меню достигает нескольких сотен, а в качестве "мозга" стоит PIC средней паршивости. (на некоторых моделях видел даже Z80)
Там наверняка такая реализация.

_________________
I am DX168B and this is my favourite forum on internet!


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

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


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

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


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

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


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