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

Обсуждаем контроллеры компании Atmel.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

mig-11101 писал(а):...
ATtiny13_power_doun.GIF
Из этого замечания на 30 стр. DS, следует, что выход из POWER-DOWN будет только при низком уровне на INT0.
Попробуйте так
POWER_DOWN.TXT
mig-11101
Открыл глаза
Сообщения: 62
Зарегистрирован: Вс янв 17, 2010 01:04:34

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

Сообщение mig-11101 »

akl

Спасибо, дейсвтвительно срабатывает, если установить прерывание на низкий уровень.
Аватара пользователя
ZERO..
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Сб окт 16, 2010 19:52:32
Откуда: Сургут

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

Сообщение ZERO.. »

akl писал(а):
mig-11101 писал(а):...
ATtiny13_power_doun.GIF
Из этого замечания на 30 стр. DS, следует, что выход из POWER-DOWN будет только при низком уровне на INT0.
Попробуйте так
POWER_DOWN.TXT
[color=#FF4000]Ищу где? и как? надо пользоваться личкой[/color]
Аватара пользователя
desolator
Открыл глаза
Сообщения: 59
Зарегистрирован: Пт окт 01, 2010 22:51:54
Откуда: Украина/Умань
Контактная информация:

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

Сообщение desolator »

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

      .DSEG
Variables:   .byte   3
Variavles2:   .byte   1
 
      .CSEG
 
; Переменная лежит в памяти, сначала надо ее достать.
   LDS   R16, Variables      ; Считать первый байт Variables  в R16
   LDS    R17, Variables+1    ; Считать второй байт Variables  в R17
   LDS   R18, Variables+2   ; Ну и третий байт в R18
 
; Теперь прибавим к ней 1, т.к. AVR не умеет складывать с константой, только
; вычитать, приходиться извращаться. Впрочем, особых проблем не доставляет.
 
   SUBI   R16,(-1)   ; вообще то SUBI это вычитание, но -(- дает +
   SBCI   R17,(-1)   ; А тут перенос учитывается. Но об этом потом.
   SBCI   R18,(-1)   ; Математика в ассемблере это отдельная история
 
   STS    Variables,R16      ; Сохраняем все как было.
   STS    Variables+1,R17
   STS   Variables+2,R18


Вот такой пример. Обьясните, пожалуйста, почему

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

SUBI   R16,(-1)   ; вообще то SUBI это вычитание, но -(- дает +
   SBCI   R17,(-1)   ; А тут перенос учитывается. Но об этом потом.
   SBCI   R18,(-1)   ; Математика в ассемблере это отдельная история

в первой строке используем SUBI, какая разница в вычитании с переносом и в вычитании без переноса?
Спасибо заранее.

У меня в мануале написано:

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

SUBI     (Rd,K8)    вычитание константы Rd=Rd-K8
SBCI     (Rd,K8)    вычитание константы с переносом Rd=Rd-K8-C

Что такое "С" выше, и откуда берется? как взаимодействует с выражением ?
SII
Вымогатель припоя
Сообщения: 635
Зарегистрирован: Пт янв 30, 2009 14:50:35
Откуда: Солнечногорск

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

Сообщение SII »

C -- флаг переноса/заёма. Устанавливается в операциях сложения, вычитания, сравнения и сдвигов. С его помощью осуществляется, например, сложение или вычитание многобайтовых величин (собственно, тут пример именно такой).
Doniak
Встал на лапы
Сообщения: 137
Зарегистрирован: Вс дек 02, 2007 14:11:07
Откуда: Кривой Рог

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

Сообщение Doniak »

DX168B писал(а):Видать отправляешь в этот порт целый байт.
Отправив целый байт целиком в порт, ты влияешь на все выводы этого порта.
Если одна часть выводов, например порта D, настроена на выход, а другая на вход, то
лучше управлять выходами порта по отдельности и отслеживать
входы тоже по отдельности(как я писАл выше).
Ещё 2 полезные команды:
sbi - подать на отдельную ногу лог. 1 (подать ток)
cbi - подать на отдельную ногу лог. 0 (убрать ток)
А вот синтаксис:

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

sbi  PortD,  0 ;Запустить ногу PD0
cbi  PortD,  0 ;Отрубить ногу PD0

sbi  PortD,  1 ;Запустить ногу PD1
cbi  PortD,  1 ;Отрубить ногу PD1

sbi  PortD,  2 ;Запустить ногу PD2
cbi  PortD,  2 ;Отрубить ногу PD2

sbi  PortD,  3 ;Запустить ногу PD3
cbi  PortD,  3 ;Отрубить ногу PD3
; И т.д.


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

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

Сообщение DX168B »

Удачи в начинаниях. :) :beer:
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
desolator
Открыл глаза
Сообщения: 59
Зарегистрирован: Пт окт 01, 2010 22:51:54
Откуда: Украина/Умань
Контактная информация:

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

Сообщение desolator »

SII писал(а):C -- флаг переноса/заёма. Устанавливается в операциях сложения, вычитания, сравнения и сдвигов. С его помощью осуществляется, например, сложение или вычитание многобайтовых величин (собственно, тут пример именно такой).

Где про этот флаг можно прочесть более подробно? Т.к. хочется понимать четко почему пишется код именно так, а не иначе.
SII
Вымогатель припоя
Сообщения: 635
Зарегистрирован: Пт янв 30, 2009 14:50:35
Откуда: Солнечногорск

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

Сообщение SII »

Это Вам надо хорошо разобраться с двоичной арифметикой вообще -- как складываются и вычитаются двоичные числа "на бумаге" (тогда увидите, как возникают переносы и заёмы), а после этого -- как производится сложение-вычитание чисел, имеющих большую разрядность, чем используемый процессор (в Вашем случае процессор 8-разрядный, а числа -- 16-разрядные, но сама идея не зависит от конкретной разрядности). У всех компьютерных архитектур этот флаг присутствует, поэтому не играет роли, AVR это, PIC, IA-32... В общем, это основа основ :)
Аватара пользователя
desolator
Открыл глаза
Сообщения: 59
Зарегистрирован: Пт окт 01, 2010 22:51:54
Откуда: Украина/Умань
Контактная информация:

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

Сообщение desolator »

Чтобы люди не бросали, надо просто пофиксить, я думаю админу не пофик, если найдутся жедающие - пофиксят, то админ прилепит.
Было б делом, если б были задачки по мере нарастания сложности.
Аватара пользователя
Roman Venom
Сверлит текстолит когтями
Сообщения: 1135
Зарегистрирован: Сб июл 11, 2009 18:42:21
Откуда: Украина, г.Николаев

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

Сообщение Roman Venom »

у меня такой вопросик.
нужно организовать задержку с изменяемым(прерывание по переполнению таймера) интервалом 8-100мс. Всего 80 значений. В этом прерывании нажимается кнопочка и выставляются значения 0-8000 с шагом 100. Это цифры сразу отображаются на ЖКИ. Этот кусок проги написал.
Думал для управления задержкок сделать похожую конструкцию: табличка с 80-ю значениями. По инкременту они последовательно пишутся в регистр, формирующий задержку.

Хотел сначала сделать обычную консрукцию вроде такой:


ldi work,0
ldi work1,0
ldi work2,0
del3_0:
inc work
cpi work,30
brne del3_1
ret
del3_1:
inc work1
cpi work1,255
brne del3_1
jmp del3_2

del3_2:
inc work2
cpi work2,5
brne del3_2
jmp del3_0


Однако оказалось неудобным то, что приходится менять значения сразу в 2-х регистрах подпроги задержки для формирования точного интервала.
Вопрос как лучше это организовать. Задержку необходимо задавать и в прерывании по переполнению таймера(последовательно) и по прерыванию от юарта(естессно сразу значением).
Успех - императив!
Аватара пользователя
desolator
Открыл глаза
Сообщения: 59
Зарегистрирован: Пт окт 01, 2010 22:51:54
Откуда: Украина/Умань
Контактная информация:

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

Сообщение desolator »

SII писал(а):Это Вам надо хорошо разобраться с двоичной арифметикой вообще -- как складываются и вычитаются двоичные числа "на бумаге" (тогда увидите, как возникают переносы и заёмы), а после этого -- как производится сложение-вычитание чисел, имеющих большую разрядность, чем используемый процессор (в Вашем случае процессор 8-разрядный, а числа -- 16-разрядные, но сама идея не зависит от конкретной разрядности). У всех компьютерных архитектур этот флаг присутствует, поэтому не играет роли, AVR это, PIC, IA-32... В общем, это основа основ :)

