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

Обсуждаем контроллеры компании Atmel.
nirq
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Re: AVR studio 4 в вопросах и ответах

Сообщение nirq »

"Проиксорить все биты в байте" с человеческого на бюрократический переводится как "посчитать единицы, определить, является их количество чётным или нечётным".
Или не переводится (ср. "вычесть все цифры в числе").

Компактно - сдвигами в цикле.
Быстро - по таблице.
Для любой хотелки должна быть специальная кнопка в AVR studio 4, надо найти её в ней - хм...
Аватара пользователя
Kill17
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 30, 2010 20:27:33
Откуда: Санкт-Петербург
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Kill17 »

Спасибо, сделал так !

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

======== r16 - регистр с байтом
   CLR   R18
   CLR   R19
   LDI   R20,1
 write_bit:
      SBRC  R16,0
      EOR   R19,R20                       
      ROR   R16
      INC   R18
      CPI   R18,8
      BRNE  write_bit
;=========== в регистре R19 - результат
nirq
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Re: AVR studio 4 в вопросах и ответах

Сообщение nirq »

Циклом:

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

.def MyByte = R16
.def OnesCounter = R17
.def BitCounter = R18      ; программа должна быть читаемой, а не шифрованной! кульксакеп-стайл

ldi BitCounter, 8        ; такие счётчики практичнее вычитать, чем прибавлять - цикл так и эдак заканчивается по условию brne, но вычитание само по себе ставит флаг Z, без дополнительных сравнений

nextbit:
rol MyByte                 ; или ror, нам без разницы, с какой стороны начинать считать единицы (или нули, по сути то же самое) - интересует только их общее количество... можно даже lsl или lsr
brcc pc + 2                ; или brcs, по сути получится то же самое, но наоборот
inc OnesCounter
dec BitCounter
brne nextbit

; OnesCounter = количество единиц в MyByte (или нулей, по сути то же самое)
; в нечётном числе младший бит =1, в чётном =0

; отдельный вопрос - нужен ли нам дальше исходный MyByte... в реальной ситуации скорее нет, чем да
По таблице:

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

ldi ZH, high(Table * 2)
ldi ZL, low(Table * 2)

add ZL, MyByte
brcc pc + 2
inc ZH

lpm OnesCounter, Z

Table:

.db 0   ; количество единиц в числе 0b00000000
.db 1   ; количество единиц в числе 0b00000001
.db 1   ; количество единиц в числе 0b00000010
.db 2   ; количество единиц в числе 0b00000011
.db 1   ; количество единиц в числе 0b00000100
...


А смысл?
А если в AVR studio 6.2? А если вообще не в AVR studio?
Аватара пользователя
Kill17
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 30, 2010 20:27:33
Откуда: Санкт-Петербург
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Kill17 »

Возник вопрос по прерываниям. Камень - Atmega168. Вроде все сделал как надо, а прерывания не работает, что в железе, что в симуляторе. Прога запускается, доходит до команды SEI и все, сразу возврат в таблицу прерываний и тд. Может я что-то проглядел?

Спойлер

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

          .nolist
           .include "m168def.inc"
           .list

           .equ XTAL = 20000     
           .equ BAUD = 9600   
           .equ NB = ((10000*XTAL)/(16*BAUD)-5)/10

