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

Обсуждаем контроллеры компании Atmel.
Ответить
Это не хвост, это антенна
Сообщения: 1495
Зарегистрирован: Ср июн 25, 2008 15:19:44
Re:

Сообщение Demiurg »

Ассемблер ничем не отличается от других языков в плане абстракций. Проектирование сверху вниз. Забудьте о регистрах, байтах и тактах. Устройство, блоки устройства, блоки блоков. Алгоритмы. Берете бумажку и составляете ТЗ. Рисуйте алгоритмы. Когда это у вас будет, тогда будут и программы. По сути, программы будут писаться по нарисованным алгоритмам. Пишите программы на ассемблере так, как будто вы пишете на языке высокого уровня.
Ссылки на цикл статей я вам давал. Читайте, там все разжевано и даже картинки есть. Вам осталось написать программу по этим картинкам.
Контактная информация:
Реклама
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск
Re:

Сообщение akl »

[uquote="radio-fan",url="/forum/viewtopic.php?p=3189945#p3189945"]

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

;#############################################################################################
;ПРЕРЫВАНИЕ ПО КНОПКЕ
;#############################################################################################

EXT_INT0:   in Temp, SREG          ;сохраняем флаги в стек
			push Temp              ;
            clr Temp               ;
            out GICR, Temp         ;запрещаем прерывание по кнопке
	        out TCCR1B, Temp       ;останавливаем компаратор
			out TCCR0, Temp        ;останавливаем таймер 0
			out TCNT0, Temp        ;очищаем регистр 0 таймера
			cbr Flag, 0b01000000   ;длинного нажатия нет

            sbrs Flag, 5           ;если 0 то было нажатие, если 1 то отпускание
			rjmp PushCycl          ;
			clr Count              ;
			ldi Temp, 0b00000011   ;настройка предделителя
	        out TCCR1B, Temp       ;вывод в TCCR1B
			mov Temp, Flag         ;сравниваем счётчик нажатий
			andi Temp, 0b00001111  ;
			cpi Temp, 11           ;
			brne GO1               ;
			andi Flag, 0b11110000  ;
			rjmp GO2               ;
GO1:        inc Flag               ;
GO2:        cbr Flag, 0b00100000   ;
            ldi TimCount, 195      ;пауза 0,05 с
            ldi Temp, 0b00000001   ;запускаем таймер 0
			out TCCR0, Temp        ;частота 1/8
			clr count              ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			reti

PushCycl:   sbr Flag, 0b00100000   ;
            ldi TimCount, 146      ;пауза 0,25 с
            ldi Temp, 0b00000011   ;частота 1/32
			out TCCR0, Temp        ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			sei                    ;
			rjmp Do                ;конец прерывания[/uquote]Здесь будет срыв стека, т.к. выход из прерывания по RJMP
Реклама
Родился
Аватара пользователя
Сообщения: 8
Зарегистрирован: Чт май 18, 2017 11:57:03
Откуда: Барнаул

Сообщение radio-fan »

Если прерывание int0 произойдёт во время отсчёта задержки, то командой reti мы вернёмся обратно в задержку, а после прерывания она нам уже будет не нужна.
Только вот что, а если из прерывания выходить не через reti, то в стеке будет оставаться адрес?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18795
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

radio-fan писал(а): если из прерывания выходить не через reti, то в стеке будет оставаться адрес?
ясен пень, куда ж ему деваться-то?
не смотря на то, что ассемблер позволяет делать, что угодно, все-таки хорошей практикой следует признать выход из прерывания туда, откуда был вход. собственно, как и из любой другой подпрограммы.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 15802
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

RETI всего лишь сбрасывает блокировку прерываний
(восстанавливает флаг "глобального разрешения" I в регистре статуса SREG после того, как он будет АВТМАТИЧЕСКИ СБРОШЕН при входе в прерывание)
По обработке стека и RET и RETI
ОДНО И ТО ЖЕ.
8)
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18795
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

BOB51 писал(а):По обработке стека и RET и RETI
ОДНО И ТО ЖЕ
только речь про
akl писал(а):rjmp Do ;конец прерывания
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск
Re:

Сообщение akl »

