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

Обсуждаем контроллеры компании Atmel.
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

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

Сообщение ПТУ-шник »

СКАЗОЧНИК писал(а):
По первому вопросу не могу ниче вразумительного сказать. Вообще-то так не принято. Все делают бесконечный цикл. Может ваш компилятор посчитал, что его надо вставить и сделал это сам. Может так и есть, если дошел до конца памяти, то прыгает на начало (или сбрасывается, что скорее всего). Однако, это сильно криво, так делать. :dont_know:


Компилятор из AVR Studio 4. Кодил в ней, результат тот же.


На кнопку реагирует нормально. Хоть как жмякай. У меня attiny13 работает от встроенного генератора по умолчанию, во фьюзы пока не лазию.
Shark-vc
Родился
Сообщения: 6
Зарегистрирован: Сб дек 05, 2015 23:21:05

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

Сообщение Shark-vc »

Народ, помогите пожалуйста, пытаюсь подключить ЖКИ HD44780 к ATmega8535 , вроде собрал правильно, но все равно не работает, мб в коде ошибка? Вроде делаю все по инструкции

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

   #define RS 2                     
   #define e  3

;НАСТРОЙКА И ВЫВОД НА ЖКИ----------------------------------------------------------------------
   ser temp
   out DDRA,temp        ;порт РА на вывод
   ldi temp,$0C        ;PC0-PC1,PD4 на ввод
   out PORTC,temp
   rcall delay2ms
   ldi acc,$38      ;8-битовый режим вывода,
   rcall lcdcom      ;2 строки, шрифт 5х7
   ldi acc,$06      ;Направление сдвига курсора вправо, без сдвига дисплея
   rcall lcdcom
   ldi acc,$0C      ;включить дисплей
   rcall lcdcom      ;погасить курсор
   ldi acc,$01      ;Очистить дисплей и установить курсор в нулевую позицию
   rcall lcdcom
   rcall delay2ms
   ldi     acc,0x31   ; загрузить цифру "1" в регистр lcd
   rcall lcddat
 rjmp Loop
 
     ;Подпрограмма вывода на дисплей байта данных
lcddat:
   out PORTA,acc      ;вывод символа
   ldi temp,0x04      ;установка режима записи данных E=1
   out PORTC,temp
   cbi PORTC,e      ;фронт 1/0 строба
   rcall delay40us
   ret
 
     ;Подпрограмма вывода на дисплей байта команды
lcdcom:
   out PORTA,acc      ;вывод команды
   ldi temp,0x08      ;установка режима записи команд
   out PORTC,temp
   ldi temp,0x04      ;установка режима записи команд E=1
   out PORTC,temp
   cbi PORTC,e      ;фронт 1/0 строба
   rcall delay40us
   ret
Вложения
Безымянный.png
СХЕМА
(84.68 КБ) 435 скачиваний
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Поправил. Не хотел писать пп DELAY, поэтому закомментировал их.
Спойлер

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

   .include "m8535def.inc"

.equ   RS=2                     
.equ   E=3
;   #define RS 2                     
;   #define E  3
.def   TEMP=R16
.def   ACC=R17

   LDI   ZH,HIGH(RAMEND)
   LDI   ZL,LOW(RAMEND)
   OUT   SPH,ZH
   OUT   SPL,ZL



;НАСТРОЙКА И ВЫВОД НА ЖКИ----------------------------------------------------------------------
   ser temp
   out DDRA,temp        ;порт РА на вывод
   LDI   R22,1<<RS|1<<E
   OUT   DDRC,R22

;   ldi temp,$0C        ;PC0-PC1,PD4 на ввод???
;   out PORTC,temp ;PC0-PC1,PD4 на вЫвод???

;   rcall delay2ms
   ldi acc,$38      ;8-битовый режим вывода,
   rcall lcdcom      ;2 строки, шрифт 5х7
   ldi acc,$06      ;Направление сдвига курсора вправо, без сдвига дисплея
   rcall lcdcom
   ldi acc,$0C      ;включить дисплей
   rcall lcdcom      ;погасить курсор
   ldi acc,$01      ;Очистить дисплей и установить курсор в нулевую позицию
   rcall lcdcom
;   rcall delay2ms
   ldi     acc,0x31   ; загрузить цифру "1" в регистр lcd
   rcall lcddat
LOOP:
 rjmp Loop
 
     ;Подпрограмма вывода на дисплей байта команды