; ========= Interrupts =================

         .cseg
         .org $0000           
          JMP RESET        ; (RESET)
     ;    .ORG $002
     ;    RETI                ; (INT0) External Interrupt Request 0
     ;    .ORG $004
     ;    RETI                ; (INT1) External Interrupt Request 1
     ;    .ORG $006
     ;    RETI               ; (PCINT0) Pin Change Interrupt Request 0
     ;    .ORG $008
     ;    RETI                ; (PCINT1) Pin Change Interrupt Request 1
     ;    .ORG $00A
     ;    RETI               ; (PCINT2) Pin Change Interrupt Request 2
     ;    .ORG $00C
     ;    RETI              ; (WDT) Watchdog Time-out Interrupt
     ;    .ORG $00E
     ;    RETI            ; (TIMER2 COMPA) Timer/Counter2 Compare Match A
     ;    .ORG $010
     ;    RETI              ; (TIMER2 COMPB) Timer/Counter2 Compare Match B
     ;    .ORG $012
     ;    RETI             ; (TIMER2 OVF) Timer/Counter2 Overflow
     ;    .ORG $014
     ;    RETI                ; (TIMER1 CAPT) Timer/Counter1 Capture Event
     ;    .ORG $016
     ;    RETI                ; (TIMER1 COMPA) Timer/Counter1 Compare Match A
     ;    .ORG $018
     ;    RETI               ; (TIMER1 COMPB) Timer/Coutner1 Compare Match B
     ;    .ORG $01A
     ;    RETI               ; (TIMER1 OVF) Timer/Counter1 Overflow
     ;    .ORG $01C
     ;    RETI               ; (TIMER0 COMPA) Timer/Counter0 Compare Match A
     ;    .ORG $01E
     ;    RETI                ; (TIMER0 COMPB) Timer/Counter0 Compare Match B
     ;    .ORG $020
     ;    RETI                ; (TIMER0 OVF) Timer/Counter0 Overflow
     ;    .ORG $022
     ;    RETI                ; (SPI, STC SPI) Serial Transfer Complete
         .ORG $024
          JMP RX_RS232                ; (USART, RX USART) Rx Complete
     ;    .ORG $026
     ;    RETI                ; (USART, UDRE USART), Data Register Empty
     ;    .ORG $028
     ;    RETI                ; (USART, TX USART), Tx Complete
    ;    .ORG $02A
     ;    RETI                ; (ADC) ADC Conversion Complete
     ;    .ORG $02C
     ;    RETI                ; (EE READY) EEPROM Ready
     ;    .ORG $02E
     ;    RETI                ; (ANALOG COMP) Analog Comparator
     ;    .ORG $030
     ;    RETI                ; (TWI) 2-wire Serial Interface
     ;    .ORG $032
     ;    RETI               ; (SPM READY) Store Program Memory Ready
         .ORG   INT_VECTORS_SIZE         ; Êîíåö òàáëèöû ïðåðûâàíèé

; ========= END Interrupts =================   
 
RESET:
   

      LDI   R16,low(RAMEND)
      STS   SPL,R16
      LDI   R16,high(RAMEND)
      STS   SPH,R16
      CLR   R16       
      STS   UBRR0H,R16
      LDI   R16,NB   
      STS   UBRR0L,R16
     
   
      LDI   R16,(1<<RXEN0)|(0<<TXEN0)|(1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0) 
      STS   UCSR0B,R16
      LDI   R16,(1<<UCSZ00)|(1<<UCSZ01)
      STS   UCSR0C,R16


;===========
      LDI   R16,(1<<PB3)         
      OUT   DDRB, R16
      SBI   PORTB,3
;=========
SEI
JMP MAIN
RETI

RX_RS232:
      LDS  R16,UDR0
      cbi portb,3
RETI

Main:
NOP
NOP
JMP Main
RETI




Что-то вообще процесс дошел до смешного! Все равно картина такая же!
Спойлер

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

           .include "m168def.inc"
; ========= Interrupts =================
         .cseg
         .org $0000           
          RJMP RESET        ; (RESET)
         .ORG $002
         RETI                ; (INT0) External Interrupt Request 0
     ;    .ORG $004
     ;    RETI                ; (INT1) External Interrupt Request 1
     ;    .ORG $006
     ;    RETI               ; (PCINT0) Pin Change Interrupt Request 0
     ;    .ORG $008
     ;    RETI                ; (PCINT1) Pin Change Interrupt Request 1
     ;    .ORG $00A
     ;    RETI               ; (PCINT2) Pin Change Interrupt Request 2
     ;    .ORG $00C
     ;    RETI              ; (WDT) Watchdog Time-out Interrupt
     ;    .ORG $00E
     ;    RETI            ; (TIMER2 COMPA) Timer/Counter2 Compare Match A
     ;    .ORG $010
     ;    RETI              ; (TIMER2 COMPB) Timer/Counter2 Compare Match B
     ;    .ORG $012
     ;    RETI             ; (TIMER2 OVF) Timer/Counter2 Overflow
     ;    .ORG $014
     ;    RETI                ; (TIMER1 CAPT) Timer/Counter1 Capture Event
     ;    .ORG $016
     ;    RETI                ; (TIMER1 COMPA) Timer/Counter1 Compare Match A
     ;    .ORG $018
     ;    RETI               ; (TIMER1 COMPB) Timer/Coutner1 Compare Match B
     ;    .ORG $01A
     ;    RETI               ; (TIMER1 OVF) Timer/Counter1 Overflow
     ;    .ORG $01C
     ;    RETI               ; (TIMER0 COMPA) Timer/Counter0 Compare Match A
     ;    .ORG $01E
     ;    RETI                ; (TIMER0 COMPB) Timer/Counter0 Compare Match B
     ;    .ORG $020
     ;    RETI                ; (TIMER0 OVF) Timer/Counter0 Overflow
     ;    .ORG $022
     ;    RETI                ; (SPI, STC SPI) Serial Transfer Complete
         .ORG $024
          JMP RX_RS232                ; (USART, RX USART) Rx Complete
     ;    .ORG $026
     ;    RETI                ; (USART, UDRE USART), Data Register Empty
     ;    .ORG $028
     ;    RETI                ; (USART, TX USART), Tx Complete
    ;    .ORG $02A
     ;    RETI                ; (ADC) ADC Conversion Complete
     ;    .ORG $02C
     ;    RETI                ; (EE READY) EEPROM Ready
     ;    .ORG $02E
     ;    RETI                ; (ANALOG COMP) Analog Comparator
     ;    .ORG $030
     ;    RETI                ; (TWI) 2-wire Serial Interface
     ;    .ORG $032
     ;    RETI               ; (SPM READY) Store Program Memory Ready
     