[uquote="radio-fan",url="/forum/viewtopic.php?p=3191470#p3191470"]...если из прерывания выходить не через reti, то в стеке будет оставаться адрес?[/uquote]Да, но указатель стека SP будет смещен и следующие прерывания с таким же условием будут его смещать и смещать. В итоге зависон обеспечен.
Друг Кота
Аватара пользователя
Сообщения: 15802
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

смотря как выходить
:roll:
можно и "комбинированным" способом через "подстановку вектора возврата"... изменение значения самого указателя стека...
там важнее вопрос - допускается или нет на том участке "вложенное" внешнее прерывание.
:roll:
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Вс июн 19, 2016 06:31:18

Сообщение sibiryak69 »

Всем спасибо за подсказку с этим "ldi r16, (1<<USIWMO)|(1<<USICS1)|(1<<USICLK)|(1<<USITC)" разобрался, в СИ то же пользуются таким приемом
Встал на лапы
Сообщения: 89
Зарегистрирован: Вт мар 31, 2015 01:12:46

Сообщение dumbass »

Добрый день! Программа на АSM для тини2313 работает не совсем красиво, как того хотелось бы. Сразу скажу, в качестве практического развития пытаюсь сделать освещения на, как бы, модель автомобиля. Есть 4 кнопки, 4 пары св-диодов. Нажимаем кн1-вкл поворот влево, кн2- передний свет и т.д. Далее будет идти речь только о левом повороте и переднем освещении (для простоты и понятности изложения).
Чего хочется: есть две кнопки( с фиксацией). Нажимаем одну - первая пара св-диодов должна моргать (частота 1Гц). Нажимаем вторую кнопку - другая пара св-диодов должна просто засветится.
Что не получается: программа работает правильно, НО! не красиво... допустим, я нажал на кн1 и через долю секунды на кн2. Первая пара св-диодов загорелась, вторая пара тоже уже должна загореться, НО! МК в это время выполняет задержку для свечения первой пары, затем выключит первую пару и вновь 0,5секунды будет выполнять задержку и лишь затем включит мне вторую пару... и эта небольшая задержка во вкл 2-рой пары создает в моей душе неприятный осадок :( :cry: )))
У меня была идея :idea: по коду программы по чаще растолкать команду опроса вкл 2-рой пары, но... интуиция новичка мне подсказывает, что это не профессионально :))
Код программы:
;Инициализация портов
clr R16
out DDRD,R16
ser R16
out PORTD,R16

out DDRB,R16
clr R16
out PORTB,R16
;Основной цикл
MAIN:
check_L:sbis PIND,PIND0 ;Запрос вкл левой пары
rjmp left
cbi PORTB,7
cbi PORTB,6

check_F:sbis PIND,PIND1 ;Запрос вкл передней пары
rjmp frwrd
cbi PORTB,5
cbi PORTB,4
rjmp MAIN


left: sbi PORTB,7 ;Вкл левой пары
sbi PORTB,6
rcall delay_LR
cbi PORTB,7
cbi PORTB,6
rcall delay_LR
rjmp check_F

frwrd: sbi PORTB,5 ;Вкл передней пары
sbi PORTB,4
rjmp check_L
delay_LR:
; ===========
; delay loop generator
; 500000 cycles:
(Задержку вырезал да бы не засорять эфир)
ret

Спасибо за ответ!
Друг Кота
Аватара пользователя
Сообщения: 15802
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

4 кнопки (да еще и с фиксацией!) и 4 светика (группы светиков) это задача для релейно-контактной логики (не то чтоб для МК). Ну отсилы еще пару NE555...
8)
а тут "МК не справляется"...
:facepalm:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

dumbass писал(а):Программа на АSM для тини2313...Чего хочется: есть две кнопки( с фиксацией). Нажимаем одну - первая пара св-диодов должна моргать (частота 1Гц). Нажимаем вторую кнопку - другая пара св-диодов должна просто засветится.
Я бы использовал таймер (частота 1Гц), в прерывании таймера изменял бы состояние первой пары св-диодов.
В основном цикле опрашивал бы кнопки без каких либо задержек, ну разве что на дребезг.
При опросе первой кнопки принимаем решение о запуске таймера или даем разрешение таймеру моргать первой парой св-диодов.
При опросе второй кнопки - зажигаем вторую пару св-диодов.
Где-то так.
Встал на лапы
Сообщения: 89
Зарегистрирован: Вт мар 31, 2015 01:12:46

Сообщение dumbass »