Да, действительно, я никогда не задумывался об этом. Всегда использовал языки высокого уровня - задал себе тип и имя переменной и делай что хочешь в пределах диапазона допустимых значений. В ассемблере-же всё изнутри :)
Т.е. если мне надо сложить ДВА 16-битных числа, например:

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

0001000110001100
и

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

0001001010001010
то, при сложении если 1 стоит напротив 1, устанавливаются флаги ZCNVHS? и единичка переносится влево, далее до старшего бита?
SII
Вымогатель припоя
Сообщения: 635
Зарегистрирован: Пт янв 30, 2009 14:50:35
Откуда: Солнечногорск

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

Сообщение SII »

Они будут складываться побайтно -- сначала младшие байты, затем старшие.

Младшие байты: 10001100 + 10001010 дадут 000010110 и возникнет перенос за пределы разрядной сетки, из-за чего будет установлен C.

Старшие байты: 00010001 + 00010010 дадут 00100011, однако к ним будет добавлено значение флага C, а там у нас 1, и в результате будет получено 00100100. При этом C будет сброшен, поскольку переноса из старшего разряда в этом сложении уже не возникло.
Аватара пользователя
Roman Venom
Сверлит текстолит когтями
Сообщения: 1135
Зарегистрирован: Сб июл 11, 2009 18:42:21
Откуда: Украина, г.Николаев

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

