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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

Valek87 писал(а):Вектора прерываний так сделать?

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

          ldi r18,0b00100111   ;разрешить прерывание компаратора (TIMSK1)
          sts 0x6F,r18
А здесь что не так?

Там делать НЕЛЬЗЯ!!!
делать надо так:
- копируешь из m324Pdef.inc таблицу описания векторов, она в самом конце
- вставляешь в свой проект
- удаляешь лишние прерывания, или за коментируй не нужные
- далее редактируешь, чтобы получилась конструкция вида:

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

;.equ   INT0addr   = 0x0002   ; External Interrupt Request 0

.org   INT1addr              ;= 0x0004   ; External Interrupt Request 1
        rjmp/jmp <ИМЯ твоего обработчика прерывания>                 ; или reti - если это "заглушка"

;.equ   INT2addr   = 0x0006   ; External Interrupt Request 2


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

          ldi r18,0b00100111   ;разрешить прерывание компаратора (TIMSK1)
          sts 0x6F,r18

здесь все нормально, за исключением абсолютного адреса а не имени TIMSK1, но это не криминал
просто ты разрешаешь прерывание а оно работать не будет, из-за таблицы векторов, в которой у тебя вектор адресуется сам на себя, т.е. 100% зависание проца.

давай дерзай потом продолжим.
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

Valek87 писал(а):Вектора прерываний так сделать?

Даже если имена векторов не заняты (INT0 например), то такая конструкция годится только для контроллеров с 2хбайтными адресами векторов. А в данном случае при появлении прерывания контроллер попадет на адрес в 2 раза меньший чем надо. Так что либо разбавлять адреса NOP-ами, либо (что более правильно) - делать через .ORG, как сказал GP1.

Valek87 писал(а):

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

          ldi r18,0b00100111   ;разрешить прерывание компаратора (TIMSK1)
          sts 0x6F,r18
А здесь что не так?

Нечитабельно же!

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

LDI R18,(1<<ICIE1)|(1<<OCIE1B)|(1<<OCIE1A)|(1<<TOIE1)
STS TIMSK1,R18
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

Engineer_Keen писал(а):Нечитабельно же!

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

LDI R18,(1<<ICIE1)|(1<<OCIE1B)|(1<<OCIE1A)|(1<<TOIE1)
STS TIMSK1,R18

Пока мучаемся с прерываниями, до этого пока еще не дошли :)))
Чем дальше, тем больше становлюсь занудой...
Изображение
Valek87
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

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

Сообщение Valek87 »

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

; ***** INTERRUPT VECTORS ************************************************
;.equ   INT0addr   = 0x0002   ; External Interrupt Request 0
.org   INT1addr   = 0x0004   ; External Interrupt Request 1
rjmp Inf
;.equ   INT2addr   = 0x0006   ; External Interrupt Request 2
;.equ   PCI0addr   = 0x0008   ; Pin Change Interrupt Request 0
.org   PCI1addr   = 0x000a   ; Pin Change Interrupt Request 1
;.equ   PCI2addr   = 0x000c   ; Pin Change Interrupt Request 2
;.equ   PCI3addr   = 0x000e   ; Pin Change Interrupt Request 3
;.equ   WDTaddr   = 0x0010   ; Watchdog Time-out Interrupt
;.equ   OC2Aaddr   = 0x0012   ; Timer/Counter2 Compare Match A
;.equ   OC2Baddr   = 0x0014   ; Timer/Counter2 Compare Match B
;.equ   OVF2addr   = 0x0016   ; Timer/Counter2 Overflow
.org   ICP1addr   = 0x0018   ; Timer/Counter1 Capture Event
.org   OC1Aaddr   = 0x001a   ; Timer/Counter1 Compare Match A
.org   OC1Baddr   = 0x001c   ; Timer/Counter1 Compare Match B
.org   OVF1addr   = 0x001e   ; Timer/Counter1 Overflow
;.equ   OC0Aaddr   = 0x0020   ; Timer/Counter0 Compare Match A
;.equ   OC0Baddr   = 0x0022   ; Timer/Counter0 Compare Match B
;.equ   OVF0addr   = 0x0024   ; Timer/Counter0 Overflow
;.equ   SPIaddr   = 0x0026   ; SPI Serial Transfer Complete
;.equ   URXC0addr   = 0x0028   ; USART0, Rx Complete
;.equ   UDRE0addr   = 0x002a   ; USART0 Data register Empty
;.equ   UTXC0addr   = 0x002c   ; USART0, Tx Complete
;.equ   ACIaddr   = 0x002e   ; Analog Comparator
;.equ   ADCCaddr   = 0x0030   ; ADC Conversion Complete
;.equ   ERDYaddr   = 0x0032   ; EEPROM Ready
;.equ   TWIaddr   = 0x0034   ; 2-wire Serial Interface
;.equ   SPMRaddr   = 0x0036   ; Store Program Memory Read
;.equ   URXC1addr   = 0x0038   ; USART1 RX complete
;.equ   UDRE1addr   = 0x003a   ; USART1 Data Register Empty
;.equ   UTXC1addr   = 0x003c   ; USART1 TX complete