Спасибо за ответы!!!
С помощью NE555 не хочется решать так проблему. Хочется решить программно, а не аппаратно ( для того ж и изучаю МК :) )
Буду пытаться на таймерах... нужно только до них добраться их изучить как следует.
Спасибо за понятный алгоритм и видео, очень доходчиво и понятно.
Если получится, то обязательно поделюсь результатами :)
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Если с пониманием таймеров сложности, можно и без них. Просто не использовать полусекундные задержки, а дробить их на более короткие.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15802
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

[uquote="dumbass",url="/forum/viewtopic.php?p=3208923#p3208923"]... Хочется решить программно, а не аппаратно ( для того ж и изучаю МК :) )...[/uquote]
Ну ежли только для учебы...
Есть буфер ввода (одновременно ВСЕ ВОЗМОЖНЫЕ комбинации кнопок) и есть буфер вывода (одновременно ВСЕ ВОЗМОЖНЫЕ комбинации включения светиков) есть таймер опроса и таймер инвертора... (независимо - программные или аппаратные).
Можно еще флажок добавить - разрешение работы инвертора.
Итогом - согласно статуса считанного состояния входных линий активируем соответствующие позиции выходных сигналов и флаг разрешения работы инвертора.
Порционно выпихиваем содержимое буфера вывода в порт вывода. А инвертор в ведомы ему моменты меняет статус нужных ему бит в буфере (пока ессно его работа разрешена флажком).
8)
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Надо просто правильно разбить программу на задачи. Сделайте так называемый суперцикл, который будет выполняться с заранее заданной задержкой - например 10мс. В этом цикле, смотрим на кнопки и выставляем в переменной "флажки". Задача простая как 5 копеек, не правда ли?
Вторая задача - на каждый флажок своя ветка в суперцикле, с немигающими фарами понятно - ничего дополнительно анализировать не надо, просто смотрим на КОНКРЕТНЫЙ флажок и включаем нужную пару светодиодов, или выключаем.
Немного сложнее с поворотами - для каждого из них заводишь дополнительную переменную счетчик - когда флажок поворота неактивен - принудительно гасим соответствующий светодиод и ОБНУЛЯЕМ его счетчик, если флажок активен - и счетчик равен нулю - меняем состояние светодиода на противоположное. Инкрементируем счетчик, и когда он достигает значения 100(или 50?) - сбрасываем. Всё.

В итоге имеем не одну монолитную программу которую сложно отлаживать, а отдельные блоки логика которых просматривается прозрачно(зависит исключительно от строго указанных входных данных и имеет конкретный легко проверяемый результат работы) и которые отлаживать можно отдельно от остальных.
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Сообщение strengerst »

Всем привет, не могу справиться с банальной задачей - подключение компаратора и сделать так что бы он вошел в прерывание, из-за разности напряжения в 2 вольта, и подключил PORTB4 . Вот код на ассемблере, и снимок в протеусе.
Спойлер

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


// Команда для переименования регистров.
.def ZERO=R22;
.def XXX=R23;
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
rjmp START; IRQ0 Handler
rjmp START;; PCINT0Z Handler
rjmp START; Timer0 Overflow Handler
rjmp START; EEPROM Ready Handler
rjmp Comparator; Analog Comparator Handler
rjmp ObrobotkaTIM0_COMPA; TIM0_COMPA CompareA Handler
rjmp START; Timer0 CompareB Handler
rjmp START; Watchdog Interrupt Handler
rjmp START; ADC Conversion Handler

//Оброботка прерывания от компаратора
Comparator:
CLI; команда запрещает глобальные прерывания.
cbi DDRB,4; - Устанавливаем порт как на выход, 
sbi PORTB,4; - Подкючаем подтягивающий резистор для включения лампы
sei; - команда разрешает глобальные прерывания
reti; - Выход с под программы прерывания
//оброботка прерывания порта INT0, по высокому сигналу. 


//Прерывания при совапдении таймера
ObrobotkaTIM0_COMPA:
inc XXX;
reti;

 /*Код установки таймера счетчика*/
TIMER:
/*
TIFR0 - регистр индикации флагов прерывания
TOV0 - флаг индикации по переполнению таймера
OCF0A,OCF0B - флаг индикации по совпадению. 
OCR0A,OCR0B - регистр установки значения для совпадения.
TCCR0A - регистр управления A;
TCCR0B - регистр управления B;
*TIMSK0 - Регистр выбора режима срабатывания прерывания
TOIE0 - по переполнению, OCIE0A - по совпадению со значанием в регистре А,
OCIE0B - по совпадению со значанием в регистре B.
*/

