Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Coldheart писал(а):Способы, варианты итд.

Способов как минимум два:
1) ветвление по состоянию бита (sbic, sbis)
2) логическое "И" содержимого порта (регистра) с константой (00010000) с последующим сравнением с константой (cpi), либо с содержимым другого регистра с ветвлением (cpse).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Alexeyslav »

Сравнивать надо с нулем - это сравнение происходит сразу в момент применения функции "И". Если там не будет "1" в порту, то результат функции "И" будет нулевой, иначе - не нулевой.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

а как насчет использовать " PCINT15:Pin Change Interrupt 2, Source 15 " ? :tea:
Аватара пользователя
Coldheart
Прорезались зубы
Сообщения: 244
Зарегистрирован: Пт сен 10, 2010 20:39:32
Откуда: Украина Луганская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Coldheart »

Спасибо большое, со всем разобрался!
Клацает как я и хотел! :solder:
Теперь подобный вопрос. Возникает чувство что начинаю изобретать велосипед. :)
Как проверить состояние ножки контроллера по спадающему или восходящему фронту импульса?(И при этом не использовать таймеры, хотя они как раз и для таких случаев предназначены)
Т.е. нажимаем на кнопочку, действие выполняется, и оно опять не выполнится пока мы её не отпустим и обратно не нажмем.
Представляется опять такой алгоритм с использованием команд 8-10 и 3х регистров как минимум )
Или, скоре всего, без таймера и прерываний здесь совсем не обойтись.
Реклама
Эиком - электронные компоненты и радиодетали
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Alexeyslav »

Для этого нужно хранить предыдущее состояние кнопки где-то.
Тогда у нас в момент проверки возможны только 4 состояния: нажата-отпущена, отпущена-отпущена, отпущена-нажата и нажата-нажата. Соответственно, нас интересуют 1 и 3-е состояние.
После проверки, состояние кнопки просто скопировать в предыдущее, независимо от состояния.
Если предыдущее состояние хранить в том же бите что и регистр порта, можно будет использовать XOR и последующий AND чтобы выявить моменты 1 и 3-го состояния, и передать управление на подпрограмму которая определяет что делать по нажатию кнопки или по отпусканию.

Можно то же самое сделать используя прерывания. Разрешать их не обязательно - можно настроить порт на прерывание по изменению уровня и смотреть признак прерывания, хоть оно и будет запрещено - признак все равно работает, главное не забывать его сбрасывать. И тут так же надо иметь в виду, что между установкой этого признака и моментом считывания состояния порта с целью определить направление нажатия проходит некоторое время, за которое уровень на выводе контроллера вполне может изменится. Тогда возникает ситуация было "0", возник признак прерывания считываешь порт, а там снова "0". Имеем вместо регистрации реального события 0->1 подразумеваем что возникло событие 1->0 так как предыдущее значение нигде не сохраняется для анализа, а если и сохраняется то смысл городить огород с прерываниями.

2 и 4 состояние можно использовать для реализации автоповтора. Когда видим в результате проверки 4-е состояние, декрементируем счетчик и когда он доходит до нуля выполняем нужное действие как будто по 3-му или 1-му состоянию. И соответственно в 1 и 3-м состоянии устанавливаем этот счетчик некоторой константой - чем меньше число тем чаще повтор.
Реклама
Аватара пользователя
Coldheart
Прорезались зубы
Сообщения: 244
Зарегистрирован: Пт сен 10, 2010 20:39:32
Откуда: Украина Луганская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Coldheart »

что-то немного запутался
надо учесть что все это во время работы генерит динамичесую индикацию
Если кратко говорить то в результате должен получиться счетчик на 4 разряда


Код: Выделить всё

Display:
   clr r16
   in r16,PinD; считываем порт в R16
   mov r3,r16, записываем R16 в R3
   sbrc r16,4; проверяем 5-ю ножку на высокий уровень
   rcall InfCycle; если он там есть, то переходим на  InfCycle
   
uu:
          ldi R17,0b00001110 ; Включаем катод первого                     
          out PortD,R17
          mov R22,r23; пересылаем из регистра первого разряда в регистр адреса декодера
          rcall Decoder    ; конвертируем в бинарный код   
          out PortB,R17      ; выводим на порт
          rcall Delay1         ; задержка
     
          Далее все также с еще 3-мя разрядами
   
   rjmp display
   
      
            