lcdcom:
   CBI   PORTC,RS      ;установка режима записи команд
   RJMP   LCDDAT+1

     ;Подпрограмма вывода на дисплей байта данных
lcddat:
   SBI   PORTC,RS      ;установка режима записи данных
   RCALL   PAUSE_RET
   SBI   PORTC,E
   RCALL   PAUSE_RET
   out PORTA,acc      ;вывод символа
   RCALL   PAUSE_RET
   CBI   PORTC,E
;   ldi temp,0x04      ;установка режима записи данных E=1
;   out PORTC,temp
;   cbi PORTC,e      ;фронт 1/0 строба
;   rcall delay40us
PAUSE_RET:
   ret
 

Инициировать дисплей желательно без отступлений от DS
Аватара пользователя
Flash.#13
Держит паяльник хвостом
Сообщения: 965
Зарегистрирован: Сб апр 12, 2014 23:46:03
Откуда: Киев

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

Сообщение Flash.#13 »

Здравствуйте товарищи, возникла накладка с АЦП. Настроил ADCSRA, настроил ADMUX, Ref прописал питание +5В, замер делается нормально. Затем следующий замер Ref прописываю внутренний 2.56В, делаю два замера с задержкой для отсева переключения, а на выходе бяка. Щупаю тестером ножку Aref а там и близко не пахнет 2.56В, как быть?

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

...
ldi R16, 0b01000000   ;РС0, +5VCC
out ADMUX, R16
sbi ADCSRA,6      ;старт замера АЦП
rcall delay40mks
rcall delay40mks
rcall delay40mks
rcall delay40mks
sbi ADCSRA,6      ;старт замера АЦП, х2 для точности, все ок
...
ldi R16, 0b11000000   ;РС0, +2.56V internal source
out ADMUX, R16
sbi ADCSRA,6      ;старт замера АЦП
rcall delay40mks
rcall delay40mks
rcall delay40mks
rcall delay40mks
sbi ADCSRA,6      ;старт замера АЦП, х2
//и ничего, нету 2.56 на ноге Aref, и замер чего-попало
Немного файлов по зажиганию: ФУОЗ 2.2 + программа правки таблиц 0.987, монтажка
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

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

Сообщение ПТУ-шник »

Как настроить таймер в Attiny13 в ассемблере? Я пытаюсь сделать так:

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

LDI temp, 0b00000001
OUT TIMSK, temp ;  Разрешение прерывания от таймер TIM0
LDI temp, 0b00000101
OUT TCCR0, temp ; установка пред. делителя

temp это переменная R16 в РОН.

Такая программа даже не компилируется. Примерно понял почему она не работает - регистр TIMSK однобитный, остальные 7 бит к шине не подключены поэтому туда никакие значения запихнуть нельзя. И как быть?

Видел такой пример:

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

ldi temp,(1<<TOIE0) ;разр. прерывания Timer0
out TIMSK,temp

Но не очень понимаю как это работает. Вроде тоже самое что и у меня. Вот эту скобку (1<<TOIE0) я вообще не понимаю. Зачем то сдвиг числа сюда запихнули. Я знаю что TOIE0 это тот бит который нужно установить в «1» но как тут к нему обратились?
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

Такая программа даже не компилируется.
На что ругается?
Примерно понял почему она не работает - регистр TIMSK однобитный
Не угадали, в AVR все регистры 8-битные. Может, кроме совсем уж внутренних, к которым нет прямого доступа.
Вот эту скобку (1<<TOIE0) я вообще не понимаю.
Это хороший тон форматирования - не использовать магических чисел, а использовать именованные константы. Совсем хорошо, когда константы поименованы разработчиком системы, как здесь. Суть всего лишь в установке бита номер TOIE0, то есть с точки зрения компилятора не отличается от вашей записи.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

ПТУ-шник писал(а):Видел такой пример:

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

ldi temp,(1<<TOIE0) ;разр. прерывания Timer0
out TIMSK,temp

Но не очень понимаю как это работает. Вроде тоже самое что и у меня. Вот эту скобку (1<<TOIE0) я вообще не понимаю. Зачем то сдвиг числа сюда запихнули. Я знаю что TOIE0 это тот бит который нужно установить в «1» но как тут к нему обратились?