Так? :)
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

:facepalm:
Компилировать не пробовали :)))
Значит так...
Таблицу скопировали, заменяем в ней .equ на .org, удаляем "= 0хАДРЕС", на следующей строке пишем RJMP/JMP на обработчик (или RETI если прерывание не задействовано)
Например:

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

; ***** INTERRUPT VECTORS ************************************************
.org  0x00 ;RESET
rjmp RESET
.org   INT0addr     ; External Interrupt Request 0
reti
.org   INT1addr     ; External Interrupt Request 1
reti
.equ   INT2addr     ; External Interrupt Request 2
reti
...
.org   OC1Aaddr   ; Timer/Counter1 Compare Match A
rjmp TIM1_COMPA
...
...
Последний раз редактировалось Engineer_Keen Пт сен 09, 2011 13:04:54, всего редактировалось 1 раз.
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

:shock: отошел на 5 минут!
Чем дальше, тем больше становлюсь занудой...
Изображение
Valek87
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

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

Сообщение Valek87 »

Сделал:

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

; ***** INTERRUPT VECTORS ************************************************
.org  0x00 ;RESET
rjmp RESET
.org   INT0addr  ; External Interrupt Request 0
reti
.org   INT1addr    ; External Interrupt Request 1
reti
.org   INT2addr     ; External Interrupt Request 2
reti
.org   PCI0addr     ; Pin Change Interrupt Request 0
reti
.org   PCI1addr     ; Pin Change Interrupt Request 1
reti
.org   PCI2addr    ; Pin Change Interrupt Request 2
reti
.org   PCI3addr   ; Pin Change Interrupt Request 3
reti
.org   WDTaddr   ; Watchdog Time-out Interrupt
reti
.org   OC2Aaddr     ; Timer/Counter2 Compare Match A
reti
.org   OC2Baddr   ; Timer/Counter2 Compare Match B
reti
.org   OVF2addr      ; Timer/Counter2 Overflow
reti
.org   ICP1addr    ; Timer/Counter1 Capture Event
reti
.org   OC1Aaddr    ; Timer/Counter1 Compare Match A
rjmp TIM1_COMPА
.org   OC1Baddr     ; Timer/Counter1 Compare Match B
reti
.org   OVF1addr    ; Timer/Counter1 Overflow
reti
.org   OC0Aaddr  ; Timer/Counter0 Compare Match A
reti
.org   OC0Baddr     ; Timer/Counter0 Compare Match B
reti
.org   OVF0addr     ; Timer/Counter0 Overflow
reti
.org   SPIaddr   ; SPI Serial Transfer Complete
reti
.org   URXC0addr    ; USART0, Rx Complete
reti
.org   UDRE0addr     ; USART0 Data register Empty
reti
.org   UTXC0addr   ; USART0, Tx Complete
reti
.org   ACIaddr    ; Analog Comparator
reti
.org   ADCCaddr    ; ADC Conversion Complete
reti
.org   ERDYaddr     ; EEPROM Ready
reti
.org   TWIaddr     ; 2-wire Serial Interface
reti
.org   SPMRaddr   ; Store Program Memory Read
reti
.org   URXC1addr   ; USART1 RX complete
reti
.org   UDRE1addr   ; USART1 Data Register Empty
reti
.org   UTXC1addr   ; USART1 TX complete
reti
Последний раз редактировалось Valek87 Пт сен 09, 2011 13:24:25, всего редактировалось 2 раза.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

