програмирование AVR на АСЕМБЛЕРЕ для чайников

Обсуждаем контроллеры компании Atmel.
Закрыто
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Так всё-таки два? (у меня нет студии)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

Вроде да. Если верить студии. :)
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

У AVR есть одна "непривычная" поначалу особенность - хоть это 8-ми битный камень, но память программ организована как DW (слово) и любая команда занимает минимум слово. А когда читаем из памяти программ (например командой lpm) - обращаемся к байтам. Поэтому и пишем ldi ZL,метка адреса<<1. Кстати поэтому "табличные вычисления" на AVR часто выигрывают не только в скорости, но и в размере.
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

С табличными вычислениями я знаком. Делал пару программок. Классно получается. :)
2 байта помещаются в стек, потому что память сидит на 16-битной адресной шине и шина данных помоему тоже 16-битная.

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

ldi            temp2,         0x0X ;(0...3)
START:
ldi				ZL,				Low(HANDLERS*2)
ldi				ZH,				High(HANDLERS*2)
mov            temp0,         temp2
lsl				temp0
clr				temp1
add				ZL,				temp0
adc				ZH,				temp1
lpm				temp0,			Z
adiw		     Z,				 0x01
lpm				temp1,			Z
mov				ZL,				temp0
mov				ZH,				temp1
icall
rjmp           START
;---------------------------------------
PRG0:
    ;какой-нибудь код
ret
;---------------------------------------
PRG1:
    ;какой-нибудь код
ret
;---------------------------------------
PRG2:
    ;какой-нибудь код
ret
;---------------------------------------
PRG3:
    ;какой-нибудь код
ret
;---------------------------------------
HANDLERS:
.dw PRG0, PRG1, PRG2, PRG3
Этот цикл будет вызывать одну и ту-же подпрограмму, пока не изменится значение в temp2
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

DX168B писал(а):и шина данных помоему тоже 16-битная
... нет она 8-ми битная. Нет у AVR команд, которые позволяют считать слово за раз.
16-битная организация памяти программ связана с работой конвейера. Плюсы - команда за такт (правда изобилие jmp, call и т.д. легко "убивает" производительность) Минусы - аналогичный по смыслу код на 8-битной шине (например у mcs51) занимает меньше места.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

Ну значит восьмибитная. Но адресная 100пудофф 16-битная. Так как восьми битами можно адресовать только 256 байт.
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

DX168B писал(а):Но адресная 100пудофф 16-битная. Так как восьми битами можно адресовать только 256 байт.
... восьми битами можно адресовать 512 байт (256X2) или 256 слов. А насчет адреса, она есть и поширее :) - отсюда и команды EICALL, EIJMP и т.д.
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

ChipKiller писал(а):... нет она 8-ми битная.
ChipKiller писал(а): ... восьми битами можно адресовать 512 байт (256X2) или 256 слов.
Вы противоречите сами себе. :))) Представьте себе простую ПЗУшку, типа УФ EPROM.
Если Вы когда - нибудь вообще имели дело с внешней памятью. Так у неё шина данных - 8бит. А 1 байт=8бит. Адресная шина, ну допустим - 14 битная. Тогда в таком чипе не может быть больше 16 килобайт памяти. Но теперь возьмём МК ATMEGA32. ПЗУ у неё - 32 килобайта, и счётчик команд 14-битный. Это означает, что к ПЗУ подходит 14-битная адресная шина. (16 бит - я даже преувеличил, имея опыт ранее с процессорами Z80. Всё никак отойти от них не могу.) Почему 32 килобайта на 14-битной адресной шине? А всё потому, что ПЗУ у этого МК 16-битная. По этому в неё влезло в 2 раза больше положенного. И этот МК как раз и возьмёт за раз одно слово. :) Тем более это подтверждают строчки из даташита. :)
Datasheet ATMEGA32 писал(а): • High Endurance Non-volatile Memory segments
– 32K Bytes of In-System Self-programmable Flash program memory
Datasheet ATMEGA32 писал(а): The ATmega32A contains 32K bytes On-chip In-System Reprogrammable Flash memory for
program storage. Since all AVR instructions are 16 or 32 bits wide, the Flash is organized as
16K x 16
. For software security, the Flash Program memory space is divided into two sections,
Boot Program section and Application Program section.
Datasheet ATMEGA32 писал(а): The ATmega32A
Program Counter (PC) is 14 bits wide, thus addressing the 16K program memory locations.
Не забывайте, это всё-таки RISC архитектура. ПЗУ, счётчик команд, регистр команд и дешифратор команд - это отдельное государство.
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Не забывайте, это всё-таки RISC архитектура. ПЗУ, счётчик команд, регистр команд и дешифратор команд - это отдельное государство.
Вот это меня тоже часто путает.
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

Да, к стати. Возьмём строчку rjmp LABEL.
Вместо LABEL, в ПЗУ не вставляется адрес метки, а вставляется число со знаком, которое в результате складывается с текущим содержимым счётчика команд, либо отнимается от него. Результат выставляется в адресной шине ПЗУ. И всё это вмещается в одну 16-битную ячейку ПЗУ. Это как раз и объясняет ограничение команды rjmp.
Ну не хватает места в ячейке для полноценного адреса метки+команды.
Путает то, что ПЗУ для командного процессора представляется просто 16-битной памятью, а для АЛУ и периферии - представляется 8-битной памятью.
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

simpleX писал(а):
ploop писал(а):Но это как-то больше к ЯВУ относится, нежели к ассемблеру.
Думаю, что и к нему тоже =)
Тут разговор был про выделение смысловых участков ассемблерного кода в подпрограммы.