TOIE0 - это просто номер бита в регистре. Ничего там на самом деле не двигается, просто такая запись говорит компилятору : " Установи в temp бит номер такой-то в 1" . А не компилироваться может вот почему: в разных поколениях АВРок регистры могут быть в разных диапазонах адресов, что, конечно, нехорошо. Поэтому то, что в одном МК проходит как OUT, в другом выглядие как STS, потому что не входит в диапазон адресов, к которым допустима команда OUT. Конкретно мы ничего не знаем о типе обсуждаемого тут МК, да и по ДШ шарить - мне лениво. Но это одна из версий.
Изображение
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

ПТУ-шник писал(а):Как настроить таймер в Attiny13 в ассемблере? Я пытаюсь сделать так:

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

LDI temp, 0b00000001
OUT TIMSK, temp ;  Разрешение прерывания от таймер TIM0
LDI temp, 0b00000101
OUT TCCR0, temp ; установка пред. делителя

Такая программа даже не компилируется.
Естественно, не должна, т.к. TOIE0 у ATtiny13 стоит в другом месте. А когда командуете (1<<TOIE0), то ассемблер сам определяет положение этого бита.
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

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

Сообщение ПТУ-шник »

akl писал(а):
ПТУ-шник писал(а):Как настроить таймер в Attiny13 в ассемблере? Я пытаюсь сделать так:

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

LDI temp, 0b00000001
OUT TIMSK, temp ;  Разрешение прерывания от таймер TIM0
LDI temp, 0b00000101
OUT TCCR0, temp ; установка пред. делителя

Такая программа даже не компилируется.
Естественно, не должна, т.к. TOIE0 у ATtiny13 стоит в другом месте. А когда командуете (1<<TOIE0), то ассемблер сам определяет положение этого бита.

Хм. Именно в этом случае ему оказывается без разницы. Ошибка: TIMSK это неверное название, надо TIMSK0. Пробывал устанавливать нулевой бит, компилятор молчит.

А вот с TCCR0 всё равно ругаеться, пишет что и раньше: Undefined variable referenced. Тобишь недопустимый адрес как я понял.

По совету поставил за место out, sts и ошибок вылезло ещё больше :o

Всё равно не понял эту (1<<TOIE0) команду. Можете объяснить по подробней? Хочу более глубинно понять что происходит внутри, а то этот << арифметический сдвиг меня смущает. И почему эта команда в скобках? Это макрос какой то? Хочу видеть исходник если это макрос.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

Как-то так работал с таймером на ТИНИ13... Не помню уже чего там понакалякал... :))) Но что-то даже работало.
Спойлер

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

; ******************************************************
; * Автор: СКАЗОЧНИК                            *                           
; * Дата: 10.10.2014                                   *                                             
; * Версия: 140831                                     *                                           
; * Имя файла: ИК управление                      *                                     
; * Для AVR: ATTiny13                                  *                                                   
; * Тактовая частота: 9,6 MHz                        *
; * Среда разработки: AVR Studio 4.12               *
; *                                          *
; * Выполняемые функции:                           *
; *                                            *
; *                                           *
; ******************************************************

; ================
; ПОДКЛЮЧАЕМЫЕ БИБЛИОТЕКИ (.include)
; ================

   .include "tn13def.inc"   

; ============
; ТИП МИКРОКОНТРОЛЛЕРА (.device)
; ============

   .device ATtiny13
 
; =================
; ОБЪЯВЛЕНИЯ И КОНСТАНТЫ (.def, .equ)
; =================
 
   .def   temp = R16
   .def   TIME = R17   
   .def   FLAG = R18
   .def   LADR = R19
   .def   HADR = R20
   .def   LCMD = R21
   .def   HCMD = R22
   .def   CNT = R23
   .def    RUN = R24
   .def   SCREEN = R25
   .def    YYY   = R26
         
; ====
; МАССИВЫ И Т.Д. (.eseg) EEPROM (.db, .dw)
; ====
   
   .eseg

; =================
; МАКРОСЫ (.MACRO)
; =================

   .MACRO PUSHF   ; Положить СРЕГ в стек
      push r16
      in r16, SREG
      push r16
   .ENDM

   .MACRO POPF      ; Достать СРЕГ из стека
      pop r16
      out SREG, r16
      pop r16
   .ENDM

; ******************************
; НАЧАЛО ПРОГРАММЫ (.cseg) FLASH
; ******************************
   
   .cseg

