Easyelectronics.ru

Электроника для всех
Текущее время: 26 фев 2021, 03:41

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



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 20 ] 
Автор Сообщение
 Заголовок сообщения: Переход на ASM после Си
СообщениеДобавлено: 09 фев 2010, 00:05 
Заглядывает иногда

Зарегистрирован: 28 янв 2010, 21:20
Сообщения: 117
Откуда: Днепропетровск
Добрый вечер уважаемое сообщество!!!
Заставил себя попробовать програмить МК на асме.
Ранее почти год использовал Си, и вот....

Первое впечатление - очень большое к-во похожих команд, их надо помнить или шерстить доки в поисках подходящей команды.

На элементарных операциях - сразу "тупняк", потом рытье инет и док и ... вроде получается...


Посмотрите пож. глобально, есть ли принципиальные ошибки, я бы даже сказал - идеологические!!!
Задача программы - на Тиньке 13а мигать поочередно 2-я светодиодами с интервалом 1 с. с использование таймера.

    ;---------------------------выставить фузы на 4 800 000
    .nolist
    .include "tn13Adef.inc"
    .list

    .def temp = R16
    .def temp1 = R17
    .def count = R18
    .equ TIMER_DELITEL = (4800000/1024/100)

    ; .dseg ; определяем сегмент данных
    ; var1: .byte 1 ; выделяем память для перем. var1 1 байт

    .cseg ; установка сегмета программы
    .org 0 ; сброс на 0 счетчика команд

    rjmp init ; перепрыгиваем таблицу векторов.
    .org INT0addr ; External Interrupt0 Vector Address
    reti
    .org PCI0addr ; External Interrupt Request 0
    reti
    .org OVF0addr ; Timer/Counter0 Overflow
    reti
    .org ERDYaddr ; EEPROM Ready
    reti
    .org ACIaddr ; Analog Comparator
    reti
    .org OC0Aaddr ; Timer/Counter Compare Match A
    rcall tim0comp
    .org OC0Baddr ; Timer/Counter Compare Match B
    reti
    .org WDTaddr ; Watchdog Time-out
    reti
    .org ADCCaddr ; ADC Conversion Complete
    reti

    .ORG 10 ; Начало основной программы
    ;---------------------------очистка регистров общ. назначения РОН r00-r31
    init: LDI ZL, 30 ;
    CLR ZH ;
    DEC ZL ;
    ST Z, ZH ;
    BRNE PC-2 ;
    ;---------------------------определяемся со стеком
    ldi temp, RAMEND ; загрузка в темп адрес конца опреративки (РАМ)
    out SPL, temp ;установка начала стека (конца RAM (оперативки))
    ;---------------------------инициализация портов ввода-вывода
    ser temp ;темп =FF
    out DDRB, temp ;все на выход
    clr temp ;темп = 0
    out PORTB, temp ;подтяжки нет
    ;---------------------------инициализация таймера 0
    ldi temp, 1<<WGM01
    out TCCR0A, temp ;установка режима - сброс по соапад.
    ldi temp, 0b00000101
    out TCCR0B, temp ;установка предделителя 1024 и режим сброс по соапад.
    ldi temp, TIMER_DELITEL
    out OCR0A, temp ;прерыв возник. прим. 50раз в сек.
    ldi temp, 1<<OCIE0A
    out TIMSK0, temp ;разр. прер. по совп. А тайм. 1


    ;---------------------------Главная программа
    start: nop
    rcall led1on
    ; rcall led2on
    sei
    start1: nop
    rjmp start1
    ;---------------------------подпрограммы
    led1on: sbi portb, 3 ;включения ЛЕД 1
    ret
    led2on: sbi portb, 4 ; -!!- ЛЕД2
    ret
    led1off:cbi portb, 3 ;выключение ЛЕД1
    ret
    led2off:cbi portb, 4 ; -!!- ЛЕД2
    ret
    led1inv:
    push temp
    push temp1
    in temp, portb
    ldi temp1, 0b00001000 ;инвертируем PB3
    eor temp, temp1
    out portb, temp
    pop temp1
    pop temp
    ret
    led2inv:
    push temp
    push temp1
    in temp, portb
    ldi temp1, 0b00010000 ;инвертируем PB4
    eor temp, temp1
    out portb, temp
    pop temp1
    pop temp
    ret
    ;---------------------------обработка прерывания от таймера 100 раз в сек
    tim0comp: nop
    in temp, SREG ; сохряняем SREG
    push temp ;
    inc count ;
    cpi count, 102 ; делитель 100 = 1секунда
    brne endint ;
    clr count
    rcall led1inv ; инвертируем 2 ЛЕДа rcall led2inv
    endint: pop temp ;
    out SREG, temp ; восстанавливаем SREG
    reti
    ;-------------