Decoder:
            

          ldi ZL,Low(DcMatrix*2)
          ldi ZH,High(DcMatrix*2)
        ldi R18,0
         ;ldi R22,1         
          add ZL,R22           
          adc ZH,R18

          lpm                   
          mov R17,r0
       
        ret


InfCycle:
              clr r16
   in r16,PinD
   eor r16,r3
   sbrs r16,4
   rjmp big
   clr r3
   ret
big:
   sts digit,r23   
   inc r23
   cpi r23,10
   breq M
   ret
M:
   clr r23
   ret

DcMatrix:
              ;     hgfedcba   hgfedcba
          .db 0b00111111,0b00000110   ;0,1
          .db 0b01011011,0b01001111   ;2,3
          .db 0b01100110,0b01101101   ;4,5
          .db 0b01111101,0b00000111   ;6,7
          .db 0b01111111,0b01101111   ;8,9
         
Delay1:                        ; задержка
           ldi R20,20
           ldi R21,11
d11:       
         dec R20
           brne d11
           dec R21
           brne d11
           ret

Реклама
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Coldheart писал(а): clr r16
in r16,PinD; считываем порт в R16

Нет смысла обнулять регистр перед закидыванием в него значения.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Coldheart
Прорезались зубы
Сообщения: 244
Зарегистрирован: Пт сен 10, 2010 20:39:32
Откуда: Украина Луганская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Coldheart »

Gudd-Head писал(а):Нет смысла обнулять регистр перед закидыванием в него значения.


R16м я там настраиваю порты. НО там еще много бредятины. Которая вылезла в процессе экспериментов
А потом не была убрана так как вроде не мешала

вопрос собственно по этим строчкам

раз:
in r16,PinD; считываем порт в R16
mov r3,r16, записываем R16 в R3
sbrc r16,4; проверяем 5-ю ножку на высокий уровень
rcall InfCycle; если он там есть, то переходим на InfCycle

и два:
in r16,PinD; считыаем портD в r16
eor r16,r3 ; исключющее или между r3 и r16
sbrs r16,4 ; проверяем 4-й бит
rjmp big ; если не установлен то переходим на подпрограмму увеличения адреса масиива
clr r3
ret
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Необязательно скидывать весь порт в регистр чтобы проверить один бит — для этого есть команды sbic и sbis.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение zero648 »

Не могу вытащить проц из спящего режима POWER-DOWN, подключена кнопка к INT1, не пойму в чем проблема?

Код: Выделить всё

            .include "m16def.inc"     ; Используем ATMega16
; ROM ===============

            .CSEG                     ; ROM
            .org $000

            jmp RESET                 ; External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            .org $002
            jmp EXT_INT0              ; INT0          Внешнее прерывание 0
            reti                      ; INT1          Внешнее прерывание 1
            reti                      ; TIMER2 COMP   Совпадение таймера/счетчика Т2
            reti                      ; TIMER2 OVF    Переполнение таймера/счетчика Т2
            reti                      ; TIMER1 CAPT   Захват таймера/счетчика Т1
            .org $00C
            jmp TMR1_COMPA            ; TIMER1 COMPA  Совпадение «А» таймера/счетчика Т1
            .org $00E
            jmp TMR1_COMPB            ; TIMER1 COMPB  Совпадение «В» таймера/счетчика Т1
            reti                      ; TIMER1 OVF    Переполнение таймера/счетчика Т1
            reti                      ; TIMER0 OVF    Переполнение таймера/счетчика Т0
            reti                      ; SPI, STC      Передача по SPI завершена
            reti                      ; USART,RXC     USART, прием завершен
            reti                      ; USART,UDRE    Регистр данных USART пуст
            reti                      ; USART,TXC     USART, передача завершена
            reti                      ; ADC           Преобразование АЦП завершено
            reti                      ; EE_RDY        EEPROM, готово
            reti                      ; ANA_COMP      Аналоговый компаратор
            reti                      ; TWI           Прерывание от модуля TWI
            reti                      ; INT2          Внешнее прерывание 2
            .org $026
            jmp TMR0_COMP             ; TIMER0 COMP   Совпадение таймера/счетчика Т0
            reti                      ; SPM_RDY       Готовность SPM
           
INIT_ports:       
            ldi     r16, 0b01000011
            out     DDRD, r16
            ldi     r16, 0b00111000
            out     PORTD, r16

            ldi     r16, (1<<INT1)    ; Включаем прерывание INT1
            out     GICR,r16
            ldi     r16, (1<<SE)|(0<<SM2)|(1<<SM1)|(0<<SM0)|(0b10<<ISC10)
            out     MCUCR, r16
            sei
            sleep
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