; ----------
; ВЕКТОРЫ ПРЕРЫВАНИЙ
; ----------
   
   rjmp RESET          ; Reset Handler
    rjmp INT0add       ; External Interrupt0 Handler
    rjmp PCI0add       
    rjmp OVF0add    
    rjmp ERDYadd    
   rjmp ACIadd      
   rjmp OC0Aadd    
   rjmp OC0Badd    
   rjmp WDTadd   
   rjmp ADCCadd    
   
      ;RESET:       ; Reset Handler
      ;INT0add:       ; External Interrupt0 Handler
      PCI0add:       
      OVF0add:    
      ERDYadd:    
      ACIadd:       
      OC0Aadd:    
      OC0Badd:    
      WDTadd:    
      ADCCadd:    
   
   reti         ; Выход из прерываний, которые не используются

; ----------
; ОБРАБОТЧИКИ ПРЕРЫВАНИЙ
; ----------
      
   INT0add:

      PUSHF
         
         in TIME, TCNT0      ; Закидываем в Тайм значение счетчика, будем использовать его позже
         clr temp
         out TCNT0, temp      ; Первоначально очищаем счетный регистр раймера
         inc CNT   
         ldi YYY, 1
      
      POPF
      
   reti                  ; Выходим из прерывания

;   OVF0add:

;      inc CNT

;   reti

; **************************************************************************************************
; ИНИЦИАЛИЗАЦИЯ МК (логическое начало основной программы) ******************************************
; **************************************************************************************************