Заранее спасибо,
с уважением,
Влад.


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 00:47 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:55
    Сообщения: 5600
    Откуда: Уругвайская АССР
    Будь проще, и люди потянутся. Для начала, незачем описывать положение каждого вектора. Это же ассемблер, он генерирует тот код, который ему скормишь, а не то, что придумается транслятору. Итак, описываем начало таблицы векторов, а потом, помня, что расстояние между векторами равно размеру команды...
    Код:
    . cseg
    .org 0
                   rjmp init           ; перепрыгиваем таблицу векторов.
                   reti                ; External Interrupt0 Vector Address
                   reti                ; External Interrupt Request 0
                   reti                ; Timer/Counter0 Overflow
                   reti                ; EEPROM Ready
                   reti                ; Analog Comparator
                   rcall tim0comp     ; Timer/Counter Compare Match A

    СТОП! здесь грубейший косяк! Должно быть rjmp tim0comp. В данном случае, может, и сканает, потому что по выходу из процедуры управление перейдет по следующему адресу, а там у тебя живёт reti. А если там нормальный вектор???
    Код:
                   reti ; Timer/Counter Compare Match B
                   reti ; Watchdog Time-out
                   reti ; ADC Conversion Complete

    Вот там, ORG 10 тоже нафик не упоролся. Закончилась таблица векторов, ну и замечательно. Следующий адрес и так и так транслятор сгенерит. Если нет необходимости сажать на определенное место именно эту команду, то незачем ставить .org. Им вообще не следует злоупотреблять. То есть, обозначил начало, (и то, чисто для очистки совести, бо если сегмент открыл, транслятор сам указатель на начало выставит), дальше тупо насыпал векторов. Я предпочитаю туда укладывать близкие переходы на оду заглушку. Скачай например мою читалку для таблетки, и посмотри.

    init: LDI ZL, 30 ;

    Опять совсем не то. Нафига регистры чистить? Пусть там хлам болтается! Он же никому не вредит, и ничьё чувство прекрасного не задевает. А если задевает, то почисть. Что только не сделаешь для удовлетворения страсти к порядку!
    Но вот ради порядка, хочу сказать, что во первых строках программы, надо бы зарядить указатель стека.
    Например так:
    Код:
          ldi   r16,low(ramend)
          out   spl,r16

    После этого, можно использовать вызовы процедур. До этого, выйдет туфта, и переход на сброс.
    Далее....

    _________________
    Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


    Последний раз редактировалось Горнист 05 апр 2010, 13:52, всего редактировалось 1 раз.

    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 01:04 
    Заглядывает иногда

    Зарегистрирован: 28 янв 2010, 21:20
    Сообщения: 117
    Откуда: Днепропетровск
    ArgusB писал(а):
    rcall tim0comp ; Timer/Counter Compare Match A

    СТОП! здесь грубейший косяк! Должно быть rjmp tim0comp. В данном случае, может, и сканает, потому что по выходу из процедуры управление перейдет по следующему адресу, а там у тебя живёт reti. А если там нормальный вектор???

    -понял!!!

    Цитата:
    init: LDI ZL, 30 ;

    Опять совсем не то. Нафига регистры чистить? Пусть там хлам болтается! Он же никому не вредит, и ничьё чувство прекрасного не задевает. А если задевает, то почисть. Что только не сделаешь для удовлетворения страсти к порядку!

    - это я где-то в комментах нашел, думал необходимо! -)))
    Цитата:
    Но вот ради порядка, хочу сказать, что во первых строках программы, надо бы зарядить указатель стека.
    Например так:
    ldi r16,low(ramend)
    out spl,r16

    - а это вроде было у меня в тексте????
    Цитата:
    После этого, можно использовать вызовы процедур. До этого, выйдет туфта, и переход на сброс.
    Далее....



    Спасибо большое! Пошел править!

    А так, в загали, инверсия бита правильно??? А Счетчик в цикле прерывания???
    Я в плане не оптимальности кода!!!


    Последний раз редактировалось Vlad777 09 фев 2010, 15:34, всего редактировалось 1 раз.

    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 01:32 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:55
    Сообщения: 5600
    Откуда: Уругвайская АССР
    Далее, вроде бы ништяк, настройка периферии на своём месте....

    Смотрим сразу на обработчик прерывания. Обработчик активируется, путём: запрета прерываний и передачи управления на соответствующий вектор. В векторе торчит rjmp на нашу процедуру обработчика. Процедуру обязательно нужно закончить reti, чтобы прерывания разрешились. Иначе она отработает один раз, и всё. Больше ничего работать не будет.
    Итак, процедура.
    tim0comp: nop ; НОП тут в угол не упирался. Зачем?
    in temp, SREG ; сохряняем SREG « Ещё один косяк. А кто регистр temp прятать будет???? В прерывании мы (не мы конечно, а процедура) получает весь контекст того случайно выбранного места, на котором тик таймера застал исполняющуюся основную программу. Вот с этого места у нас есть содержимое регистров, верхушка стека, и флаги (признаки) . И всё это дело, по завершению, надо вернуть владельцу в целости и сохранности. То есть выглядеть должно вот так:
    Код:
    tim0comp:   push   temp
          in   temp,SREG
          push   temp

    Вот так мы упаковали в стек временный регистр и регистр состояния процессора.
    Шо у нас там далее? Вроде всё в порядке. Смущает оправданность использования регистра в качестве глобальной переменной. Хотя почему бы нет?
    Код:
          inc   count ;
          cpi   count, 102 ; делитель 100 = 1секунда
          brne   endint ;
          clr   count
          rcall   led1inv ; инвертируем 2 ЛЕДа rcall led2inv
    endint:   pop   temp ;
          out   SREG, temp ; восстанавливаем SREG. Вооот! Здесь нужно постараться, чтобы всё, запихнутое стек, покинуло его, и желательно, в том же порядке, как и пришло. Вернее, в обратном тому порядке. Добавим сюда наш временный регистр, который мы спрятали первым.
          pop   temp
          reti   
    ; Вот, это и есть нормальный выход из прерывания, управление вернётся туда, отуда его взяли. А если бы у нас осталась команда rcall в таблице векторов, то возврат бы произошел на адрес, следующий за ней. И это был бы косяк...
    Далее...

    led1inv:
    push temp
    push temp1
    in temp, portb
    ldi temp1, 0b00001000 ;инвертируем PB3
    eor temp, temp1
    out portb, temp
    pop temp1
    pop temp
    ret

    Какой ужас на! Во-первых, зачем прятать в стек temp? Он же спрятан уже в процедуре обработчика прерывания. И подход к инвертированию бита странный.

    (предчувствую, сейчас прибежит SWG и начнёт скрипеть, что у пика это одной командой делается. Не слушайте его, у пика другие вещи неординарно делаются, и я даже сказал бы, с подвывертом...)

    Итак, задачу модификации одного бита в порту можно решить двумя способами: Способ первый: баловство с битовыми масками.
    Код:
          in   temp, portb ; предупреждаю, здесь читается значение, которое мы сами выдали в порт.
          mov   temp1,temp   ;Делаем копию считанного.
          andi   temp1,0b11101111   ; прорезаем в копии дырку в том месте, котое будем модифицировать.
          ori   temp, 0b11101111   ; оставляем от содержимого регистра только тот бит, который будем модифицировать
          com   temp      ; инвертируем ВСЕ биты ... Поправился...
          or   temp,temp1      ; собираем как было
          out   portB,temp

    А можно этот же кусок реализовать ветвлением. Выкидываем всю эту шнягу, которой кормили учебники по СИ и Васику, о том, что ветвление-зло. Промываем мозги шестидесятипроцентным раствором воды, и накрепко запоминаем: Любой алгоритм, где есть альтернативы, работает ТОЛЬКО на ветвлении. Если ЯВУ прячут ветвление от юзера, это не значит что его нет в реале. Запомнили? Далее...
    делаем так:
    Код:
          sbis   PortB,3   ; здесь определяем, какое состояние у бита
          rjmp   _bit_is_low   ; если бит в низком состоянии, идём его зажигать
          cbi   PortB,3   ; Иначе - гасим...
          rjmp   _bit_exit
    _bit_is_low:   sbi   PortB,3   ; зажгли бит
    _bit_exit:   ret   ; и досвидания.

    Как-то так. Но отладка всё покажет....

    _________________
    Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


    Последний раз редактировалось Горнист 09 фев 2010, 15:10, всего редактировалось 3 раз(а).

    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 01:33 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:55
    Сообщения: 5600
    Откуда: Уругвайская АССР
    Vlad777 писал(а):
    Спасибо большое! Пошел править!

    Оверквотинг нэ нада дэлат, да! А то читать неудобно.

    _________________
    Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 01:44 
    Заглядывает иногда

    Зарегистрирован: 28 янв 2010, 21:20
    Сообщения: 117
    Откуда: Днепропетровск
    ArgusB писал(а):
    Vlad777 писал(а):
    Спасибо большое! Пошел править!

    Оверквотинг нэ нада дэлат, да! А то читать неудобно.


    Виноват! Исправлюсь!
    Пошел вникать! Спасибо!!!


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 02:17 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:48
    Сообщения: 3965
    Откуда: Звенигород
    А мне avr тем и нравится, что регистров много и всегда можно найти лишний, особенно в верхней половине, для глобальной переменной. Или если глобальная не нужна, то для static переменной. Как в свое время для 90S1200 писали - 32 регистра и не одной ячейки памяти.

    _________________
    От Парижа до Находки с водкой лучше, чем без водки!


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 03:34 
    Заглядывает иногда
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:46
    Сообщения: 125
    Откуда: г. Буча, Киевская обл., Украина
    Цитата:
    neg temp ; инвертируем ВСЕ биты ...

    Чтобы получить инверсию с помощью neg, надо бы еще одиничку отнять опосля.

    neg temp
    dec temp
    neg temp ---> temp = 0x00 - temp.
    если temp = A (00001010), то neg temp ----> temp = 0x00 - A = F6 (11110110), как видно в результате чучуть не то. Отняв 1 получим точную инверсию.

    Для инверсии обычно инструкция com в ходу.
    com temp ---> temp = 0xFF-temp

    _________________
    -||devil was an angel too||-
    -||world is a ghetto||-


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 11:21 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:55
    Сообщения: 5600
    Откуда: Уругвайская АССР
    DeVOuR писал(а):
    Цитата:
    neg temp ; инвертируем ВСЕ биты ...

    Чтобы получить инверсию с помощью neg, надо бы еще одиничку отнять опосля.


    Пардоньте, ошибочку допустил-с!

    _________________
    Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 12:06 
    Заглядывает иногда

    Зарегистрирован: 28 янв 2010, 21:20
    Сообщения: 117
    Откуда: Днепропетровск
    Мне необходтмо инвертировать не ВСЕ биты а только ОДИН (выборочно)
    На Си написал PORTB ^= (1<<PB3) - и все!!! Третий бит инвертится!
    Вот такую бы краткую инструкцию на АСМе!!!! -)))


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 12:52 
    Заглядывает иногда

    Зарегистрирован: 06 фев 2010, 13:53
    Сообщения: 99
    Откуда: Tushino
    В современных AVRках для инверсии выходного бита достаточно записать "1" в соответствующий разряд регистра PIN этого же порта, в т.ч. командой SBI. Например, в Tiny13, Tiny2313 и Mega48/88/168 эта фича есть, а в Mega8 и Mega16 - нет (в даташитах надо искать раздел Toggling the Pin).

    То есть в данном случае достаточно одной команды
    SBI PINB,1<<3


    Последний раз редактировалось SVK 09 фев 2010, 13:12, всего редактировалось 2 раз(а).

    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 12:52 
    Администратор
    Аватара пользователя

    Зарегистрирован: 16 янв 2010, 06:09
    Сообщения: 6285
    Откуда: Челябинск
    А на асме то же самое.

    Что ты тут делаешь? Ты делаешь исключающее или по маске 1<<PB3

    А на асме
    IN R17,PORTB
    LDI R16,1<<PB3

    EOR R17,R16

    OUT PORTB,R17

    вот и все.

    _________________
    Хозяин дома


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 13:04 
    Заглядывает иногда

    Зарегистрирован: 28 янв 2010, 21:20
    Сообщения: 117
    Откуда: Днепропетровск
    Так я так и делал!!!

    in temp, portb
    ldi temp1, 0b00010000
    eor temp, temp1
    out portb, temp
    а мне сказали:


    Какой ужас на! Во-первых, зачем прятать в стек temp? Он же спрятан уже в процедуре обработчика прерывания. И подход к инвертированию бита странный.


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 13:42 
    Администратор
    Аватара пользователя

    Зарегистрирован: 16 янв 2010, 06:09
    Сообщения: 6285
    Откуда: Челябинск
    Да он просто испугался прятанья temp в стек :)

    _________________
    Хозяин дома


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 14:58 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:55
    Сообщения: 5600
    Откуда: Уругвайская АССР
    Vlad777 писал(а):
    Так я так и делал!!!

    in temp, portb
    ldi temp1, 0b00010000
    eor temp, temp1
    out portb, temp

    А под отладчиком этот код что выдаёт ??? (Капитан Булева Логика каг бэ говорит нам, что все прочие биты этого порта, которые были нулевыми, ВНЕЗАПНО превратятся в единичные.
    И такое поведение порта Очень Огорчает моего Горниста!
    )

    Отож.

    Я ведь комментировал все телодвижения...

    Читаем из порта, делаем копию. В копии все биты оставляем, кроме нужного нам. Его сбрасываем. Получается Дырофка (см. ниже, зачем она)
    Потом, в результате оставляем только нужный нам бит, все остальные в единицу. Далее, эту кашу инвертируем, всю. Те биты, что были не нужны, превращаются в нули, и дальнейшей рояли из кустов нам не сыграют. Нужный нам бит просто проинвертировался. Потом собираем (орим) этот результат с копией. Наш инвертированный бит спокойно проходит в заботливо сделаное для него отверстие...

    DI HALT писал(а):
    А на асме то же самое.
    Что ты тут делаешь? Ты делаешь исключающее или по маске 1<<PB3
    А на асме
    IN R17,PORTB
    LDI R16,1<<PB3
    EOR R17,R16
    OUT PORTB,R17
    вот и все.


    Кэп ехидно скалится. Горнист подавился пивом. Ну вы понели, да?

    _________________
    Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


    Последний раз редактировалось Горнист 09 фев 2010, 15:42, всего редактировалось 1 раз.

    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 15:30 
    Заглядывает иногда

    Зарегистрирован: 28 янв 2010, 21:20
    Сообщения: 117
    Откуда: Днепропетровск
    Цитата:
    Я ведь комментировал все телодвижения...
    Читаем из порта, делаем копию. В копии все биты оставляем, кроме нужного нам. Его сбрасываем. Получается Дырофка (см. ниже, зачем она)
    Потом, в результате оставляем только нужный нам бит, все остальные в единицу. Далее, эту кашу инвертируем, всю. Те биты, что были не нужны, превращаются в нули, и дальнейшей рояли из кустов нам не сыграют. Нужный нам бит просто проинвертировался. Потом собираем (орим) этот результат с копией. Наш инвертированный бит спокойно проходит в заботливо сделаное для него отверстие...


    Да я и не спорю!!!
    Сделал всеми 3-я способами - все работает!!!!!

    Я тут извращался, что бы не задействовать под счетчик (count в виде глобальной переменной) регистр старше r16.
    Как оказалось :-) с РОН<16 команда CPI не работает!
    В итоге пришлось заюзать два рег. меньше r16.
    1 для счетчика, 2-й для константы, а потом все это безобразие сравнивать командой CP

    А других, менее извращенческих способов нет????


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 15:41 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:55
    Сообщения: 5600
    Откуда: Уругвайская АССР
    СТОП! Вот это я протупил!!!
    Капитан ржётниможет, горнист интересуется у меня, где я купил этой замечательной травы.
    Записываю себе левелап в умение «нести Полную Ахинею с серьёзным видом».
    Вспомнинаю, как долго я пребывал именно в этом заблуждении...
    Ушел править несколько исходников....

    Vlad777 писал(а):
    Я тут извращался, что бы не задействовать под счетчик (count в виде глобальной переменной) регистр старше r16.
    Как оказалось :-) с РОН<16 команда CPI не работает!
    В итоге пришлось заюзать два рег. меньше r16.
    1 для счетчика, 2-й для константы, а потом все это безобразие сравнивать командой CP
    А других, менее извращенческих способов нет????


    Да, CPI нижними регистрами не работает.
    Можно поступать так:
    mov temp, r14
    cpi temp, 102
    Но тогда легче отправить счётчик в память, и пусть он там живёт.

    _________________
    Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 09 фев 2010, 22:57 
    Заглядывает иногда

    Зарегистрирован: 28 янв 2010, 21:20
    Сообщения: 117
    Откуда: Днепропетровск
    Ух!!! Че-то зацепил меня ассемблер!!! -)))
    Разбил свою тестовую прогу на куски:
    defines
    macros
    vectors
    init
    main

    А теперь попробовал сделать на 1-м таймере 3 таймера управления флаговым регистром.
    Потом в бесконечном цикле - реакция на эти флаги.
    Гляньте если не лень пожалуйста на предмет оптимальности и правильности.

    Это прерывание от таймера :

    tim0comp: push temp
    in temp, SREG ; сохряняем SREG
    push temp ;
    inc count1 ;
    inc count2
    inc count3
    cp count1, count1_end ; длина цикла1 ранее заданна
    brne endint1 ;
    clr count1
    sbr flag, 0b00000010 ; уст. флаг 1 бит1
    endint1: cp count2, count2_end ; длина цикла2 ранее заданна
    brne endint2 ;
    clr count2
    sbr flag, 0b00000100 ; уст. флаг 2 бит2
    endint2: cp count3, count3_end ; длина цикла3 ранее заданна
    brne endint3 ;
    clr count3
    sbr flag, 0b00001000 ; уст. флаг 3 бит3
    endint3: pop temp ;
    out SREG, temp ; восстанавливаем SREG
    pop temp
    reti
    ;-------------


    А это - обработка в цикле гл. проги:

    ;--------------------------- ГЛАВНАЯ ПРОГРАММА -----------------------------
    start: sei
    start1: sbrs flag, 1 ;пропустить команду если бит флага уст.
    rjmp m1
    cbr flag, 0b00000010 ;сбрасывает бит флага в 0
    rcall led1inv ;инвертируем СИД1
    m1: sbrs flag, 2 ;пропустить команду если бит флага уст.
    rjmp m2
    cbr flag, 0b00000100 ;сбрасывает бит флага в 0
    rcall led2inv ;инвертируем СИД2
    m2: sbrs flag, 3 ;пропустить команду если бит флага уст.
    rjmp m3
    cbr flag, 0b00001000 ;сбрасывает бит флага в 0
    rcall led3inv ;инвертируем СИД3
    m3: rjmp start1 ;бесконечный цикл


    Заранее спасибо,
    с ув. Владислав.


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 10 фев 2010, 00:48 
    Старожил
    Аватара пользователя

    Зарегистрирован: 26 янв 2010, 21:55
    Сообщения: 5600
    Откуда: Уругвайская АССР
    Если гашения флагов перенести вовнутрь процедур управления лампочками, то получится красиво

    start1: sbrc flag, 1 ;пропустить команду если бит флага уст.
    rcall led1inv ;инвертируем СИД1
    sbrc flag, 2 ;пропустить команду если бит флага уст.
    rcall led2inv ;инвертируем СИД2
    sbrc flag, 3 ;пропустить команду если бит флага уст.
    rcall led3inv ;инвертируем СИД3
    rjmp start1 ;бесконечный цикл

    _________________
    Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


    Вернуться к началу
     Профиль  
     
     Заголовок сообщения: Re: Переход на ASM после Си
    СообщениеДобавлено: 10 фев 2010, 01:07 
    Заглядывает иногда

    Зарегистрирован: 28 янв 2010, 21:20
    Сообщения: 117
    Откуда: Днепропетровск
    ArgusB писал(а):
    Если гашения флагов перенести вовнутрь процедур управления лампочками, то получится красиво


    Да!!! Действительно, не подумал!!!
    Спасибо!!!


    Вернуться к началу
     Профиль  
     
    Показать сообщения за:  Поле сортировки  
    Начать новую тему Ответить на тему  [ Сообщений: 20 ] 


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


    Кто сейчас на конференции

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


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

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

    Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
    Русская поддержка phpBB