Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.10.2011, 23:57   #1
Faton 11
Пользователь
 
Регистрация: 04.10.2011
Сообщений: 74
По умолчанию Зажигание светодиодов от кнопки

Здравствуйте! Пожалуйста, помогите. Изучаю ассемблер, хочу написать программу для зажигания светодиодов от кнопки.
Светодиоды подключены к выводам PD6 и PD7 и через резисторы - на общий провод, кнопка - на PE4. Нажатие кнопки должно генерировать прерывание на зажигание одного светодиода, при следующем нажатии кнопки загорается второй светодиод, при этом первый светодиод гаснет. Таким образом, светодиоды должны загораться от кнопки попеременно. При 1-м,2-м,3-м (т.е. нечетных) нажатиях должна выполняться подпрограмма для зажигания 1-ого светодиода, при четных - подпрограмма для зажигание второго светодиода. Как это осуществить с помощью команды "исключающее или"?

Вот что пока получилось:

Код:
.include "m128def.inc" 

.org	0
	jmp	reset   		

.ORG 0x0002
	 rjmp forever ;прерывание должно происходить по этому адресу


begin: 

   ldi r16,low(RAMEND) 
   out spl,r16 
   ldi r16,high(RAMEND)  
   out sph,r16 

;инициализация светодиодов
   ldi r16,(1<<6) | (1<<7) 
   out DDRD,r16 


;к линии, отвечающей за кнопку подключаем подтягивающий резистор
   ldi r16,(1<<4) 
   out PORTE,r16 

;направление передачи данных - на вход
   ldi r16,0 
   out DDRE,r16

;инициализация прерываний
   ldi r16,0x80
   out SREG,r16

   ldi r16,0x01  ;накладываем "маску" на регистр прерываний
   out EIMSK,r16 ;за разрешение прерываний отвечает разряд  Int0

;определяем условия генерации прерываний
   ldi r16,(0<<ISC41)|(0<<ISC40);  - по низкому уровню
   out EICRB,r16
     
main program:   
   rjmp forever
    

forever:  
push r16

;полагаю, в этом месте должна быть команда "исключающее или" то бишь eor, 
но какой регистр с каким с помощью неё нужно складывать? 
В зависимости от четного/нечетного нажатия кнопки переходим к процедуре forever1/forever2

forever1: 
in r16,PINE ; считываем текущее состояние кнопки 
com r16 ; кнопка "нажимается" нулем, поэтому инвертируем регистр
lsl r16 ; переносим бит "4" в позицию "6"
lsl r16 
andi r16,(1<<6); "обновляем" показания светодиодов  
out PORTD,r16 
sbrc r16,(1<<6);если светодиод горит, пропускаем следующую команду
rcall forever1
pop r16
reti
rcall main program

forever2: 
in r16,PINE ;считываем текущее состояние кнопки
com r16 ; кнопка "нажимается" нулем, поэтому инвертируем регистр
lsl r16 ; переносим бит "4" в позицию "7"
lsl r16
lsl r16
andi r16,(1<<7)  ;"обновляем" показания светодиодов
out PORTD,r16 
sbrc r16,(1<<7) ;если светодиод горит, пропускаем следующую команду
rcall forever2 
pop r16
reti
rcall main program

Последний раз редактировалось Stilet; 12.10.2011 в 08:27.
Faton 11 вне форума Ответить с цитированием
Старый 12.10.2011, 22:35   #2
С.М.С
Участник клуба
 
Аватар для С.М.С
 
Регистрация: 29.12.2008
Сообщений: 1,598
По умолчанию

Не думал, что чтобы помочь надо всё сначала проверить. Адреса прерываний не совпадают. по адресу 0x0002 находится INT0, а это вывод PD0. Нет объявленной процедуры Reset и.т.д. Извините, но не стал лепить к самолёту плуг в виде EOR. И оставил объявленное прерывание INT0, поэтому поменяйте кнопку на PD0 или выберете другое прерывание. Защиту от дребезга если потребуется добавите сами.


Код:

.device ATmega128
.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m128def.inc"


;=============== Прерывания ====================================================================
	.org 0								;Начало программы после сброса
	jmp RESET ; Reset Handler
	.org INT0addr						;адрес прерывания INT0
	jmp EXT_INT0


.def temp = r16
.def Flag = r17



RESET: 

	ldi temp,low(RAMEND) 
	out spl,r16 
	ldi temp,high(RAMEND) 
	out sph,r16 

	;к линии, отвечающей за кнопку подключаем подтягивающий резистор
	ldi temp,(1<<0) 
	out PORTD,temp 

	;направление передачи данных - на вход и инициализация светодиодов
	ldi temp,0b11000000 
	out DDRD,temp

	ldi temp,(0<<ISC01)|(0<<ISC00)	;устанавливаем прерывание по спаду
	out MCUCR,temp

	ldi temp,(1<<INT0)	;разрешаем прерывание INT0
	out GIMSK,temp


	ldi Flag,1	

sei



;============Главный цикл==================
 Main: 
	nop
	nop
jmp Main
;------------------------------------------



;============Процедура обработки прерывания INT0 ===========
EXT_INT0:
		;
	clr temp
	out GIMSK,temp
		;
	ldi temp,$FF
	out GIFR,temp	;

	ldi temp,1
	cp Flag,temp
	breq LED_1_light_up
	
	ldi temp,2
	cp Flag,temp
	breq LED_2_light_up
;------------------------------------------------------------