;           --------- конфигурация портов ----------           

   Reset:   ldi temp, (1<<PB4)|(1<<PB3)|(0<<PB2)|(0<<PB1)|(0<<PB0)         ; Конфигурация порта
         out DDRB, temp   

         ldi temp, (0<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
         out PORTB, temp

         ldi temp, (1<<INT0)      ; Разрешить прерывание
         out GIMSK, temp

         ldi temp, (1<<ISC01)|(0<<ISC00)         ; Настраиваем прерывание по низкому уровню (на ИНТ0)
         out MCUCR, temp
         
         ldi temp, low(RAMEND)   ; Загрузка указателя стека
         out SPL, temp
         
         ldi temp, 0x00         ; Конфигурация таймера
         out TCCR0A, temp
         ldi temp, (1<<CS02)|(0<<CS01)|(1<<CS00)   ; Тактовый сигнал = CK/1024 (ЗАПУСКАЕМ ТАЙМЕР)
           out TCCR0B, temp

         clr FLAG            ; Просто очищаем
         clr TIME
         clr CNT
         clr RUN
         clr SCREEN
         clr YYY
          
;           ---------- разрешение прерываний ----------         

         sei                  ; Разрешаем прерывания   

; *******************************************************************************************************************
; ОСНОВНАЯ ПРОГРАММА (основной цикл) ********************************************************************************
; *******************************************************************************************************************

   Start:   
      
      cpi YYY, 1
      brbs SREG_Z, KOD
      rjmp Start

      KOD: rcall NULONE

      cpi RUN, 1
      brbs SREG_Z, KOD1

      rjmp Start

      KOD1: rcall DRIWER

   rjmp   Start   ; Конец программы, переход на начало

; *******************************************************************************************************************
; ПОДПРОГРАММЫ ******************************************************************************************************
; *******************************************************************************************************************

   NULONE:               ; Заполнение 4 переменных нулями и единицами с послыл
      
         cpi FLAG, 0
         brbc SREG_Z, A1   ;
         inc FLAG
         clr YYY
         ret

   A1:      cpi FLAG, 1
         brbc SREG_Z, A2
      
            cpi TIME, 120      ; Проверка 122 < T < 130
            brlo END
            cpi TIME, 132
            brsh END

                  N:   ldi temp, (0<<PB4)|(0<<PB3)|(1<<PB2)|(0<<PB1)|(1<<PB0)   ; Стоп мотор
                     out PORTB, temp   
                     rjmp N


         inc FLAG
         clr CNT
         clr YYY
         ret

   A2:    cpi FLAG, 2
         brbc SREG_Z, END

            cpi TIME, 8         ; Проверка 8 < T < 12
            brbs SREG_C, END
            cpi TIME, 12
            brbc SREG_C, ONE
         
               clc            ; Убираем флаг С
               rol LCMD      ; Задвигаем ноль в самый правый разряд
               rol HCMD      ; и по очереди сдвигаем все байты влево
               rol LADR      ; В итогде, вся цепочка переместилась влево на один бит, а старший вывалился...
               rol HADR
               rjmp TT         ; Все, вышли .

      ONE:    cpi TIME, 18      ; Проверка 18 < T < 22
            brbs SREG_C, END
            cpi TIME, 22
            brbc SREG_C, END
      
               sec            ;
               rol LCMD      ;
               rol HCMD      ;
               rol LADR      ;
               rol HADR
                           
      TT:    cpi CNT, 32
            brbs SREG_Z, PROVERKA

               clr YYY
               ret

      PROVERKA:    cpi HADR, 0b00010000
               brbc SREG_Z, END
               cpi LADR, 0b11001000
               brbc SREG_Z, END
               cpi HCMD, 0b11100001
               brbc SREG_Z, END
               cpi LCMD, 0b00011110
               brbc SREG_Z, END

               clr FLAG
               clr CNT
               clr YYY
               ldi RUN, 1

               ret
      
      END:
         
         clr FLAG
         clr CNT
         clr YYY
         clr RUN
      
   ret

; =============

   DRIWER:

      clr temp   ; Запретить прерывание
      out GIMSK, temp

      cpi SCREEN, 0b00000000      ; Проверяем флаг, опущен экран или поднят
      brbc SREG_Z, UP

         ldi temp, (0<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)   ; Запускаем мотор вниз, а на остальных оставляем поддтяжку
         out PORTB, temp

      TUDA:   ldi temp, (1<<TOIE0) ; Разрешить прерывание по переполнению таймера
            out TIMSK0, temp
            clr temp
            out TCNT0, temp                     ; счетный регистр раймера
         ;   ldi temp, (1<<CS02)|(0<<CS01)|(1<<CS00)   ; Тактовый сигнал = CK/1024 (ЗАПУСКАЕМ ТАЙМЕР)
           ;   out TCCR0B, temp

      NEXT:   cpi CNT, 2         ; ждем, пока таймер проткает 3 раза примерно 100 мсек
            brbc SREG_Z, NEXT   ; Тупо задержка по таймеру

            clr temp          ;Запретить прерывание по переполнению таймера
            out TIMSK0, temp            
             out TCCR0B, temp
            
      NEXT1:   sbic PINB, 0      ; Пропускаем следующую, если бит очищен (датчик сработал, прижал вывод к земле)
            rjmp NEXT1         ; а если не очищен, то продолажем крутиться и ждать, пока датчик не сработает

            ldi temp, (0<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)   ; Стоп мотор
            out PORTB, temp

            com SCREEN         ; переворачиваем флаг положения экрана

            rjmp EX          ; Выходим

      UP:    ldi temp, (1<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)   ; Запускаем мотор вверх
            out PORTB, temp

            rjmp TUDA

   EX:      
         clr FLAG            ; Просто очищаем
         clr TIME
         clr CNT
         clr RUN
         clr YYY
            
      ldi temp, (1<<INT0)      ; Разрешить прерывание
      out GIMSK, temp
      ldi temp, (1<<ISC01)|(0<<ISC00)         ; Настраиваем прерывание по низкому уровню (на ИНТ0)
      out MCUCR, temp

   ret

                     



Всё равно не понял эту (1<<TOIE0) команду. Можете объяснить по подробней? Хочу более глубинно понять что происходит внутри, а то этот << арифметический сдвиг меня смущает. И почему эта команда в скобках? Это макрос какой то? Хочу видеть исходник если это макрос.


Для начала надо разобраться, подключена ли у вас библиотека с определениями всех этих названий????

.include "tn13def.inc"

А потом все просто. Запись (1<<TOIE0) говорит запихать единицу в бит ТОIE0 в регистре. А бит TOIE0 определен в подключенной библиотеке (см. выше), если ее открыть, то можно его там найти и понять что ему присвоено. Сделано это для "удобочитаемости", как вам уже и ответили выше. В скобках, потому что так и читать удобнее. А по поводу вообще команды <<, читайте инструкции к ассемблеру. В гугле их очень много.
Можно было вместо (1<<TOIE0) написать (1<<3), что означало бы, задвинуть (сделать так, чтобы было) единицу в позицию третьего бита.

Вот пример:

ldi temp, (1<<INT0) ; Разрешить прерывание
out GIMSK, temp

Запихиваем единицу в бит INT0 регистра temp, т.е. бит INT0 у нас объявлен в подключенной библиотеке (без нее работать не будет), а там он может записан быть непосредственно для этого микроконтроллера как 0. Т.е. INT0=0. Значит,
ldi temp, (1<<0)

что означает запихать единицу в нулевой бит регистра temp, а по сути, сделать это:

ldi temp,0b00000001

но читается верхнее лучше.

После этого мы просто копируем темп в нужный нам регистр.
Последний раз редактировалось СКАЗОЧНИК Чт дек 17, 2015 18:34:05, всего редактировалось 1 раз.
Станислав
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

ПТУ-шник писал(а):...
Вложения
jhytfcyf.jpg
(64.53 КБ) 448 скачиваний
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

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

Сообщение Z_h_e »

ПТУ-шник писал(а):эту (1<<TOIE0) команду
Это не команда. TOIE0 - это константа и ее значение может быть разным. И еще зависит от среды программирования. В AVR STUDIO надо было в исходник включать специальный файл, в котором были прописаны константы именного того контроллера, для которого пишется код. Другая среда может сама подключить все файлы для нужного контроллера.
Во включаемом файле может быть, например, такая строка:

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

TOIE0 equ 0x03
Это означает что компилятор встретив TOIE0 заменит ее на 0x03.

Запись (1<<TOIE0) скажет компилятору, что надо 1 сдвинуть влево 0x03 раз. И компилятор заменит (1<<TOIE0) на 0b00001000 (0x08).
Следующие две команды будут скомпилированы в один и тот же код.

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

ldi R16,(1<<TOIE0)
ldi R16,0x08
Последний раз редактировалось Z_h_e Чт дек 17, 2015 19:41:45, всего редактировалось 1 раз.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

Да. ))) Выше дорисовал тоже самое, может и не так понятно..
Станислав
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Глянул в ДЩ на тини13 - регистры таймера в "нормальной области", так что своим STSом я чуть не ввел в заблуждение, как Сусанин. Но для других МК, напр. мега48, вышеописанное имеет место.
Изображение
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

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