Valek87 писал(а):Engineer_Keen. Чем это отличается от

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

.org   INT1addr     ; External Interrupt Request 1
reti
этого?

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

.equ   INT2addr     ; External Interrupt Request 2
reti

Хоть бы хелп по ассемблеру почитали...
.equ X=Y - определяет константу X, чтобы писать в коде не непонятное число, а осмысленное имя.
.org X - сообщает компилятору, что следующий код начинается с адреса Х (а этот адрес в данном случае определен в inc-файле, как раз через .equ).
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

:oops:
надеюсь успел удалить предыдущий пост, и никто его не прочитал
:oops:

и так

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

.equ    INT0=0x0002

присваивает метке c именем INT0 значение 2

а директива

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

.org    INT0

говорит компилятору что следующая команда располагается по адресу определенному как INT0, т.е. с адреса 0х0002

опередили :beer:
Чем дальше, тем больше становлюсь занудой...
Изображение
Valek87
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

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

Сообщение Valek87 »

Понятно теперь. Проверьте правильно ли я написал прерывания?
Последний раз редактировалось Valek87 Пт сен 09, 2011 13:30:31, всего редактировалось 1 раз.
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

Valek87 писал(а):Сделал:

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

; ***** INTERRUPT VECTORS ************************************************
.org  0x00 ;RESET
rjmp RESET
.org   INT0addr  ; External Interrupt Request 0
reti

Вот уже лучше.
Теперь компилируй, и смотри что получишь.
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

Теперь выглядит гораздо лучше...
GP1 писал(а)::oops:
надеюсь успел удалить предыдущий пост, и никто его не прочитал
:oops:

:)))
GP1 писал(а):и так

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

.equ    INT0=0x0002

присваивает метке c именем INT0 значение 2

Только может случится такое, что это имя уже используется, тогда компилятор ругнется...
Кусок INC-файла от меги324:

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

; EIMSK - External Interrupt Mask Register
.equ   INT0   = 0   ; External Interrupt Request 0 Enable
.equ   INT1   = 1   ; External Interrupt Request 1 Enable
.equ   INT2   = 2   ; External Interrupt Request 2 Enable

Если случилось - изобретаем другое имя.
Valek87
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

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

Сообщение Valek87 »

del
Последний раз редактировалось Valek87 Пт сен 09, 2011 13:39:23, всего редактировалось 1 раз.
Valek87
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

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

Сообщение Valek87 »