zero648 писал(а):не пойму в чем проблема?

...Видимо в строчках кода, которые здесь не приведены...
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение zero648 »

В каком коде, в том то и дело, что после команды SLEEP программа не двигается, из режима IDLE выходит и прога дальше работает, а после POWER-DOWN стоит на месте.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Вы включаете INT1, в коде прыжок на обработчик INT0, которого не видно. Чего вы хотите? К тому же, что у вас после команды sleep? Ничего?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение zero648 »

У меня кнопка на INT1, в таблице векторов на INT1 команда RETI, INT0 не смотрите, там свой обработчик.
Вот дальше такой код:

Код: Выделить всё

INIT_adc:
            ldi     r16, (1<<ADLAR)|(0b00111<<MUX0); ADC left, ADC7 as input (SENSOR_1)
            out     ADMUX, r16                     ; AREF, Internal Vref turned off
            ldi     r16, (1<<ADEN)|(0b100<<ADPS0)  ; Enable ADС, ADC Prescaler = 1:16
                                         ; 000=1:2,001=1:2,010=1:4,011=1:8,100=1:16,
                                         ; 101=1:32,110=1:64,111=1:128.
            out     ADCSRA, r16   

INIT_variables:
            ldi     ZL, low(CHAR_GNR*2)  ; Знакогенератор
            ldi     ZH,high(CHAR_GNR*2)  ;

            ldi     YL, low(VARIABLES)   ; Адрес таблицы переменных
            ldi     YH,high(VARIABLES)   ;

            ldi     r17, low(SCL_TYP_EP)
            ldi     r18,high(SCL_TYP_EP)
            call    EEPROM_read
            std     Y+$3e, r16           ; store SCALE_TYPE
           ...
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

zero648 писал(а):У меня кнопка на INT1

:facepalm: нашёл я вашу ошибку кажется.
RTFM
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

Да, да. Она все-таки есть в приведенном вначале коде, и именно из-за невнимательного чтения даташита... Но ведь не факт, что именно он выполняется в качестве инициализации, ведь программа вначале прыгает на метку reset, а вот код, который с нее начинается как раз и не выложен.
Последний раз редактировалось Engineer_Keen Пн окт 08, 2012 10:58:19, всего редактировалось 1 раз.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Engineer_Keen писал(а):программа вначале прыгает на метку reset, а вот код, который с нее начинается как раз и не выложен.

Таки да, лол.
А ещё reti в векторе прерываний, хотя у 16-й Меги на каждое прерывание отведено по 2 слова (4 байта). Т.е. на самом деле всё выглядит так:

Код: Выделить всё

 .org $000

            jmp RESET                 ; External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            .org $002
            jmp EXT_INT0              ; INT0          Внешнее прерывание 0
            reti                      ; INT1          Внешнее прерывание 1
            reti                      ;
            reti                      ; TIMER2 COMP   Совпадение таймера/счетчика Т2
            reti                      ;
...
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

Короче, если не нашли в даташите - из power-down выходят только по прерыванию по уровню, т.е. в ISC нужно писать "00"
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение zero648 »

Gudd-Head писал(а):А ещё reti в векторе прерываний, хотя у 16-й Меги на каждое прерывание отведено по 2 слова (4 байта). Т.е. на самом деле всё выглядит так:

Код: Выделить всё

 .org $000

            jmp RESET                 ; External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            .org $002
            jmp EXT_INT0              ; INT0          Внешнее прерывание 0
            reti                      ; INT1          Внешнее прерывание 1
            reti                      ;
            reti                      ; TIMER2 COMP   Совпадение таймера/счетчика Т2
            reti                      ;
...

По большому счету это не важно, процессор все равно попадает на команду RETI, тем более перед ним стоит команда абсолютного перехода, которая занимает свои четыре байта и смещает команду на свой адрес.
По ресету ничего сверхестественного, установка вершины стека и обнуление регистров РОН
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение zero648 »

Engineer_Keen писал(а):Короче, если не нашли в даташите - из power-down выходят только по прерыванию по уровню, т.е. в ISC нужно писать "00"

Engineer_Keen респект и уважуха, сразу то нельзя было сказать, а то код, код :beer:
Теперь робит.

Код: Выделить всё

            ldi     r16, (1<<SE)|(0<<SM2)|(1<<SM1)|(0<<SM0)|(0b00<<ISC10)
Ответить

Вернуться в «AVR»