Сообщение Roman Venom »

появился один интересный прикол. в прерывании по переполнению 16-битного таймера вызывается 2 подпрограммы:
next_time_H:;
; *
ldi work,0x00; *
out TIMSK,work;запретить прерывания таймерoв
ldi ZH,High(speed_value_delays_H1*2); *
ldi ZL,Low(speed_value_delays_H1*2); *
; *
; *
;
; *
add ZL,BLDC_cnt;указать адрес ячейки таблицы
adc ZH,work
;*
lpm; извлечь из флеш-памяти *
mov t_count1_H,r0;вывести значение
; *
out TCNT1H,t_count1_H;отправить в таймер *
ldi work,0b00000100;разрешить прерывание по переполнению *
out TIMSK,work ; *


; *
ret ;*
;*************************************

и сразу за ней вызывается вторая(такая же. только она перемещает из другой таблички число в младший рег. 16-битного таймера)

next_time_L:;

; *
ldi work,0x00; *
out TIMSK,work;запретить прерывания таймерoв
ldi ZH,High(speed_value_delays_L*2); *
ldi ZL,Low(speed_value_delays_L*2); *
; *
; *
;
; *
add ZL,BLDC_cnt;
adc ZH,work
;
; *
lpm; *
mov t_count1_L,r0; *
out TCNT1L,t_count1_L; *
ldi work,0b00000100; *
out TIMSK,work ; *
; *
ret ;*


Таблички:
speed_value_delays_L:
.db 0b11111111, 0b00000100, 0b00000100, 0b11111100, 0b00000100, 0b10010010, 0b00000100, 0b11111010, 0b00000000, 0b01001000
.db 0b11111010, 0b01010010, 0b01000110, 0b11111110, 0b10000100, 0b11001110, 0b00000100, 0b00001000, 0b00000010, 0b11011110
.db 0b10100110, 0b01011010, 0b00000100, 0b10011010, 0b00100110, 0b10101000, 0b00100000, 0b10011000, 0b11111100, 0b01100000
.db 0b11000100, 0b00010100, 0b01100100, 0b10110100, 0b00000100, 0b01000000, 0b10000110, 0b11000010, 0b11111110, 0b00111010
.db 0b01101100, 0b10011110, 0b11010000, 0b00000010, 0b00101010, 0b01010010, 0b10000100, 0b10100010, 0b11001010, 0b11110010
.db 0b00010000, 0b00111000, 0b01010110, 0b01110100, 0b10010010, 0b10110000, 0b11001110, 0b11100010, 0b00000000, 0b00010100
.db 0b00110010, 0b01000110, 0b01100100, 0b01111000, 0b10001100, 0b10100000, 0b10110100, 0b11001000, 0b11011100, 0b11110000
.db 0b00000100, 0b00011000

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

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

Сообщение akl »

Здравствуйте. Не указан тип контроллера, но, судя по назначению бита разрешения прерывания переполнения Т1 это что-то типа mega8. Проверил в студии 3.21 для 90S8515; принудительно сделал различные таблицы, вроде никаких противовопоказаний нет.
За одним попробовал свое представление занесения значений из таблицы в формате старший-младший. Находится в закомментированном T1_OVER1.
Аватара пользователя
Roman Venom
Сверлит текстолит когтями
Сообщения: 1135
Зарегистрирован: Сб июл 11, 2009 18:42:21
Откуда: Украина, г.Николаев

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

