Ассемблер (ASM) для AVR в вопросах и ответах
Re: AVR studio 4 в вопросах и ответах
"Проиксорить все биты в байте" с человеческого на бюрократический переводится как "посчитать единицы, определить, является их количество чётным или нечётным".
Или не переводится (ср. "вычесть все цифры в числе").
Компактно - сдвигами в цикле.
Быстро - по таблице.
Для любой хотелки должна быть специальная кнопка в AVR studio 4, надо найти её в ней - хм...
Или не переводится (ср. "вычесть все цифры в числе").
Компактно - сдвигами в цикле.
Быстро - по таблице.
Для любой хотелки должна быть специальная кнопка в AVR studio 4, надо найти её в ней - хм...
- Kill17
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Вс май 30, 2010 20:27:33
- Откуда: Санкт-Петербург
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Спасибо, сделал так !
Код: Выделить всё
======== 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 - результат
Re: AVR studio 4 в вопросах и ответах
Циклом:По таблице:
А смысл?
А если в AVR studio 6.2? А если вообще не в AVR studio?
Код: Выделить всё
.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 в вопросах и ответах
Возник вопрос по прерываниям. Камень - 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 // Очистка РОН (Регистров Общего Назначения)Re: AVR studio 4 в вопросах и ответах
Задал вопрос, сам нашёл ответ! Kill17, круто!
Сам то понял в чём была проблема с инициализацией стека у Kill17?
Лучше, хуже...философия...НАПАЛМ писал(а):Именно поэтому лучше юзать библиотеку макроопределений.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Kill17
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Вс май 30, 2010 20:27:33
- Откуда: Санкт-Петербург
- Контактная информация:
Re: AVR studio 4 в вопросах и ответах
Kavka писал(а): Сам то понял в чём была проблема с инициализацией стека у Kill17?
Я так понял, что он не прописывался из-за команды STS, я правельно понял&?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Kill17, ну, да, можно сказать, что и из-за неё. Хотя, скорее из-за того, что вы упустили тот момент, что команды in/out работают в адресном подпространстве сдвинутом относительно основного пространства данных.
И чтобы LDS/STS при тех определениях, что есть работали правильно надо вот так записать
А можно воспользоваться макросом, тогда команда будет подставляться соответствующая адресу регистра в/в.
http://www.atmel.com/Images/doc2550.pdf
http://www.atmel.com/images/AVR001.zip
И чтобы 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
.ENDMACROhttp://www.atmel.com/Images/doc2550.pdf
http://www.atmel.com/images/AVR001.zip
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: AVR studio 4 в вопросах и ответах
НАПАЛМ писал(а):Код: Выделить всё
RAMFLUSH // Очистка ОЗУ
GPRFLUSH // Очистка РОН (Регистров Общего Назначения)
Нафига вот это делать?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Явной инициализацией ВСЕХ ячеек гарантируется начало работы с определённого и единственного состояния. Всегда.
Сам по себе переход на адрес "ресет" их не инициализировал бы.
Но и здравым смыслом тоже можно пользоваться - как в дополнение к "потому что так НАДО", так и вместо.
(я так и не понял, для чего занадобился подсчёт количества единиц в байте... начинающему программисту)
Сам по себе переход на адрес "ресет" их не инициализировал бы.
Но и здравым смыслом тоже можно пользоваться - как в дополнение к "потому что так НАДО", так и вместо.
(я так и не понял, для чего занадобился подсчёт количества единиц в байте... начинающему программисту)
Последний раз редактировалось nirq Пн июл 07, 2014 10:08:36, всего редактировалось 1 раз.
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
nirq писал(а):Сам по себе переход на адрес "ресет" их не инициализировал бы.
Так а зачем их инициализировать? В программе всё равно идёт ПРИСВОЕНИЕ значения, без разницы что там было до этого.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А это уже и есть здравый смысл: сначала обнулили 1024 ячейки "оптом", потом сразу переинициализировали 50 из них отличными от нуля значениями "в розницу".
Или не сразу, а ближе к середине. И разные ячейки в разных местах.
Или 49 ячеек инициализировали, а про ещё одну забыли. И привет отладка.
Поэтому практичнее: обнулить оптом всю память сразу и эти же нули считать уже сразу готовым стартовым состоянием переменных, без переприсвоений.
Чат.
Или не сразу, а ближе к середине. И разные ячейки в разных местах.
Или 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 в вопросах и ответах
РОНы обнуляются вместе со всей периферией по любым сигналам сброса, и обнулять их стоит только в том случае если вы используете "программный сброс" путем перехода на вектор сброса. Но это вообще довольно специфическое применение и усы надо держать остро... там и проблемы с инициализацией периферии могут возникнуть.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
РОНы обнуляются вместе со всей периферией по любым сигналам сброса
Re: Ассемблер (ASM) для AVR в вопросах и ответах
И опять здравый смысл: РОН явно инициализируется непосредственно перед любой (разумной) попыткой им воспользоваться.
Как временная, сугубо локальная переменная.
ldi Maksimum, 100
cp TekuscheeZnachenie, Maksimum
brsh ...
или
lds Temp1, TekuscheeZnachenie
lds Temp2, Maksimum
cp Temp1, Temp2
brsh ...
Поэтому проблема (не)инициализации РОН при ресете имеет скорее академический характер, чем практический.
А за аппаратные ("периферийные") регистры вопрос отпадёт сам собой, если приглядеться например к MCUCSR.
Как временная, сугубо локальная переменная.
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 в вопросах и ответах
Возможно пишу не совсем по этой теме, за что прошу прощения.
В общем, суть проблемы(?) такова: задался целью написать на ассемблере программу для работы с датчиком 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. И, далее, с опросом состояния по циклу.
В общем, суть проблемы(?) такова: задался целью написать на ассемблере программу для работы с датчиком 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. И, далее, с опросом состояния по циклу.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Много лишнего. Может так проще.
- dr.doc
- Это не хвост, это антенна
- Сообщения: 1368
- Зарегистрирован: Вс мар 28, 2010 12:52:22
- Откуда: Беларусь
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Так я ведь так и делаю. Единственное отличие - начал смотреть все 9 байт. Сначала выводил их по UART, а потом конвертировал в hex и на 44780. Просто может модель датчика такая? С 2-мя первыми байтами дело не прошло, поэтому пришлось читать все для понимания причин...
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Так не должно быть, а уверенны что корректно считываются все 9 байт? Быть может что-то со скоростью и датчик молчит при опросе второго байта а начинае отдавать второй когда считываете третий
В регистрах TH TL можно хранить любые 2 байта если не пользоваться командой alarm search. Это и подразумевается под ячейками универсальной памяти
В регистрах TH TL можно хранить любые 2 байта если не пользоваться командой alarm search. Это и подразумевается под ячейками универсальной памяти