ldi R16, (1<<OCIE0A);Установка режима по совпадению с А;
out TIMSK0, R16;
ldi R16, 0xFF; Устанавливаем значение при совпадении с А
out OCR0A, R16;
ldi R16, 0x00;// Сбрасываем все флаги таймера
out TIFR0, R16;
/*Скорость работы таймера выбираем СК/1024 - где СК - частота работы микроконтролера 
в нашем случаи мы выставляем во fuces clkdiv8 что обеспечит нам частоту 9,6Мhz/8=1,2Mhz значит 
скорость работы таймера будет 1,2Mhz/1024=1,17Khz что увеличивает счет значения. Чем меньше 
частота тем большее время срабатывания до прерывания*/
ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00);
out TCCR0B, R16;

ret; //возврат из подпрограммы TIMER:

//Определяем начальные параметры микроконтролера.

START:

 CLI; команда запрещает глобальные прерывания.
 //инициализация стэка.(установка максимально размера ОЗУ);
 ldi R17, RAMEND;
 out SPL, R17;
 ldi ZERO, 0x00; //Присваеваем значение 0 переменной zero;
 
 //Отключаем аналогово-цифровой преобразователь
 CBI ADCSRA, ADEN;
//Подключаем компаратор для сравнения сигналов
////Команда CBI устанавливает значение в 0 регистра ACSR ячейки ASD что включает компаратор - по умолчанию он и так включен;
CBI ACSR, ACD;
//Команда SBI устанавливает значение в 1 регистра ACSR ячейки ACIE которая включает разрешения прерывания от компаратора.
SBI ACSR, ACIE;
//Устанавливаем условие генерации прерывания выставляем изменения сосотояния от 0 до 1;
sbi ACSR, ACIS1;
sbi ACSR, ACIS0;
//инициализация портов ввода вывод

//Устанавливаем работу портов на вход и выход. 
//Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
//Если порт DDB установлен в 1 то данный порт является входам, 
//а если в 0 то выходам.
ldi R16,(0<<DDB5)|(0<<DDB4)|(0<<DDB3)|(0<<DDB2)|(1<<DDB1)|(1<<DDB0);
out DDRB, R16;
//Разрешаем глобальные прерывания
sei;
//Переходим к основному циклу проверки
rjmp START1;

START1:
nop;
rjmp START1;

Снимок в протеусе
СпойлерИзображение
Вложения
Коту.png
(27.85 КБ) 429 скачиваний
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

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

//Если порт DDB установлен в 1 то данный порт является входам,
//а если в 0 то выходам.
DDRx=1 это выход!
Желательно отключать цифровые входы от лап АС

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

 //Отключаем аналогово-цифровой преобразователь
; CBI ADCSRA, ADEN;
//Подключаем компаратор для сравнения сигналов
////Команда CBI устанавливает значение в 0 регистра ACSR ячейки ASD что включает компаратор - по умолчанию он и так включен;
;CBI ACSR, ACD;
//Команда SBI устанавливает значение в 1 регистра ACSR ячейки ACIE которая включает разрешения прерывания от компаратора.
;SBI ACSR, ACIE;
//Устанавливаем условие генерации прерывания выставляем изменения сосотояния от 0 до 1;
	LDI	R22,1<<ACIS1|1<<ACIS0|1<<ACIE
	OUT	ACSR,R22
	LDI	R22,1<<AIN1D|1<<AIN0D
	OUT	DIDR0,R22

;sbi ACSR, ACIS1;
;sbi ACSR, ACIS0
Последний раз редактировалось akl Чт окт 26, 2017 11:02:00, всего редактировалось 1 раз.
Вымогатель припоя
Аватара пользователя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Сообщение strengerst »

А вот и нет. В книги написано:

Изображение
Вложения
Коту2.png
(56.18 КБ) 815 скачиваний
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18795
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

[uquote="strengerst",url="/forum/viewtopic.php?p=3216583#p3216583"]А вот и нет. В книги написано:
Изображение[/uquote]
читайте оригинальные даташиты. в этой книжке ошибка.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Ответить

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