![]() |
|
Модераторы: PILOT, ManiaK, Mazzi |
![]()
|
|
| fol |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 22.10.2006 Репутация: нет Всего: нет |
Общий привет.
Извиняйте за такой вопрос, но перерыв кучу исходников так и не нашел ответа. Пишу (а точнее перписываю под AVR) драйвер LED индикатора, и застопорилось все на выборке данных из таблицы. То есть в зависимости от определенной константы в буфере происходит выборка данных из таблицы. В старых своих прогах под PIC контроллер, все решалось очень просто и изящно: addwf PC,F ; Увеличить значение PC на величину лежащую в W После этого голова программы скакала на нужное место в таблице. С AVR... застопорилось. Я конечно использовал другой способ, когда программа последовательно сравнивает знчение буфера и констант, и таким образом находит нужную позицию в таблице. Но так все это не красиво. Даже когда производим вывод чисел от 0 до 9 имеем 10 позиций-меток. А если нужно выбирать еще символы и т.д. вообще все это разрастается. Подскажите пожалуйста, как решается задача. Дайте формулу на ASM, или хоть направление. Плиз. Пжалста. Буду благодарен, правда... на хлеб не намажешь. |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
В AVR контроллерах регистр PC не доступен, я тебе могу предложить IJMP, переход по регистру Z. Если тебе надо скокнуть относительно какойто позиции, то ты должен знать какую нибудь точную позицию, относительно каторой известен здвиг. Если ты и этого не знаешь, то можно извратиться так: скокнуть RCALL на следующую команду - ты в стеке получишь типо PC. Выдави из стека информацию, измени, вдави обратно и сделай RET (изврат, а что делать).
Вопрос, ты пишешь на чистом ASM или используешь ассемблерные вставки в C-шный код? Это сообщение отредактировал(а) Ivan. - 30.10.2006, 17:24 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| PILOT |
|
|||
|
производство ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2724 Регистрация: 4.4.2002 Где: москва Репутация: 20 Всего: 54 |
Ivan в принципе прав, но.
Задача case MyVar of 1: 2: 3: ... N: решается действительно с помощью IJmp, но других применений кроме как в машине состояний я пока этой команде не нашел. В вашем случае, я так понял, нужно выводить двоичное число в десятиричном виде на индикатор. В такой постановке делается примерно так: 1) вы находите десятичное представление, т.е. переводите то что нужно отобразить в так называемый BCD формат (можно и не в сжатый) 2) создаете в памяти программ таблицу соответствия десятичного числа семисегментному (или любому другому коду) отображению. 3) после определения какие цифры отображать (т.е. после перевода в BCD) вы смещаетесь по этой созданной таблице на номинал цифры (например, если ноль, то не смещаетесь, а значит отобразится символ сообтетвующий нулю по нулевому смещению). 4) повторяете пункт 3 до тех пор пока все разряды не отобразятся. СУВ. -------------------- тут могла быть Ваша реклама... |
|||
|
||||
| fol |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 22.10.2006 Репутация: нет Всего: нет |
Привет. Спасибо что ответили.
Сейчас как раз занимаюсь моделированием всех этих вариантов. То есть имеем два основных, возможных варианта вычисляемого перехода, в рамках камня AVR. Резюме: 1. Вариант. "Ivan" Это косвенная загрузка счетчика команд через регистр Z. Кстати это не такой уж изврат а нормальный подход, по моему на такой способ где то была ссылка в фирменном даташите на Atmega16, которую я сейчас юзаю на макете. Основной недостаток, нырнув в этот тоннель, надо точно знать координаты выхода из тоннеля. А это всегда вычисления, причем вручную. А вот попользоваться услугой стека, это очень перспективно. 2. Вариант. "PILOT" Попробую наиболее подробно поработать с вариантом создания таблиц. Подозреваю что при больших массивах (вборка большого к-ва ячеек) вариант табличного размещения будет наиболее компактен, и возможно даже более визуально нагляден. Но так же подозреваю что этот вариант будет иметь серьезный недостаток. А именно нужно всегда быть очень внимательным при размещении таблицы в памяти чтобы ни она никуда не "уползла", ни на нее никто не "наехал". Это весьма проблематичной, с моей философией письма, вариант. Я предпочитаю, составление полностью готовых, снаряженных, и универсальных модулей. Это в особенности актуально при смене контроллера. Дело в том что я стараюсь составлять даже простейшую программу, из набора подпрограмм, модулей, по типу конструктора. Естественно каждый модуль должен перед эти пройти все испытания, причем во всех возможных режимах и т.д. То есть в каждом модуле я должен быть уверен. Если к этому подойти философски, это можно представить как язык программирования сверх высокого уровня, то есть оперируем глобальными величинами, ну как наше правительство. А я президент, ха. По загрузке, использовании памяти проца это конечно не эффективно. Но с точки зрения времени на создание проекта, и отладку, это оправдано. К тому же последнее время не помню когда ограничивала память. Если надо больше, взял другой кристалл, и все. Так вот, в стремлении создать очередной такой модуль, как я называю его, драйвер LED индикатора, я пытаюсь изучить все досконально. Зато потом можно забыть, и заниматься другим. Готовый модуль нужно только врезать в основную прогу, прописывать его там и т.д. Вначале я применил метод последовательного перебора: SELECT_SYMBOL_LINE: inc Count ; Увеличить счетчик разрядов на 1 (+1) ;----- В регистре Temp находится двоично-десятичное число ------- ;----- В регистре Count находится номер текущего разряда -------- ;-------------------- ВКЛЮЧИМ СЕГМЕНТЫ ---------------------------- ;----- Выберем сегменты соответствуюшие числу в регистре Temp ------ cpi Temp, 0 ; Если содержимое Temp = КОНСТАНТА breq SYMBOL_0 ; то производим выборку SYMBOL_0. cpi Temp, 1 ; Если содержимое Temp = КОНСТАНТА breq SYMBOL_1 ; то производим выборку SYMBOL_1. ; НУ И ТАК ДАЛЕЕ Вот какая махина.!!! Ни красоты ни изящества. Я много просмотрел прог в инете, ну там всякие частотомеры, вольтметры, и везде (вроде) народ пользует этот алгоритм. Опять че то меня понесло. Ладно, у меня точно что то с головой. Спасибо всем, будем работать. "А у вас нет, точно такого же, но с перламутровыми пуговицами? Нет? Будем искать..." |
|||
|
||||
| PILOT |
|
|||
|
производство ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2724 Регистрация: 4.4.2002 Где: москва Репутация: 20 Всего: 54 |
Рассказываю!
Берем и делаем так LdI ZL, low(lCaseLabels<<1); LdI ZH, high(lCaseLabels<<1); AdIW ZL, R16; LPM MovW ZL,R0 IJmp Symbol1: {commands} RJmp lSymExt Symbol2: Symbol3: SymbolN: lSymExt: {commands after case} RJmp lMainLoop; lCaseLabels: .dw Symbol1, Symbol2, Symbol3,..., SymbolN; За компилируемость не ручаюсь, но суть должна быть ясна СУВ. -------------------- тут могла быть Ваша реклама... |
|||
|
||||
| PILOT |
|
|||
|
производство ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2724 Регистрация: 4.4.2002 Где: москва Репутация: 20 Всего: 54 |
На таблицу никогда ничего не наедет, за этим следит линкер. Так что делай что хочешь
СУВ. -------------------- тут могла быть Ваша реклама... |
|||
|
||||
| fol |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 22.10.2006 Репутация: нет Всего: нет |
Ну спасибочки.
Теперь минимум на три дня засяду. Пока все переварится, отложиться и сформируется... Пока щетина не вылезет. Это примета такая, как только начал врубаться, это значит прошло около трех, четырех дней. Все это время как бы в отключке. Все же не совершенен мозг человека, (или мой? тьфу через левое плечо) необъятное не обнимается. А потом, однажды, вдруг... выходишь на улицу, и, нифига себе... Облака летят, листья падают. И где это меня носило? А нигде. Вычисляемый переход постигал, понимашь, это не хухры мухры. А за это время столько облаков улетело... И че в жизни САМОЕ. ? Всем спасибо!!!. Временно отключаюсь. Потрудимся на благо себя. |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
Если рассмотреть задачу глобальней, то я так понял, что тебе надо управлять сегментным индикатором (скорей всего 7-ми сегментным).
Чем тебе не подошел классический способ управления 7-ми сегментным индикатором? например дано: 5 7-ми сегментных индикаторов, расположенных в ряд.
ну и так далее. Функция Dec выводит число в десятичном формате с точкой в позиции Dot. Если разряды после запятой не влезают в строку, функция уменьшает точность выводимого числа. Если целая часть числа тоже не влезает функция выводит закодированную ошибку в виде (например надо вывести число 12345 с точкой после первого разряда на трех сегментах) "12.3." указывая, что один разряд не влез. второй пример, если надо вывести число 12345 с Dot = 0 => "1.23." - невлезло 2 символа. конечно это необходимо только если число действительно может не влезти на дисплей, например при дисплее величиной в 3 разряда. А вообще по логике программы таких чисел допускать впринципе нельза. Если хочешь, могу выложить полную версию моей компоненты TLed7_2 - Это динамическая компонента (class) для управления семисегментным двухцветным индикатором с возможность автоматического мигания. Это сообщение отредактировал(а) Ivan. - 3.11.2006, 22:53 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
![]()
|
| Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)" | |
|
|
На данный раздел помимо Правил форума распространяются текже следующие правила:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi. |
| 1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |