реклама на сайте
подробности

 
 
> Использование команды ijmp
Sprite
сообщение Jul 13 2008, 16:45
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Доброго времени суток, товарищи! Программирую я на atmega8535.
Задача такая:
Имеется промежуток времени - 1000 тактов. Через время t [~0;1000] должно наступить событие S(скажем должен податься уровень 1 на ногу PB7) с точностью до 1 такта. Вначале промежутка время события t известно. Наступление этого события требуется сгенерировать программно, не используя какие-либо прерывания.
По логике вещей нужно после преобразования значения t в значение счетчика декрементировать его до наступления этого события, т.е. примерно так:
Код
        ldi    R16,    200   ; Считаем, что 200  - уже преобразованное значение счетчика, соответствующее t = 800
Decrement:
        dec R16    ; Вычитаем 1
        cpi R16,    0; Сравниваем с 0
        brne Decrement; Перейти если не равно 0    

                                sbi  PORTB,   7          ; Событие S - подаем уровень 1 на ногу PB7

Все бы хорошо, но вышеописанный подход позволяет генерировать событие S через время t кратное 4, т.е. 16, 20, 24 и т.д., поскольку код в операциях dec, cpi и brne занимает 4 тактаsad.gif А как быть если t = 513? Добить NOP-ами просто не получится, поскольку t постоянно меняется каждые 1000 тактов. Товарищ посоветовал использовать команду ijmp, но как ей пользоваться я не разобрался.
Помогите!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
aaarrr
сообщение Jul 13 2008, 20:03
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Забейте 1000 nop'ов и используйте ijmp.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jul 14 2008, 07:35
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Sprite @ Jul 13 2008, 19:45) *
...позволяет генерировать событие S через время t кратное 4, т.е. 16, 20, 24 и т.д., поскольку код в операциях dec, cpi и brne занимает 4 такта. А как быть если t = 513? Добить NOP-ами просто не получится, поскольку t постоянно меняется каждые 1000 тактов. Товарищ посоветовал использовать команду ijmp

Команда cpi в Вашем примере - явно лишняя (команда dec сама устанавливает флаг z), поэтому время - кратно 3. Можно, конечно, поставить много-много nop'ов подряд и переходить на нужный командой ijmp (как посоветовал aaarrr), а можно модифицировать ваш цикл (добавить nop'ы)

Код
Decrement_2: nop
Decrement_1: nop
Decrement: dec R16
      brne Decrement

При одном и том же значении r16, переход на Decrement_1 даст на 1 такт задержку больше чем переход на Decrement, а, переход на Decrement_2 - на два такта.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 14 2008, 11:09
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Палыч @ Jul 14 2008, 10:35) *
Код
Decrement_2: nop
Decrement_1: nop
Decrement: dec R16
      brne Decrement

При одном и том же значении r16, переход на Decrement_1 даст на 1 такт задержку больше чем переход на Decrement, а, переход на Decrement_2 - на два такта.
Да, именно так.
Только тут на 3 делить надо и максимальное время задержки меньше заявленной тысячи тактов.
Если использовать пару R25:R24, то увеличивается максимальная задержка и естественным образом цикл становится 4 такта, легче вычислять счётчик. Что-то в духе:
Код
; тут в r25:r24 время в тактах на задержку, 17..65536
; r17:r16 рабочие
    sbiw    r24, 14; 2; накладные расходы на организацию процесса
    movw    r16,r24; 1;
    lsrw    r24; 2;
    lsrw    r24; 2;
    andi    r16, 0x03; 1;
    clr    r17; 1;
    ldiw    ZL, pm(delay); 2;
    subw    r30,r16; 2;
    ijmp    ; 2;
    nop
    nop
    nop
delay:
    sbiw  r24, 1
    brne delay

макросы lsrw, ldiw, subw считаю очевидными :-)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Sprite
сообщение Jul 14 2008, 11:48
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Цитата(Палыч @ Jul 14 2008, 14:35) *
Команда cpi в Вашем примере - явно лишняя (команда dec сама устанавливает флаг z), поэтому время - кратно 3. Можно, конечно, поставить много-много nop'ов подряд и переходить на нужный командой ijmp (как посоветовал aaarrr), а можно модифицировать ваш цикл (добавить nop'ы)

Код
Decrement_2: nop
Decrement_1: nop
Decrement: dec R16
      brne Decrement

При одном и том же значении r16, переход на Decrement_1 даст на 1 такт задержку больше чем переход на Decrement, а, переход на Decrement_2 - на два такта.


Спасибо, обязательно попробую.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jul 14 2008, 12:50
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(ReAl @ Jul 14 2008, 14:09) *
Если использовать пару R25:R24, то увеличивается максимальная задержка и естественным образом цикл становится 4 такта, легче вычислять счётчик. Что-то в духе:
Код
delay:
    sbiw  r24, 1
    brne delay

макросы lsrw, ldiw, subw считаю очевидными :-)
Последнюю команду (brne) необходимо заменить на brnew smile.gif (а, иначе оно и работать не будет). Но, как демонстрация использования ijmp, Ваш пример - самое то.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 14 2008, 12:54
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Палыч @ Jul 14 2008, 16:50) *
Последнюю команду (brne) необходимо заменить на brnew smile.gif (а, иначе оно и работать не будет).

Это шутка? sbiw ставит флаг Z.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jul 14 2008, 14:00
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(aaarrr @ Jul 14 2008, 15:54) *
Это шутка? sbiw ставит флаг Z.
Конечно - шутка (я, и смайлик соответствующий поставил). Просто в первый раз вижу как активно используются макросы типа lsrw, ldiw, subw (сам пишу соответствующую пару команд). Автор вопроса, наверное, - новичок (судя по названию подфорума) - может и не понять сути макросов.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th August 2025 - 13:13
Рейтинг@Mail.ru


Страница сгенерированна за 0.02385 секунд с 7
ELECTRONIX ©2004-2016