А ничего хорошего не получилось. (хотя компиляция прошла удачно) Мне кажется он до TIM1_COMPA вообще не доходит.(

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

; ******************************************************
; BASIC .ASM template file for AVR
; ******************************************************

#include "m324Pdef.inc"
.def  temp=r16
.def  temp1=r17
.def  temp2=r18
.def  temp3=r19
.def  temp4=r20
.cseg
.org 0
   
; ***** INTERRUPT VECTORS ************************************************
.org  0x00 ;RESET
rjmp RESET
.org   INT0addr  ; External Interrupt Request 0
reti
.org   INT1addr    ; External Interrupt Request 1
reti
.org   INT2addr     ; External Interrupt Request 2
reti
.org   PCI0addr     ; Pin Change Interrupt Request 0
reti
.org   PCI1addr     ; Pin Change Interrupt Request 1
reti
.org   PCI2addr    ; Pin Change Interrupt Request 2
reti
.org   PCI3addr   ; Pin Change Interrupt Request 3
reti
.org   WDTaddr   ; Watchdog Time-out Interrupt
reti
.org   OC2Aaddr     ; Timer/Counter2 Compare Match A
reti
.org   OC2Baddr   ; Timer/Counter2 Compare Match B
reti
.org   OVF2addr      ; Timer/Counter2 Overflow
reti
.org   ICP1addr    ; Timer/Counter1 Capture Event
reti
.org   OC1Aaddr    ; Timer/Counter1 Compare Match A
rjmp TIM1_COMPA
.org   OC1Baddr     ; Timer/Counter1 Compare Match B
reti
.org   OVF1addr    ; Timer/Counter1 Overflow
reti
.org   OC0Aaddr  ; Timer/Counter0 Compare Match A
reti
.org   OC0Baddr     ; Timer/Counter0 Compare Match B
reti
.org   OVF0addr     ; Timer/Counter0 Overflow
reti
.org   SPIaddr   ; SPI Serial Transfer Complete
reti
.org   URXC0addr    ; USART0, Rx Complete
reti
.org   UDRE0addr     ; USART0 Data register Empty
reti
.org   UTXC0addr   ; USART0, Tx Complete
reti
.org   ACIaddr    ; Analog Comparator
reti
.org   ADCCaddr    ; ADC Conversion Complete
reti
.org   ERDYaddr     ; EEPROM Ready
reti
.org   TWIaddr     ; 2-wire Serial Interface
reti
.org   SPMRaddr   ; Store Program Memory Read
reti
.org   URXC1addr   ; USART1 RX complete
reti
.org   UDRE1addr   ; USART1 Data Register Empty
reti
.org   UTXC1addr   ; USART1 TX complete
reti
;****************************************************
; ИНИЦИАЛИЗАЦИЯ
;****************************************************
Reset:    ldi r16,0b01111111 ;настройка PORTD
          out portd,r16

         ldi r16,0b00000100 ;загрузка указателя стека
          out $3E,r16
          ldi r16,0b10111111 ;загрузка указателя стека
          out $3D,r16

          ldi r18,0b00100111   ;разрешить прерывание компаратора (TIMSK1)
          sts 0x6f,r18

          ldi Temp,0b00000101   ;тактовый сигнал = CK/1024 (TCCR1B)
          sts 0x81,Temp

          ldi Temp,0x4E         ;инициализация компаратора
          sts 0x89,Temp       ;(OCR1AH)
          ldi Temp,0x20
          sts 0x88,Temp       ;(OCR1AL)

          ldi Temp1,0b00000100  ;инициализация индикатора

          ldi Temp,0            ;обнуление таймера
          sts 0x85,Temp       ;(TCNT1H)
        sts 0x84,Temp       ;(TCNT1L)

          sei                   ;разрешить прерывания
;****************************************************
; ОСНОВНОЙ ЦИКЛ
;****************************************************
Inf:

     rjmp Inf              ;бесконечный цикл
;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************
TIM1_COMPA:
         ldi Temp,0            ;обнуление таймера
         sts 0x85,Temp
       sts 0x84,Temp

Shift:   cpi Temp1,0b00000000  ;сравнить с 0
         breq Init             ;если равно - загрузка нач. знач.

         ldi Temp1,0b00000000 
         rjmp Output           ;перейти на вывод в порт

Init:    ldi Temp1,0b00000100  ;загрузить нач. значение
Output:  out portd,Temp1       ;вывод в порт D

         reti                  ;выход из обработчика
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

А вот теперь самое интересно :wink:
тут возможны варианты:
1. неправильный алгоритм
2. ты где-то напутал с абсолютными адресами (вспоминаем что говорилось об именах портов и перифирии)

или просто ты не дождался прерывания, у тебя же стоит предделитель 1/1024

и еще, лимит "разжевываний" у меня ограничен :wink: :tea: , поэтому прежде чем задавать очередной вопрос прогони прогу в пошаговом режиме, посмотри как меняются значения регистров, а потом задавай вопрос конкретно, а просто "ни чего не работает", к рассмотрению приниматься не будет :kill: :kill: :kill:
Последний раз редактировалось GP1 Пт сен 09, 2011 13:55:34, всего редактировалось 3 раза.
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

Valek87 писал(а):А ничего хорошего не получилось. (хотя компиляция прошла удачно) Мне кажется он до TIM1_COMPA вообще не доходит.(

Это почему так кажется?
PD2 мигает с периодом 5с (тактовая 8Mhz)... Только вот его наверно еще надо на выход настроить...
Ага, скорее всего просто долго симуляция проходит, поэтому кажется что ничего не работает, а надо повнимательнее на регистры смотреть и использовать точки останова...
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

Engineer_Keen писал(а):
GP1 писал(а):сравнение temp1 с 0 я вижу, а вот чтобы ты его где-то менял не нашел, я не имею ввиду присвоения значений внутри прерывания.

Я тоже не сразу нашел :)))