Сейчас пишу небольшой проектик, и пока вспомнил добавлю: ассемблер поддерживает макросы. А это мощная вещь, можно разбить листинг на любые смысловые части, не теряя при этом драгоценные такты процессора и считанные байты ОЗУ. Читабельность улучшается на порядок!
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Так же, пример того, как с помощью констант можно быстро сконфигурировать I/O-порты для более простой разводки печатной платы. Пример:

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

; где-то в файле со своими макросами и константами
.equ led_port = PORTD       ; порт светодиода 
.equ button_port = PORTB  ; порт кнопки
.equ exit_port = PORTD  ; выход

.equ led_bit = 1       ; бит светодиода 
.equ button_bit = 0  ; бит кнопки
.equ exit_bit = 4  ; бит выхода

;------------- всё, дальше не лезем ------------------
; тут настраиваем DDR и PIN, смотрим .inc файл контроллера
;.equ	PORTD	= $0B		; - PORTD -
;.equ	DDRD	= $0A
;.equ	PIND	= $09	
;.equ	PORTC	= $08		; - PORTC -
;.equ	DDRC	= $07
;.equ	PINC	= $06
;.equ	PORTB	= $05		; - PORTB -
;.equ	DDRB	= $04
;.equ	PINB	= $03
; Отлично! делаем

.equ led_ddr = led_port-1
.equ button_ddr = button_port-1
.equ exit_ddr = exit_port-1

.equ led_pin = led_port-2
.equ button_pin = button_port-2
.equ exit_pin = exit_port-2
;-------------------------------------------------
; где-то в инициализации
sbi led_ddr,led_bit ; порт светодиода на выход
cbi button_ddr,button_bit ; кнопку на вход
sbi exit_ddr,exit_bit ; выход - на выход
Теперь если мы при разводке платы подцепим светодиод, кнопку и выход к другим ногам, нам останется всего лишь поправить значения до черты "дальше не лезем" в примере. Остальное компилятор сделает сам.
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

DX168B писал(а):
ChipKiller писал(а): ... нет она 8-ми битная.
ChipKiller писал(а): ... восьми битами можно адресовать 512 байт (256X2) или 256 слов.
Вы противоречите сами себе.
... никаких противоречий нет. Первая фраза относится к шине данных, а вторая к исполнению команд и имелось ввиду именно следующее: the Flash is organized as 16K x 16, т.е. при изменении PC (Program Counter) на 1 - адрес меняется на слово (2 байта). В RISC следует различать исполнение (т.е. выборку инструкций и операндов - 16-бит) и обращение к Flash с целью чтения или к RAM, I/O register ... для чтения/записи - здесь только "поштучно" :) (шина всегда 8-бит)
Друг Кота
Аватара пользователя
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)

Сообщение DX168B »

Ну я что и имею в виду. Только память Flash не восьмибитная. А "поштучно" читается, потому, что шина данных вычислительного узла (АЛУ, регистры и периферия) составляет 8 бит. Команды, типа rjmp LABEL составляют одно слово и жрут 2 байта. За 1 такт, счётчика команд, такая команда забирается целиком, но выполняется за несколько тактов. Там ведь надо ещё знак распознать и сложить его с текущим содержимым счётчика команд. Команды, типа jmp LABEL съедают больше и читаются за 2 такта. Даже в даташитах говорится, что команды AVR бывают 16-битные или 32-битные. Короче, закончим FLOOD, так как пришли к одному выводу. :)
I am DX168B and this is my favourite forum on internet!
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

еще один пример организации табличного преобразования

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

led_pin.inc
; описание разрядов индикатора ( ... у каждого может быть свое )
.equ	led_a	=0x01	
.equ	led_b	=0x02
.equ	led_c	=0x04
.equ	led_d	=0x08
.equ	led_e	=0x10
.equ	led_f	=0x20
.equ	led_g	=0x40
.equ	led_h	=0x80
эта часть может находиться в начале вашей программы

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

.include "led_pin.inc"
; описание символов, выводимых на индикатор
.equ	ch_0	= led_a + led_b + led_c + led_d + led_e + led_f
.equ	ch_1	= led_b + led_c
.....
.equ	ch_F	= led_a + led_e + led_f + led_g
если вдруг необходимо инверсное значение (например смена индикаторов с ОК на ОА) - можно подправить код, а можно просто поменять определение

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

.equ	ch_0	= 255-(led_a + led_b + led_c + led_d + led_e + led_f)
плюсы такого подхода - при любом изменении распайки, меняется только содержимое led_pin.inc
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Во, тоже можно взять на заметку!
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

всем мяу.

помогите замяукать 8-разрдный АЦП на attiny13. большая просьба выложить текст (от .include до .exit) с коментариями замяукования уровня АЦП в регистр, например R20.

хочу сделать управление двигателем как шаговым так и обычным. в случае с шаговым он должен смещаться на определенный угол в зависимости от уровня АЦП. обычный - менять обороты (обратная связь по ИК-датчику, 2 импульса на 1 оборот двигателя). ну это все постараюсь сам сделать, а вот с АЦП прошу помощи.

а может НУ К МЫШАМ этот ацп и сделать все на N-кодерах???
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

А даташит читать уже не модно? :) Там есть примеры. С комментариями.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

все что я могу в даташите это выковырять коготками таблицу прерываний... ибо с английскими котами не дружу... поэтому и прошу момощи.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

Технический английский учить обязательно. А пока, на Ваше счастье, есть вот что: http://easyelectronics.ru/avr-uchebnyj- ... e-acp.html
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Закрыто

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