; ========= END Interrupts =================   
 
RESET:
   
      LDI   R16,low(RAMEND)
      STS   SPL,R16
      LDI   R16,high(RAMEND)
      STS   SPH,R16
      CLR   R16       
SEI

Main:
NOP
NOP
JMP Main
RETI



RX_RS232:
RETI


Нашел проблему!

LDI R16,low(RAMEND)
OUT SPL,R16
LDI R16,high(RAMEND)
OUT SPH,R16
Аватара пользователя
НАПАЛМ
Это не хвост, это антенна
Сообщения: 1314
Зарегистрирован: Пт ноя 27, 2009 19:47:13
Откуда: Казань

Re: AVR studio 4 в вопросах и ответах

Сообщение НАПАЛМ »

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

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

STACKINIT // Инициализация стека
 RAMFLUSH  // Очистка ОЗУ
 GPRFLUSH  // Очистка РОН (Регистров Общего Назначения)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: AVR studio 4 в вопросах и ответах

Сообщение Kavka »

Задал вопрос, сам нашёл ответ! Kill17, круто!

НАПАЛМ писал(а):Именно поэтому лучше юзать библиотеку макроопределений.
Лучше, хуже...философия... :) Сам то понял в чём была проблема с инициализацией стека у Kill17?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
Kill17
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 30, 2010 20:27:33
Откуда: Санкт-Петербург
Контактная информация:

Re: AVR studio 4 в вопросах и ответах

Сообщение Kill17 »

Kavka писал(а): Сам то понял в чём была проблема с инициализацией стека у Kill17?

Я так понял, что он не прописывался из-за команды STS, я правельно понял&?
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Kill17, ну, да, можно сказать, что и из-за неё. Хотя, скорее из-за того, что вы упустили тот момент, что команды in/out работают в адресном подпространстве сдвинутом относительно основного пространства данных.
И чтобы LDS/STS при тех определениях, что есть работали правильно надо вот так записать

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

      LDI   R16, low(RAMEND)
      STS   SPL + 0x20, R16
      LDI   R16, 0x20 + high(RAMEND)
      STS   SPH + 0x20, R16


А можно воспользоваться макросом, тогда команда будет подставляться соответствующая адресу регистра в/в.
Спойлер

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

.MACRO STORE       ;параметры: адрес, регистр
   .if   @0>0x3F
      sts   @0, @1
   .else
      out   @0, @1
   .endif
.ENDMACRO

.MACRO LOAD       ;параметры: адрес, регистр
   .if   @1>0x3F
      lds   @0, @1
   .else
      in   @0, @1
   .endif
.ENDMACRO

http://www.atmel.com/Images/doc2550.pdf
http://www.atmel.com/images/AVR001.zip
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: AVR studio 4 в вопросах и ответах

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

НАПАЛМ писал(а):

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

 RAMFLUSH  // Очистка ОЗУ
 GPRFLUSH  // Очистка РОН (Регистров Общего Назначения)

Нафига вот это делать?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
nirq
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

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

Сообщение nirq »

Явной инициализацией ВСЕХ ячеек гарантируется начало работы с определённого и единственного состояния. Всегда.
Сам по себе переход на адрес "ресет" их не инициализировал бы.

Но и здравым смыслом тоже можно пользоваться - как в дополнение к "потому что так НАДО", так и вместо.



(я так и не понял, для чего занадобился подсчёт количества единиц в байте... начинающему программисту)
Последний раз редактировалось nirq Пн июл 07, 2014 10:08:36, всего редактировалось 1 раз.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

nirq писал(а):Сам по себе переход на адрес "ресет" их не инициализировал бы.

Так а зачем их инициализировать? В программе всё равно идёт ПРИСВОЕНИЕ значения, без разницы что там было до этого.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
nirq
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

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

Сообщение nirq »