я уже понял что косяк и удалил.
никогда до такого изврата, в плане

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

Shift:   cpi Temp1,0b00000000  ;сравнить с 0
         breq Init             ;если равно - загрузка нач. знач.

         ldi Temp1,0b00000000 
         rjmp Output           ;перейти на вывод в порт

Init:    ldi Temp1,0b00000100  ;загрузить нач. значение


для установки/сброса бита РВВ не додумывался. :)))
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

GP1 писал(а):никогда до такого изврата для установки/сброса бита РВВ не додумывался. :)))

Я по началу и не такого мог наваять :oops: А теперь понимаю что эти 6 строк можно заменить одной :)))
Последний раз редактировалось Engineer_Keen Пт сен 09, 2011 14:12:25, всего редактировалось 1 раз.
Valek87
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

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

Сообщение Valek87 »

Ну да. Сейчас сам увидел, что бит сбрасывается. Теперь буду пробовать на железке. Всем большое спабо за помощь.

И еще такой маленький вопрос: есть кусок программки (

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

Choose_voltage:
  cpi r17, 0b00000000
  breq  V4 ;breq - переход, если равно
  rjmp F4
V4:           ;установка второго уровня
  cbi 0x0B,5   ;сброс U0
  sbi 0x0B,6   ;установка U1
  inc r17
  ret
F4:
  cpi r17, 0b00000001
  breq  V3
  rjmp F3
V3:           ;установка третьего уровня
  sbi 0x0B,5   ;установка U0
  cbi 0x0B,6   ;сброс U1
  inc r17
  ret
F3:
  cpi r17, 0b00000010
  breq  V2
  rjmp F1
V2:           ;установка четвертого уровня
  sbi 0x0B,5   ;установка U0
  sbi 0x0B,6   ;установка U1
  inc r17
  ret
F1:           ;установка первого уровня
  cbi 0x0B,5   ;сброс U0
  cbi 0x0B,6   ;сброс U1
  clr r17
  ret)
. Куда мне необходимо вставить эту программу, чтобы они (таймер и выше упомянутая) работали совместно?
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

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

Сообщение GP1 »

Судя по этому:

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

Choose_voltage:
... 
...
ret

обычная подпрограмма вставляешь в любом месте после основного цикла.
и в нужное время просто вызываешь командой

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

call   Choose_voltage 

или

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

rcall   Choose_voltage 

если она не очень "далеко"

сразу же одно замечание:
вызывать п/п из прерывания - дурной тон, не делай так. :)
Чем дальше, тем больше становлюсь занудой...
Изображение
Ответить

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