Сообщение Z_h_e »

СКАЗОЧНИК писал(а): Запись (1<<TOIE0) говорит запихать единицу в бит ТОIE0 в регистре.
Очень некорректное объяснение. Тогда Запись 2<<TOIE0 будет говорит запихать двойку в бит ТОIE0 в регистре? :).

Кстати скобки совсем не обязательно ставить в данном случае.

Следующие команды будут скопмилированы в один и тот же код.

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

ldi R16,0x06
ldi R16,(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)
ldi R16,(1<<ADPS2)+(1<<ADPS1)+(0<<ADPS0)
ldi R16,(1<<ADPS2)+(1<<ADPS1)
ldi R16,0x03<<1
ldi R16,0x0C>>1
ldi R16,3+3

Это биты регистра ADCSRA для тиньки13. Но собственно это не имеет значения сейчас.

Запись (0<<ADPS0) тоже имеет смысл. Потом, например в процессе отладки, если будет необходимость, Вы легко замените значение бита на 1 не заглядывая даташит, кроме того она указывает что такой бит существует, просто Вы в данном случае сбросили его.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

ПТУ-шник писал(а):А вот с TCCR0 всё равно ругаеться, пишет что и раньше: Undefined variable referenced. Тобишь недопустимый адрес как я понял
Вложения
jhytfcyf.jpg
(64.53 КБ) 511 скачиваний
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

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

Сообщение СКАЗОЧНИК »

Z_h_e писал(а):Тогда Запись 2<<TOIE0 будет говорит запихать двойку в бит ТОIE0 в регистре?

:))) :facepalm:
Да, правильно будет так:
"Возвращает левое выражение, сдвинутое влево на число бит указанное справа"

Только хотел еще и вот это показать, а вы уже написали.

ldi temp, (1<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0) ; Запускаем мотор вверх
out PORTB, temp
Станислав
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

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

Сообщение ILYAUL »

Demiurg писал(а):
ПТУ-шник писал(а):А вот с TCCR0 всё равно ругаеться, пишет что и раньше: Undefined variable referenced. Тобишь недопустимый адрес как я понял

Мне тоже стало интересно, сколько ты ещё сделаешь попыток донести правду TC. Знаешь , после пятой попытки , выложи чуть другое изо, может сравнительный анализ поможет
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

ILYAUL писал(а):...

Думаю, ник ПТУ-шник все за себя говорит...
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

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

Сообщение ПТУ-шник »

Спасибо, вроде с программой разобрались. Компилятор не ругается :)

По поводу команды. Со скобками понятно, это приоритет операции или просто оформление. С символом << разобрался это сдвиг числа влево. Получаеться команда

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

LDI temp, (1<<2)

Дано число 0b00000001 оно по команде сдвига << сдвинет его так 0b00000100 и запишет в temp. Тоже самое делает с TOIE0.

Всё спасибо, стало понятно.
Ответить

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