А это уже и есть здравый смысл: сначала обнулили 1024 ячейки "оптом", потом сразу переинициализировали 50 из них отличными от нуля значениями "в розницу".
Или не сразу, а ближе к середине. И разные ячейки в разных местах.
Или 49 ячеек инициализировали, а про ещё одну забыли. И привет отладка.

Поэтому практичнее: обнулить оптом всю память сразу и эти же нули считать уже сразу готовым стартовым состоянием переменных, без переприсвоений.

Чат.
Аватара пользователя
НАПАЛМ
Это не хвост, это антенна
Сообщения: 1314
Зарегистрирован: Пт ноя 27, 2009 19:47:13
Откуда: Казань

Re: AVR studio 4 в вопросах и ответах

Сообщение НАПАЛМ »

Kavka писал(а):Задал вопрос, сам нашёл ответ! Kill17, круто!

НАПАЛМ писал(а):Именно поэтому лучше юзать библиотеку макроопределений.
Лучше, хуже...философия... :) Сам то понял в чём была проблема с инициализацией стека у Kill17?


Да, я прогонял у себя программу, хотел написать, гляжу, а тут уже и сам он ответил.

По поводу обнуления озу и рон: да, это не всегда нужно, согласен. Но это 100% верняк, минус еще одно место возможных косяков. Лучше задать начальную точку отсчета и плясать от неё. Мало ли как программу решишь написать и какие ходы придумать.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

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

Сообщение Alexeyslav »

РОНы обнуляются вместе со всей периферией по любым сигналам сброса, и обнулять их стоит только в том случае если вы используете "программный сброс" путем перехода на вектор сброса. Но это вообще довольно специфическое применение и усы надо держать остро... там и проблемы с инициализацией периферии могут возникнуть.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

РОНы обнуляются вместе со всей периферией по любым сигналам сброса

:shock: Отсебятина. Удалите, пока никто не видел.
nirq
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

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

Сообщение nirq »

И опять здравый смысл: РОН явно инициализируется непосредственно перед любой (разумной) попыткой им воспользоваться.
Как временная, сугубо локальная переменная.

ldi Maksimum, 100
cp TekuscheeZnachenie, Maksimum
brsh ...


или

lds Temp1, TekuscheeZnachenie
lds Temp2, Maksimum

cp Temp1, Temp2
brsh ...


Поэтому проблема (не)инициализации РОН при ресете имеет скорее академический характер, чем практический.
А за аппаратные ("периферийные") регистры вопрос отпадёт сам собой, если приглядеться например к MCUCSR.
Аватара пользователя
dr.doc
Это не хвост, это антенна
Сообщения: 1368
Зарегистрирован: Вс мар 28, 2010 12:52:22
Откуда: Беларусь

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

Сообщение dr.doc »

Возможно пишу не совсем по этой теме, за что прошу прощения.
В общем, суть проблемы(?) такова: задался целью написать на ассемблере программу для работы с датчиком DS18B20, и, в принципе, успешно ее решил. Но! В datasheet сказано, что датчик выдает при чтении 1. LSB температуры, 2. MSB температуры, 3 и 4-й байты регистры аварии верхнего и нижнего предела, 5. Регистр конфигурации, 3 резервных байта и байт CRC.
Так вот, в Proteus для корректного съема температуры приходится конвертировать 1-й и 3-й байты! Конечно, в документе есть сноска "если функция аварии DS18B20 не используется, то регистры TH and TL могут быть ячейками универсальной памяти" - Какой и как я не нашел. И как в реальности работает такой датчик?
PS Датчик один. Конфигурация: Presense, SKIP ROM, READ ROM, запись 9-ти байт по порядку в ОЗУ (.dseg .org 0x60 rec: .byte 9), Convert temperature. И, далее, с опросом состояния по циклу.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Много лишнего. Может так проще.
Аватара пользователя
dr.doc
Это не хвост, это антенна
Сообщения: 1368
Зарегистрирован: Вс мар 28, 2010 12:52:22
Откуда: Беларусь

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

Сообщение dr.doc »

Так я ведь так и делаю. Единственное отличие - начал смотреть все 9 байт. Сначала выводил их по UART, а потом конвертировал в hex и на 44780. Просто может модель датчика такая? С 2-мя первыми байтами дело не прошло, поэтому пришлось читать все для понимания причин...
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Аватара пользователя
*скрыто*
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Пн дек 31, 2012 13:16:59

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

Сообщение *скрыто* »

Так не должно быть, а уверенны что корректно считываются все 9 байт? Быть может что-то со скоростью и датчик молчит при опросе второго байта а начинае отдавать второй когда считываете третий

В регистрах TH TL можно хранить любые 2 байта если не пользоваться командой alarm search. Это и подразумевается под ячейками универсальной памяти
Ответить

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