Сообщение Roman Venom »

akl
Благодарю. У меня атмега16 на 5В.
Возникло несколько вопросов по вашей программе.

T1_OVER1:
OUT TCCR1B,ZERO ;остановить таймер
OUT TCNT1H,ZERO
OUT TCNT1L,ZERO
RCALL NEXT
OUT TIFR,_FF ; сброс флагов Т1
OUT TCCR1B,A ; запусить таймер

Первые 3 бита регистра TCCR1B отвечают(по крайней мере в меге16) за предделитель тактовой частоты. Зачем его сбрасывать а потом устанавливать в прерывании, если можно запретить прерывание по переполнению(а по выходу из прерывания разрешить) и обнулить счётчики(собсно это у вас есть). Не подумайте, что придираюсь: просто интересно.

и ещё маленький вопросик
NEXT:
ldi ZH,High(T_speed1*2); *
ldi ZL,Low(T_speed1*2); *
add ZL,BLDC_cnt ;указать адрес ячейки таблицы
adc ZH,ZERO
LPM; извлечь из флеш-памяти *
OUT TCNT1H,R0;отправить в таймер *
ADIW ZL,1
LPM
OUT TCNT1L,R0;отправить в таймер *
INC BLDC_cnt ; только для теста!!!!!!!
INC BLDC_cnt ; только для теста!!!!!!!
ret ;*

Интересует зачем здесь применена строчка АDIW ZL,1.
В регистровую пару прибавляется по единице для извлечения из таблицы следующей по счёту ячейки и всё?
П.С. Ну и смещать таблички заданием адреса попробую. Может, в этом дело.
Успех - императив!
Аватара пользователя
Liv
Вымогатель припоя
Сообщения: 525
Зарегистрирован: Сб сен 20, 2008 12:12:30
Откуда: Minsk
Контактная информация:

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

Сообщение Liv »

Если это мега16, то проще использовать команду LPM Rxx,Z+
Аватара пользователя
Roman Venom
Сверлит текстолит когтями
Сообщения: 1135
Зарегистрирован: Сб июл 11, 2009 18:42:21
Откуда: Украина, г.Николаев

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

Сообщение Roman Venom »

Liv
Если это мега16, то проще использовать команду LPM Rxx,Z+

Проще, если требуется последовательно извлекать из таблички. А если изменение счётчика должно происходить, допустим, по нажатию кнопки, то не очень.
Успех - императив!
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Мне было лениво создавать проект в 4-й студии, поэтому использовал "классику", в которой нет еще таких продвинутых команд.
По поводу сброса-запуска таймера в прерывании
-запрет прерывания в самом прерывании нелогичен, т.к. I-флаг сбрасывается в прерывании аппаратно. Другое дело очищать флаги или исключать из таблиц состояния вызывающие такие требования (например первый элемент Вашей таблицы, в котором сразу в таймер загружается максимальное число, а таймер не остановлен. Т.е. следующее прерывание будет несанкционированным)
-манипуляции с предустановками в TCNT1 можут привести к появлению флага TOV1, да и другие флаги могут взвестись. Причем на аппаратном уровне. Я так привык делать
-остановил
-очистил, чтобы начинать с одной точки
-загрузил требуемое значение
-сбросил флаги
-запустил
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Roman Venom писал(а):Проще, если требуется последовательно извлекать из таблички. А если изменение счётчика должно происходить, допустим, по нажатию кнопки, то не очень.
Liv абсолютно прав и для данного случая, ведь из таблички извлекается больше одного байта. Если уж на асме писать, то зачем делать хуже, чем сделает С-компилятор?

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

...
   adc   ZH,ZERO
   LPM   R0, Z+
   OUT   TCNT1H,R0
   ; и эта команда оказалась не нужна ;  ADIW   ZL,1
   LPM
   OUT   TCNT1L,R0
   ...
Кстати, а почему в табличке константы хранятся старшим байтом по младшему адресу, неудобно же табличку задавать. Что двумя полутаблицами, что с переставленными байтами... Иногда есть за что побороться, но лучше хранить в естественном порядке. Тут, похоже, ZL/ZH уже не нужны после вычитывания из таблички, так что (чтобы лишний регистр не занимать)

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

...
   adc   ZH, ZERO
   LPM   R0, Z+ ; младший
   LPM   ZL, Z   ; старший
   OUT   TCNT1H, ZL ; старший
   OUT   TCNT1L, R0 ; младший
   ...
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Ответить

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