;============Процедура индикации первого светодиода===========
LED_1_light_up:
	cbr Flag,0b00000001
	sbr Flag,0b00000010

	ldi temp,0b01000001
	out PortD, temp

	ldi temp,(1<<INT0)	;разрешаем прерывание INT0
	out GIMSK,temp

	sei

reti
;------------------------------------------------------------



;============Процедура индикации второго светодиода================
LED_2_light_up:
	cbr Flag,0b00000010
	sbr Flag,0b00000001

	ldi temp,0b10000001
	out PortD, temp

	ldi temp,(1<<INT0)	;разрешаем прерывание INT0
	out GIMSK,temp

	sei

reti
;------------------------------------------------------------

Последний раз редактировалось С.М.С; 12.10.2011 в 23:31.
С.М.С вне форума Ответить с цитированием
Старый 13.10.2011, 00:37   #3
Faton 11
Пользователь
 
Регистрация: 04.10.2011
Сообщений: 74
По умолчанию

Первый блин комом.. =)Спасибо за помощь огромное! =)
Faton 11 вне форума Ответить с цитированием
Старый 17.10.2011, 23:31   #4
Faton 11
Пользователь
 
Регистрация: 04.10.2011
Сообщений: 74
По умолчанию

Начала разбираться, появились вопросы:

Разве можно в моделе ATmega128 использовать регистры GIMSK и MCUCR?
Кажется,для этой модели контроллера для внешних прерываний существуют следующие регистры:
EIMSK – регистр для разрешения/запрещения внешних прерываний
EICRA и EICRB – регистры, определяющие условия генерации
EIFR – регистр, предназначенный для индикации возникновения внешних прерываний
Так же нужно учесть флаг I регистра SREG

Как при этом для генерации по низкому уровню использовать регистры EICRA и EICRB. И вообще, как их использовать? Почему их два и одинаковые ли они выполняют роли?

Для чего в подпрограмме Мain: нужно ждать 2 машинных цикла? И почему после выполнения команды nop сразу перебрасывает к переходу на EXT_INT0, вместо того, чтобы выполнить следующий nop, а затем jmp Main?
Faton 11 вне форума Ответить с цитированием
Старый 18.10.2011, 01:03   #5
С.М.С
Участник клуба
 
Аватар для С.М.С
 
Регистрация: 29.12.2008
Сообщений: 1,598
По умолчанию

Цитата:
Сообщение от Faton 11 Посмотреть сообщение
Начала разбираться, появились вопросы:

Разве можно в моделе ATmega128 использовать регистры GIMSK и MCUCR?
Кажется,для этой модели контроллера для внешних прерываний существуют следующие регистры:
EIMSK – регистр для разрешения/запрещения внешних прерываний
EICRA и EICRB – регистры, определяющие условия генерации
EIFR – регистр, предназначенный для индикации возникновения внешних прерываний
Так же нужно учесть флаг I регистра SREG

Как при этом для генерации по низкому уровню использовать регистры EICRA и EICRB. И вообще, как их использовать? Почему их два и одинаковые ли они выполняют роли?

Для чего в подпрограмме Мain: нужно ждать 2 машинных цикла? И почему после выполнения команды nop сразу перебрасывает к переходу на EXT_INT0, вместо того, чтобы выполнить следующий nop, а затем jmp Main?
Да, удалите из RESET MCUCR, оно там не надо.

GIMSK = EIMSK это определоно в описание адресов и констант

Код:
; EIMSK - External Interrupt Mask Register
.equ	GICR	= EIMSK	; For compatibility
.equ	GIMSK	= EIMSK	; For compatibility
EICRA для прерывний т.е выводов от 0 до 3, EICRB для от 4 до 7

команды nop показаны, что в процедуре MAIN, что-то может выполняться, в место того, чтобы в пустую молотить в ожидании нажатия кнопки.

Что бы всё работало в отладчике поставьте бит PDO это PIND0, что соответствует высокому уровню на входе МК. Для того чтобы с эмитировать нажатие кнопки снимите этот бит.
С.М.С вне форума Ответить с цитированием
Старый 24.11.2011, 00:07   #6
Faton 11
Пользователь
 
Регистрация: 04.10.2011
Сообщений: 74
По умолчанию

Ура! =) Ваши проги помогли! Спасибо =)
Faton 11 вне форума Ответить с цитированием
Старый 29.11.2011, 19:33   #7
Faton 11
Пользователь
 
Регистрация: 04.10.2011
Сообщений: 74
По умолчанию

Появились новые вопросы:
1. Чтобы светодиоды загорались от нажатия кнопки на клавиатуре, достаточно будет одностороннего режима? (т.е. инициализируем USART не на прием/передачу, а лишь на прием) И можно ли так делать вообще?

2. Какие линии отвечают за клавиатуру?
Faton 11 вне форума Ответить с цитированием
Старый 22.06.2012, 10:35   #8
Вячеслав-sda
Новичок
Джуниор
 
Регистрация: 22.06.2012
Сообщений: 2
По умолчанию

Вы можете мне помочь сделать один прибор? Ищу знающего человека. Есть заказ.
Вячеслав-sda вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
кнопки Артэс Win Api 10 08.12.2009 20:04
Кнопки Принц HTML и CSS 1 29.05.2008 17:25
UCOZ: Кнопки кнопки на изображении ReDuX HTML и CSS 19 25.04.2008 02:39
Кнопки )Игнат( Компоненты Delphi 21 22.01.2008 09:35
триггерные кнопки и кнопки переключатели в DELPHI MARGO Помощь студентам 3 12.11.2007 17:35