А тем временем мы с LGT8f328p продолжаем мучить друг друга Много всего недо_документрованного В аппаратной математике ещё столкнулся с одним нюансом.. на этот раз вычитание..
Код:
; Например загружаем в вычитемое: ldi R25, 0x00 ldi R24, 0xFF ldi R23, 0XFF ldi R22, 0xFF ; вычитаем: R26, 0xFF R27, 0xFF ; и тут мы перед самой загрузкой в DA меняем R25: ser R25 out DSAH, R24 ; загружаеи R22..R25 в регистр DA out DSAL, R22 ... ... ; ответ будет 0x00FF0000 ; так как R25 не успевает прогрузиться ; нужно так: ... ser R25 nop out DSAH, R24 ; загружаеи R22..R25 в регистр DA out DSAL, R22 ... ; тогда ответ будет 0xFFFF0000
Вобщем, если значение в регистре изменялось, то перед загрузкой в DA нужен один такт, это если нет перехода. интересный чип Всем
И опять не знаю, в тему этой темы или нет... Возникла проблема с LGT8f328p. Не знаю, на 328-й меге так же должно быть, или это "особенности" LGT.
Суть следующая: имеется весьма компактный рабочий кусок кода с инструкцией ICALL. Но как только он записывается в другое адресное пространство, он перестаёт работать..
Для чистоты эксперимента я просто размещал перед ним пустые данные в виде .db 0x00, 0x00, 0x00... e.t.c.., а в подпрограммах, куда осуществлялся переход, процедуры заменял на NOP-ы
Если разместить перед этим кодом примерно 8kB данных, то при вызове ICALL контроллер идёт в перезагрузку. При 7kB отрабатывает нормально.
В принципе, я могу разместить этот код в любом месте флеша, но просто интересно, почему так происходит
в нормальных AVR ICALL работает в диапазоне 128 кБ, а у тебя получился для этой команды диапазон 8 кБ. у тебя твой LGT8f328p отрабатывает эту команду аналогично RCALL, только RCALL работает в диапазоне 4 кБ.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Сорри.. Те процедуды писал больше недели назад.. И странно, что они работали.. По запаре напутал после ICALL где rjmp, где ret... А обнаружил только сегодня, когда шрифты подключил 20x30 и 30x48 и блоки изображений..
Сейчас всё работает. Для уверенности выставил перед ICALL 20kB - полёт нормальный.
Starichok51 писал(а):
в нормальных AVR ICALL работает в диапазоне
Этот контроллер тоже нормальный.. Видимо это я не очень..
Месяца 2 разбирался с контроллером (а всего у меня 3 платы, заказаных в китае у разных продавцов) и настало время всё это завершить и собрать уже в корпус.. Стенд решил не разбирать.. Достаю новую плату, прошиваю и.. (а в проекте дисплей ILI9341 240x320) на дисплее выводится как бог на душу положил Третья плата также не работает с моей прошивкой.. Неисправность проявляется следующим образом: если например заливка экрана просто одним цветом, то работает без нареканий. Но если вывод информации, с частой сменой поля вывода и переключением пина команда/данные, то творится странное.. Частично удалось добиться работы снизив тактовую частоту с 32мгц до 16, стало более вменяемо, но не до конца.. снижение до 8мгц результат не улучшило.. Хотя на первом чипе результат стабилен. Также не корректно считывается EEPROM. Из-за чего это происходит не знаю, может и при питании 3,3В разные чипы ведут себя по разному, хотя в даташите заявлена тактовая 32мгц на весь диапазон напряжений.. Но повысить напряжение для проверки мне сложновато, так как две переферии на 3,3в
Вобщем ещё предстоит разбираться.. выставлять где то какие то задержки.. и искать компромиссный вариант, подходящий для всех чипов, а так же пытаться вернуть частоту к 32мгц..
Добить то проект я добью, в крайнем случае вернусь на мегу 328-ю, просто делюсь впечатлением, и, если решите позаниматься с LGT8f328p, имейте ввиду, что чипы очень разнятся, и прошивка может оказаться неповторяема.
PS Спойлервместо LGT8f328p почему то уже хочется написать LGBT8f328p
Добавлено after 2 hours 44 minutes 21 second: PS2 Разобрался. Проблема была в постоянно включеном арифметическом модуле uDSC. Проявлялась (у меня) на инструкциях brts и sbrc, причём не вот постоянно, а зависило от ряда факторов, включая тактовую частоту. Не знаю, может в эмуляторах это можно разглядеть.. но я не пользуюсь ими
Поправил код. uDSC теперь включается непосредственно на время выполнения операции. Всё работает, на всех частотах.
Но! Один чип исправно работает при постоянно включеном uDSC, а вот 2 других капризничают))
shonty, С дисплеем обратите внимание, сигнал D/C (а так же CS, если пользуете) нужно переключать после окончания передачи байта по SPI. Когда то я на этом споткнулась. Т.е. перед переключением D/C нужно дождаться окончания передачи SPI.
Здравствуйте! ... Написал простейшую программку, которая по внешним прерываниям опрашивает энкодер, инкрементирует/декрементирует значение в регистре и сразу отправляет по UART. ... ... Проблема в том, что независимо от направления вращения энкодера получается только инкремент (или только декремент, если переход не по sbis, а по sbic). Как будто второй канал энкодера постоянно находится в 1. ... ...
Вот и я задался этим же вопросом.
При использовании энкодера раньше чужим кодом пользовался. Но он, как по мне, излишне сложен, громоздок и интуитивно непонятен. Опрос энкодера был в основном цикле, потом проверка на дребезг в таймере.. Кроме того, не смотря на всю навороченность кода, я проверял работу энкодера на 8-ми светодиодах, наблюдались то пропуски щелчков, то вообще в обратку простреливал.. Я было грешил на некачественный энкодер, но, как потом оказалось, с энкодером всё впорядке.
Решил поискать что-то получше.. но в итоге пришлось писать самому.. Оказалось совсем несложно. Проверял всё на той же плате с восемью светодиодами, работает чётко, как при быстром вращении, так и при медленном.
Если ещё для кого-то актуально: Спойлер
Код:
; Определение подключения каналов. Здесь же меняется направление вращения: .equ CANAL_A = 1 ; канал А (PIND 1) .equ CANAL_B = 2 ; канал А (PIND 2)
Код:
; ---------- Главный цикл ---------- LOOP: ... ... ... Read_ENC: sbis PIND, CANAL_A rjmp ROTATE_LEFT ; переход если сигнал в канале "A" sbis PIND, CANAL_B rjmp ROTATE_RIGHT ; переход если сигнал в канале "B" exit_read_enc: ... ... ... rjmp LOOP ; в начало цикла ----------
Код:
ROTATE_LEFT: ; проверка на вращение влево: sbis PIND, CANAL_A rjmp PC-1 ; ждём когда канал "A" деактивируется sbic PIND, CANAL_B rjmp exit_read_enc ; если канал "B" деактивирован, то на выход
; процедура: ... ... ...
ROTATE_RIGHT: ; проверка на вращение вправо: sbis PIND, CANAL_B rjmp PC-1 ; ждём когда канал "B" деактивируется sbic PIND, CANAL_A rjmp exit_read_enc ; если канал "A" деактивирован, то на выход
; процедура: ... ... ...
PS: В схеме каналы энкодера подключены к контроллеру к выводам с внутренней подтяжкой к VCC
Но если следовать даосской практике символической организации пространства, то в цикле правильнее будет проверять состояние всего порта, а не отдельных пинов. Особенно если элементов управления будет несколько.
Поэтому главный цикл лучше переписать так:
Код:
;---------- Главный цикл ---------- LOOP: in R16, PIND andi R16, (1<<CANAL_A)|(1<<CANAL_B) cpi R16, (1<<CANAL_A)|(1<<CANAL_B) breq LOOP
sbrs R16, CANAL_A rjmp ROTATE_LEFT ; переход если сигнал в канале "A" ; sbrs R16, CANAL_B ; последюю проверку не обязательно rjmp ROTATE_RIGHT ; переход если сигнал в канале "B"
rjmp LOOP
Добавлено after 44 minutes 2 seconds: Но а пропуски всё равно есть.. Сделал 10 полных оборотов в одну сторону, потом в другую столько же. Разница 15 щелчков
Но от них никуда не деться. Если опрос порта происходит в этот момент, то пропуск гарантирован:
Без пропусков только через прерывания.. Но если "приборы" не подключать, а чисто по ощущениям, то пропуски не заметны
Тоже делал обработку энкодеров в прерывании. Но у меня критично по времени было, не мог себе "позволить" каких-либо ожиданий в цикле. Подумал над данными, поступающими от энкодера, и отметил следующее: три последовательных состояния представляют собой константу, которая однозначно определяет направление вращения Например: 01 -> 00 -> 10 = поворот в одну сторону 10 -> 00 -> 01 = поворот в противоположную сторону Поэтому сохранял в байте три последних изменения пинов энкодера (3 * 2бита = 6бит). И сравнивал эти 6 бит с константами поворота влево и вправо.
PS Прерывание не от пинов энкодера, по таймеру через 500 мкс, пропусков состояния энкодеров (2 шт) нет, анализируется быстрое и медленное вращение
Я применял для быстрой обработки энкодера такой код: от энкодера есть 2 входа, я размещал их в соседние разряды бита, затем делал младшему разряду XOR со старшим, результат записывал обратно в младший, всё - у меня получался обычный счёт, и теперь чтобы узнать, куда повернулся энкодер, достаточно было это состояние вычесть из предыдущего - если результат 1 - вправо, если -1 - влево, если 0 - энкодер не шевелился, если 2 или -2 (что при 2хбитной переменной тождественно) - значит энкодер крутанули слишком быстро... ну, и новое состояние не забываем сохранить, для следующего вычисления.
ПС: код был на С написан, но с учетом того, как онна ассемблер развернётся и код не под рукой, а то бы выложил - там ещё трюки были...
ПС2: это был вольтметр на семисегментниках и опрос энкодера вызывался после переключения динамической индикации...
_________________ Для тех, кто не учил магию мир полон физики Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Последний раз редактировалось Ivanoff-iv Ср ноя 20, 2024 15:14:55, всего редактировалось 1 раз.
Но у меня критично по времени было, не мог себе "позволить" каких-либо ожиданий в цикле.
Если в цикле только опрос порта, то in - 1 цикл andi - 1 cpi - 1 breq - 1 если условия не соблюдены, 2 если соблюдены
Итого 4..5 циклов. Думаю это не столь критично.
Критичны именно пропуски. А они при опросе неизбежны.
Всего при опросе пропусков может быть примерно треть от общего количества щелчков. Опрос может совпасть как с зелёной, так и с красной зоной. А это 2:1
На практике сделал энное количество оборотов:
Фиксировал до и после этого кода:
Код:
sbis PIND, CANAL_A rjmp pc-1 ; ждём когда канал "A" деактивируется sbic PIND, CANAL_B rjmp LOOP
0xEC это 236 - всего щелчков 0x97 это 151 - это сколько сработало
(236/3)*2=157,33... примерно так и есть.
При опросе срабатывает примерно 2/3 щелчков.
Добавлено after 2 minutes 53 seconds:
shonty писал(а):
При опросе срабатывает примерно 2/3 щелчков.
Сорри В моём коде срабатывает примерно 2/3 щелчков. Но чисто тактильно не ощущается и меня устраивает
shonty, чего то я не понял вас, я писал опрос на 1 прерывании по изменению внутри прерывания просто сравнивал состояния входов без каких либо ожиданий, если равны - полцикла вправо, иначе - полцикла влево и ни каких 2/3 пропусков не было...Спойлер
_________________ Для тех, кто не учил магию мир полон физики Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Я тоже не понял про 2/3. У меня работает без пропусков. Прерывание через 500 мкс, два энкодера опрашиваются по очереди, сначала 1й, при следующем входе в прерывание 2-й. Получается каждый энкодер опрашивается с интервалом 1 мс. Сохраняется только изменение состояния по сравнению с предыдущим.
Через очень короткое время (напр. недели .. несколько месяцев) меняется состояние контактов механического энкодера. Контакты загрязняются, изнашиваются и т.д. Неправильные выходные сигналы создают "беспорядок" от какого-то избыточного импульса до неправильная реакция вперед/назад. Сигнал ниже: энкодер на примерно 1-2 года в синтезатор частоты ham-радио. Конденсаторы отчасти помогают, но "замедлить" реакцию.
Добавьте математическую обработку. По прерыванию или в цикле нет значении. Никаких доп. задержек в коде для debounce. Пример: Rotary на Ben Buxton - state machine. Лучшего "лечения" мех. енкодера пока не нашол. Енкодеры работают годами, напр. в VFO: DDS или PLL в качестве основного компонента настройки, базовое радио. Просто если зуб енкодера поврежден, позиция пропускается. При втором зубе - тоже пропускает. На 3-м потерянном зубе - меняю энкодер .
Портировал метод на несколько типа МК: от Arduino к "чистый" AVR, PIC, STM8/32 и др. Везде работа безупречная. В перерыве, в цикле, без проблем. Конденсаторы нет.
Даже аппаратная обработка в STM32 с этой проблемой не справилась, ни при каких настройках. И там "сломанный кодер" /и его недостатки/ заставил меня использовать метод. Аппаратную часть там оставил для опт. энкодер. (частично пользуюсь переводчиком БГ-РУ)
енкодер KY-040 к лог. анализатор: - новый кодер - в эксплуатации /1-2-3 года/
Последний раз редактировалось veso74 Ср ноя 20, 2024 16:07:00, всего редактировалось 6 раз(а).
ДядяВован, там аппаратная поддержка, таймер сам считает в одну или другую сторону, с фильтрацией, потому нет ни прерываний по изменению уровня на пинах, ни просто периодических. Можно в любой момент прочитать значение счетчика и получить разницу по сравнению с прошлым разом, но если между опросами небольшая задержка, то работает не лучшим образом, потому я просто выхожу из функции если прошло меньше 1ms.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения