Страница 10 из 15

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 04, 2012 16:25:39
uwrtey
то-есть, если я правильно понял, основная задача - проверить читается ли клавиатура?

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 04, 2012 16:38:59
ВитГо
основная задача прочитать клавиатуру и потом проверить а была ли нажата хоть одна кнопка

в готовой программе мы будем читать клаву, и как только зарегистрируем нажатие какой нить кнопки - бум переходить к передаче этих 5 байт

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 04, 2012 21:26:37
uwrtey
вот написал программулину
Спойлер

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



 	.def	Temp=R16
	.def	Temp1=R17
	.def	Temp2=R18
	.def	Temp3=R19
	.def	Temp4=R20
	.def	Temp5=R21
	.def	Temp6=R22
	.def	Temp7=R23
	.def	Temp8=R24
	.def	Temp9=R25


.dseg			;оперативка

key_buff: .byte 5	; зарезервируем 5 байт в ОЗУ


;******************************************************************************
;
;******************************************************************************

.cseg
.org 0


					; СТАРТ
rjmp RESET				; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset

.org	INT0addr;	= 0x0001	; External Interrupt Request 0
reti
.org	INT1addr;	= 0x0002	; External Interrupt Request 1
reti
.org	ICP1addr;	= 0x0003	; Timer/Counter1 Capture Event
reti
.org	OC1Aaddr;	= 0x0004	; Timer/Counter1 Compare Match A/////////////////////////
rjmp TIM1_COMPA
.org	OVF1addr;	= 0x0005	; Timer/Counter1 Overflow
reti
.org	OVF0addr;	= 0x0006	; Timer/Counter0 Overflow
reti
.org	URXCaddr;	= 0x0007	; USART, Rx Complete
reti
.org	UDREaddr;	= 0x0008	; USART Data Register Empty
reti
.org	UTXCaddr;	= 0x0009	; USART, Tx Complete
reti
.org	ACIaddr;	= 0x000a	; Analog Comparator
reti
.org	PCIBaddr;	= 0x000b	; Pin Change Interrupt Request B
reti
.org	OC1Baddr;	= 0x000c	;
reti
.org	OC0Aaddr;	= 0x000d	;
reti
.org	OC0Baddr;	= 0x000e	; 
reti
.org	USI_STARTaddr;	= 0x000f	; USI Start Condition
reti
.org	USI_OVFaddr;	= 0x0010	; USI Overflow
reti
.org	ERDYaddr;	= 0x0011	; 
reti
.org	WDTaddr;	= 0x0012	; Watchdog Timer Overflow
reti
.org	PCIAaddr;	= 0x0013	; Pin Change Interrupt Request A
reti
.org	PCIDaddr;	= 0x0014	; Pin Change Interrupt Request D
reti


;******************************************************************************
;старт
;******************************************************************************

reset:					; включение микроконтроллера

cli					; глобальный запрет на прерывания


ldi Temp,low(RamEnd)			; инициализации стека	
out SPL,Temp				;



ldi Temp,0b00001001			;
out DDRB,Temp				; настроили порт "В" (0-ввод, 1-вывод)
					; 0000х000 - "вывод" на передатчик (PB3- 15 ножка)
					; хххх0000 - "ввод" для чтения строк клавиатуры
					; 0000000х - "вывод" для индикации того что была нажата какая то кнлпка  ++++++++++++++++


ldi Temp,0b00001111			;
out DDRD,Temp 				; настраиваем порт "D" (0-ввод, 1-вывод)
					; 0000хххх - на вывод столбцов клавы



ldi Temp,(1<<COM1A0)			;переключать ножку "OC1A" по совпадению (PB3- 15 ножка)
out TCCR1A,Temp				;*1



ldi Temp,(1<<wgm12)|(1<<CS12)|(1<<cs10)		;подключили режим "CTC" (вместе с *1) 
out TCCR1B,Temp					; и установили тактовый сигнал = CK 1024  +++++++++++++++++++++++++++++++++++++++
						;таймер начал считать!!!


					; инициализация компаратора
ldi Temp,0xFF				; как и просил -побольше ( 0xFFFF )
out OCR1AH,Temp				; 
ldi Temp,0xFF				; 
out OCR1AL,Temp				; 


ldi Temp,(1<<OCIE1A)			; разрешить прерывание компаратора
out TIMSK,Temp


ldi Temp,0				; обнуление таймера при включении
out TCNT1H,Temp
out TCNT1L,Temp


sei					; глобальное разрешение прерываний
        


ldi Temp,0b00001000			; выводим в порт "Б" на "OC1A" импульс 
out PortB,Temp




;*******************************************************************************
; главный цикл
;*******************************************************************************


main_cycle:

	rjmp main_cycle



;*******************************************************************************
;обработка прерывания
;*******************************************************************************

TIM1_COMPA:				; включен режим CTC 
					; обнуление таймера  происходит автоматически
					; "OC1A" меняет свое логическое состояние автоматически


	ldi Temp,0b00000000		; ВЫВОДИМ "0b00000000" В ПОРТ "Б" (12 ножка) //или выключам светодиод//
	out PortB,Temp


	rcall keyboardread		; вызов подпрограммы чтения клавиатуры

	rcall certain_buttons_keyboard	; вызов подпрограммы проверки нажатия
	
	reti





;*******************************************************************************
; Чтение клавы и запись данных в ОЗУ
;*******************************************************************************

keyboardread:				;метка - опрос клавиатуры

          
	ldi Temp,5			; количество столбцов клавы = пять
         
	ldi Temp1,0b00000001		; первый столбец

          				; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару X
	ldi XL,low(key_buff)		; младший байт адреса
	ldi XH,high(key_buff)		; старший байт адреса

keyboardread_loop:			; цикл опроса

	out PortD,Temp1			; выводим в порт "Д" значение "Temp1" для выбора столбца клавиатуры
	in Temp2,PinB			; прочитали состояние столбца
         
	st X+,Temp2			; сохраним в ОЗУ состояние столбца клавы, 
 					; адрес в регстровой паре "X" автоматом увеличится на 1

	lsl Temp1			; сдвинули единичку выбора столбца клавиатуры на 1
 					; позицию влево

	dec temp			; уменьшим счетчик
	brne keyboardread_loop		; если не все просканировали, то циклимся

ret
       
;******************************************************************************************
;проверка нажатия клавиатуры
;******************************************************************************************



certain_buttons_keyboard:
		

	ldi temp1,5			; УСТАНОВИМ СЧЕТЧИК столбцов клавы	

	
                  			; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару "Z"
	ldi ZL,low (key_buff)		; младший байт адреса
	ldi ZH,high(key_buff)		; старший байт адреса 


Certain_button:


	ld Temp,Z+			; загрузим данные в регистр из ОЗУ по адресу из регистровой пары "Z", 
					; и после этого адресс в регистровой паре автоматически увеличится на еденицу


	cpi Temp,0b00000000		; проверяем, нажата ли какая ни будь кнопка?
	brne inform			; если нажата то переходим на метку


	dec temp1			; уменьшим счетчик
	brne Certain_buttons		; если не все столбцы, то циклимся

metka:


ret

;***********************************************************************************************
;вывод единицы в порт "Б" 
;***********************************************************************************************

inform:

	ldi Temp,0b00000001		; ВЫВОДИМ "0b00000001" В ПОРТ "Б" (12 ножка) //или включам светодиод//
	out PortB,Temp

	rjmp metka

;***********************************************************************************************

после запуска программа крутится в бесконечном цикле
когда срабатывает прерывание
1) программа гасит светодиод (если с прошлого раза он был включен)
2) читает клавиатуру и записывает данные в ОЗУ
3) читает ОЗУ и проверят была ли нажата какая ни будь кнопка
(а) если нажата, то зажигает светодиод и выходит из обработчика
(б) если не нажата, то просто выходит из обработчика

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 04, 2012 21:53:55
ВитГо
приложи архив проекта, а то с экрана браузера не удобно читать

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 04, 2012 22:10:37
uwrtey
вот архивчик
урок3.zip
(19.31 КБ) 204 скачивания

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 04, 2012 22:32:04
ВитГо
в принципе нормально !

правда наверное лучше будет вытащить опрос клавиатуры и проверку из прерывания в главный цикл программы

в прерывании будет только оправка !

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 04, 2012 22:34:31
uwrtey
попробую...
не понял вот эту фразу :
в прерывании будет только оправка !
что за "оправка"?

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 07:05:25
ВитГо
uwrtey писал(а):
в прерывании будет только оправка !
что за "оправка"?
это я "т" пропустил :-))) ОТПРАВКА будет в прерывании :-))

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 09:50:06
uwrtey
а-а вот оно что.... :))

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 19:23:37
uwrtey
вот написал код, в котором, вытащил опрос клавиатуры и проверку кнопок в главный цикл программы, а в прерывании оставил только отправку
Спойлер

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



 	.def	Temp=R16
	.def	Temp1=R17
	.def	Temp2=R18
	.def	Temp3=R19
	.def	Temp4=R20
	.def	Temp5=R21
	.def	Temp6=R22
	.def	Temp7=R23
	.def	Temp8=R24
	.def	Temp9=R25


.dseg			;оперативка

key_buff: .byte 5	; зарезервируем 5 байт в ОЗУ


;******************************************************************************
;
;******************************************************************************

.cseg
.org 0


					; СТАРТ
rjmp RESET				; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset

.org	INT0addr;	= 0x0001	; External Interrupt Request 0
reti
.org	INT1addr;	= 0x0002	; External Interrupt Request 1
reti
.org	ICP1addr;	= 0x0003	; Timer/Counter1 Capture Event
reti
.org	OC1Aaddr;	= 0x0004	; Timer/Counter1 Compare Match A/////////////////////////
rjmp TIM1_COMPA
.org	OVF1addr;	= 0x0005	; Timer/Counter1 Overflow
reti
.org	OVF0addr;	= 0x0006	; Timer/Counter0 Overflow
reti
.org	URXCaddr;	= 0x0007	; USART, Rx Complete
reti
.org	UDREaddr;	= 0x0008	; USART Data Register Empty
reti
.org	UTXCaddr;	= 0x0009	; USART, Tx Complete
reti
.org	ACIaddr;	= 0x000a	; Analog Comparator
reti
.org	PCIBaddr;	= 0x000b	; Pin Change Interrupt Request B
reti
.org	OC1Baddr;	= 0x000c	;
reti
.org	OC0Aaddr;	= 0x000d	;
reti
.org	OC0Baddr;	= 0x000e	; 
reti
.org	USI_STARTaddr;	= 0x000f	; USI Start Condition
reti
.org	USI_OVFaddr;	= 0x0010	; USI Overflow
reti
.org	ERDYaddr;	= 0x0011	; 
reti
.org	WDTaddr;	= 0x0012	; Watchdog Timer Overflow
reti
.org	PCIAaddr;	= 0x0013	; Pin Change Interrupt Request A
reti
.org	PCIDaddr;	= 0x0014	; Pin Change Interrupt Request D
reti


;******************************************************************************
;старт
;******************************************************************************

reset:					; включение микроконтроллера

cli					; глобальный запрет на прерывания


ldi Temp,low(RamEnd)			; инициализации стека	
out SPL,Temp				;



ldi Temp,0b00001001			;
out DDRB,Temp				; настроили порт "В" (0-ввод, 1-вывод)
					; 0000х000 - "вывод" на передатчик (PB3- 15 ножка)
					; хххх0000 - "ввод" для чтения строк клавиатуры
					; 0000000х - "вывод" для индикации того что была нажата какая то кнлпка  ++++++++++++++++


ldi Temp,0b00001111			;
out DDRD,Temp 				; настраиваем порт "D" (0-ввод, 1-вывод)
					; 0000хххх - на вывод столбцов клавы



ldi Temp,(1<<COM1A0)			;переключать ножку "OC1A" по совпадению (PB3- 15 ножка)
out TCCR1A,Temp				;*1



ldi Temp,(1<<wgm12)|(1<<CS12)|(1<<cs10)		;подключили режим "CTC" (вместе с *1) 
out TCCR1B,Temp					; и установили тактовый сигнал = CK 1024  +++++++++++++++++++++++++++++++++++++++
						;таймер начал считать!!!


					; инициализация компаратора
ldi Temp,0xFF				; как и просил -побольше ( 0xFFFF )
out OCR1AH,Temp				; 
ldi Temp,0xFF				; 
out OCR1AL,Temp				; 


ldi Temp,(1<<OCIE1A)			; разрешить прерывание компаратора
out TIMSK,Temp


ldi Temp,0				; обнуление таймера при включении
out TCNT1H,Temp
out TCNT1L,Temp


sei					; глобальное разрешение прерываний
        


ldi Temp,0b00001000			; выводим в порт "Б" на "OC1A" импульс 
out PortB,Temp




;*******************************************************************************
; главный цикл
;*******************************************************************************


main_cycle:



	rcall keyboardread		; вызов подпрограммы чтения клавиатуры

	rcall certain_buttons_keyboard	; вызов подпрограммы проверки нажатия
	
	rjmp main_cycle



;*******************************************************************************
;обработка прерывания
;*******************************************************************************

TIM1_COMPA:				; включен режим CTC 
					; обнуление таймера  происходит автоматически
					; "OC1A" меняет свое логическое состояние автоматически




	cpi Temp3,0b00000000		; проверяем, нажата ли какая ни будь кнопка?
	brne inform_1			; если нажата то переходим на метку


	ldi Temp,0b00000000		; ВЫВОДИМ "0b00000000" В ПОРТ "Б" (12 ножка) //или выключам светодиод//
	out PortB,Temp
	rjmp inform_0

inform_1:

	ldi Temp,0b00000001		; ВЫВОДИМ "0b00000001" В ПОРТ "Б" (12 ножка) //или включам светодиод//
	out PortB,Temp

inform_0:

reti					; выход из обработчика прерывания


;*******************************************************************************
; Чтение клавы и запись данных в ОЗУ
;*******************************************************************************

keyboardread:				;метка - опрос клавиатуры

          
	ldi Temp,5			; количество столбцов клавы = пять
         
	ldi Temp1,0b00000001		; первый столбец

          				; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару X
	ldi XL,low(key_buff)		; младший байт адреса
	ldi XH,high(key_buff)		; старший байт адреса

keyboardread_loop:			; цикл опроса

	out PortD,Temp1			; выводим в порт "Д" значение "Temp1" для выбора столбца клавиатуры
	in Temp2,PinB			; прочитали состояние столбца
         
	st X+,Temp2			; сохраним в ОЗУ состояние столбца клавы, 
 					; адрес в регстровой паре "X" автоматом увеличится на 1

	lsl Temp1			; сдвинули единичку выбора столбца клавиатуры на 1
 					; позицию влево

	dec temp			; уменьшим счетчик
	brne keyboardread_loop		; если не все просканировали, то циклимся

ret
       
;******************************************************************************************
;проверка нажатия клавиатуры
;******************************************************************************************


certain_buttons_keyboard:
		

	ldi temp1,5			; УСТАНОВИМ СЧЕТЧИК столбцов клавы	

	
                  			; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару "Z"
	ldi ZL,low (key_buff)		; младший байт адреса
	ldi ZH,high(key_buff)		; старший байт адреса 


Certain_button:


	ld Temp3,Z+			; загрузим данные в регистр из ОЗУ по адресу из регистровой пары "Z", 
					; и после этого адресс в регистровой паре автоматически увеличится на еденицу


	dec temp1			; уменьшим счетчик
	brne Certain_button		; если не все столбцы, то циклимся


ret

;***********************************************************************************************
вот проект
urok4.rar
(15.66 КБ) 197 скачиваний
Только вот сразу несколько замечаний по этому коду:
Прерывание может произойти в любой момент - когда опрашивается клавиатура или когда происходит проверка нажатой кнопки.
После того, как обработчик прерываний закончит свою работу - то программа вернется в главный цикл и в это время значения некоторых регистров будут заполнены "левыми" данными (с которыми работал обработчик прерываний)
В общем - лучше не получилось... ( не соображу ни как :dont_know: )
ЗЫ: может лучше сделать наоборот? в обработчик прерывания засунуть опрос клавиатуры и проверку нажатия кнопок, а в основной цикл поместить отправку ??

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 19:29:32
ВитГо
а ты не включай сначала счетчик (в предделитель запиши 0).. :-))

по идее пока кнопки не нажаты - передавать то и нечего.. так что в прерывании делать нечего

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 20:24:04
uwrtey
что то смысл не могу уловить.

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 20:30:35
ВитГо
а что тут понимать?

если у тебя нет нажатых кнопок - то и отправлять нечего...

нам важно выдерживать временные интервалы именно при отправке, поэтому отправку бум делать через таймер

а вот опрос клавиатуры пока сделаем просто в непрерывном цикле.. (по хорошему нужно использовать другой таймер)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 21:20:31
uwrtey
:write: утро вечера мудренее :sleep: (ни чего в голову не идет)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 05, 2012 22:05:14
ВитГо
Кстати, а ты уже схему приемника придумал ?

для входа нам наверное ICP вход понадобиться.. или какой нить из int1 или int0

а вот выходные линии - это уже только от твоей фантазии :-)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 06, 2012 09:56:28
uwrtey
ВитГо писал(а):Кстати, а ты уже схему приемника придумал ?
Нет, даже не начинал. Нужно до конца с передатчиком разобраться...
Сейчас пытаюсь затолкать в обработку прерывания отправку единицы на свободный пин...
в нашем варианте если зарегистрировано нажатие любой кнопки нужно будет просто вывести "1" на какой нить порт микроконтроллера - так мы проконтролируем что программа считывает значения с клавиатуры
а все остальное оставить в основном цикле .... (чЁ тут я торможу - пытаюсь додуматься....)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 06, 2012 10:13:33
clawham
если на выходе приёмника у вас нормальный PPM сигнал то декодер - это одна микруха и пара резюков-кондюков

http://www.rcgroups.com/forums/showatt. ... 1316256633

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 06, 2012 11:16:34
uwrtey
ВитГо писал(а):нам важно выдерживать временные интервалы именно при отправке, поэтому отправку бум делать через таймер
нам таймер нужен для того что бы:
а) сработало прерывание и программа пошла в цикл отправки ?
б) или нам надо, что бы в цикле отправки, включился таймер и отправка разных бит происходила по таймеру?

по идее второе, но ведь Ты просил просто включить светодиод прикошаченный к свободному пину любого порта мк (не OC1A )
по идее подпрограмма проверки кнопок просто должна сравнивать 5 байт считанных линий клавиатуры с 0x00
если значение не равно 0х00 - значит какая то кнопка была нажата и нужно начать передачу
в нашем варианте если зарегистрировано нажатие любой кнопки нужно будет просто вывести "1" на какой нить порт микроконтроллера - так мы проконтролируем что программа считывает значения с клавиатуры
:facepalm: что то я совсем запутался :dont_know: для чего нужен таймер именно в этой программулине ? мы ведь собираемся проверить читается ли клавиатура или нет....
короче я пытаюсь написать то - сам не понимаю что и для чего... :)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 06, 2012 11:53:27
uwrtey
сейчас еще попробую один вариант............ :write:
.....
и вот что получилось
Спойлер

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



 	.def	Temp=R16
	.def	Temp1=R17
	.def	Temp2=R18
	.def	Temp3=R19
	.def	Temp4=R20
	.def	Temp5=R21
	.def	Temp6=R22
	.def	Temp7=R23
	.def	Temp8=R24
	.def	Temp9=R25


.dseg			;оперативка

key_buff: .byte 5	; зарезервируем 5 байт в ОЗУ


;******************************************************************************
;
;******************************************************************************

.cseg
.org 0


					; СТАРТ
rjmp RESET				; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset

.org	INT0addr;	= 0x0001	; External Interrupt Request 0
reti
.org	INT1addr;	= 0x0002	; External Interrupt Request 1
reti
.org	ICP1addr;	= 0x0003	; Timer/Counter1 Capture Event
reti
.org	OC1Aaddr;	= 0x0004	; Timer/Counter1 Compare Match A/////////////////////////
rjmp TIM1_COMPA
.org	OVF1addr;	= 0x0005	; Timer/Counter1 Overflow
reti
.org	OVF0addr;	= 0x0006	; Timer/Counter0 Overflow
reti
.org	URXCaddr;	= 0x0007	; USART, Rx Complete
reti
.org	UDREaddr;	= 0x0008	; USART Data Register Empty
reti
.org	UTXCaddr;	= 0x0009	; USART, Tx Complete
reti
.org	ACIaddr;	= 0x000a	; Analog Comparator
reti
.org	PCIBaddr;	= 0x000b	; Pin Change Interrupt Request B
reti
.org	OC1Baddr;	= 0x000c	;
reti
.org	OC0Aaddr;	= 0x000d	;
reti
.org	OC0Baddr;	= 0x000e	; 
reti
.org	USI_STARTaddr;	= 0x000f	; USI Start Condition
reti
.org	USI_OVFaddr;	= 0x0010	; USI Overflow
reti
.org	ERDYaddr;	= 0x0011	; 
reti
.org	WDTaddr;	= 0x0012	; Watchdog Timer Overflow
reti
.org	PCIAaddr;	= 0x0013	; Pin Change Interrupt Request A
reti
.org	PCIDaddr;	= 0x0014	; Pin Change Interrupt Request D
reti


;******************************************************************************
;старт
;******************************************************************************

reset:					; включение микроконтроллера

cli					; глобальный запрет на прерывания


ldi Temp,low(RamEnd)			; инициализации стека	
out SPL,Temp				;



ldi Temp,0b00001001			;
out DDRB,Temp				; настроили порт "В" (0-ввод, 1-вывод)
					; 0000х000 - "вывод" на передатчик (PB3- 15 ножка)
					; хххх0000 - "ввод" для чтения строк клавиатуры
					; 0000000х - "вывод" для индикации того что была нажата какая то кнлпка  ++++++++++++++++


ldi Temp,0b00001111			;
out DDRD,Temp 				; настраиваем порт "D" (0-ввод, 1-вывод)
					; 0000хххх - на вывод столбцов клавы



ldi Temp,0b00000000			; выключено
out TCCR1A,Temp				;



ldi Temp,0b00000000			;
out TCCR1B,Temp				; установили тактовый сигнал = CK 0  +++++++++++++++++++++++++++++++++++++++
					; таймер выключен!!!


					; инициализация компаратора
ldi Temp,0xFF				; как и просил -побольше ( 0xFFFF )
out OCR1AH,Temp				; 
ldi Temp,0xFF				; 
out OCR1AL,Temp				; 


ldi Temp,(1<<OCIE1A)			; разрешить прерывание компаратора
out TIMSK,Temp


ldi Temp,0				; обнуление таймера при включении
out TCNT1H,Temp
out TCNT1L,Temp


sei					; глобальное разрешение прерываний
        


ldi Temp,0b00001000			; выводим в порт "Б" на "OC1A" импульс 
out PortB,Temp




;*******************************************************************************
; главный цикл
;*******************************************************************************


Main_cicle:



	rcall keyboardread		; вызов подпрограммы чтения клавиатуры

	rcall certain_buttons_keyboard	; вызов подпрограммы проверки нажатия

	
rjmp Main_cicle				; циклимся




;*******************************************************************************
;обработка прерывания
;*******************************************************************************

TIM1_COMPA:				; включен режим CTC 
					; обнуление таймера  происходит автоматически
					; "OC1A" меняет свое логическое состояние автоматически




	ldi Temp4,0b00000000		; ВЫВОДИМ "0b00000000" В ПОРТ "Б" (12 ножка) //или выключам светодиод//
	out PortB,Temp4


	
	ldi Temp4,0b00000000		; выключаем таймер
	out TCCR1A,Temp4		;


	ldi Temp4,0b00000000		;
	out TCCR1B,Temp4		; установили тактовый сигнал = CK 0  +++++++++++++++++++++++++++++++++++++++
					; таймер выключен!!!


reti





;*******************************************************************************
; Чтение клавы и запись данных в ОЗУ
;*******************************************************************************

keyboardread:				;метка - опрос клавиатуры

          
	ldi Temp,5			; количество столбцов клавы = пять
         
	ldi Temp1,0b00000001		; первый столбец

          				; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару X
	ldi XL,low(key_buff)		; младший байт адреса
	ldi XH,high(key_buff)		; старший байт адреса

keyboardread_loop:			; цикл опроса

	out PortD,Temp1			; выводим в порт "Д" значение "Temp1" для выбора столбца клавиатуры
	in Temp2,PinB			; прочитали состояние столбца
         
	st X+,Temp2			; сохраним в ОЗУ состояние столбца клавы, 
 					; адрес в регстровой паре "X" автоматом увеличится на 1

	lsl Temp1			; сдвинули единичку выбора столбца клавиатуры на 1
 					; позицию влево

	dec temp			; уменьшим счетчик
	brne keyboardread_loop		; если не все просканировали, то циклимся

ret




       
;******************************************************************************************
;проверка нажатия клавиатуры
;******************************************************************************************



certain_buttons_keyboard:
		

	ldi temp1,5			; УСТАНОВИМ СЧЕТЧИК столбцов клавы	

	
                  			; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару "Z"
	ldi ZL,low (key_buff)		; младший байт адреса
	ldi ZH,high(key_buff)		; старший байт адреса 


Certain_button:


	ld Temp,Z+			; загрузим данные в регистр из ОЗУ по адресу из регистровой пары "Z", 
					; и после этого адресс в регистровой паре автоматически увеличится на еденицу


	cpi Temp,0b00000000		; проверяем, нажата ли какая ни будь кнопка?
	brne inform			; если нажата то переходим на метку "inform"


	dec temp1			; уменьшим счетчик
	brne Certain_button		; если не все столбцы, то циклимся

metka:


ret

;***********************************************************************************************
;вывод единицы в порт "Б" 
;***********************************************************************************************

inform:


							; включаем таймер
	ldi Temp,(1<<COM1A0)				; переключать ножку "OC1A" по совпадению (PB3- 15 ножка)
	out TCCR1A,Temp					;*1


	ldi Temp,(1<<wgm12)|(1<<CS12)|(1<<cs10)		; подключили режим "CTC" (вместе с *1) 
	out TCCR1B,Temp					; и установили тактовый сигнал = CK 1024  +++++++++++++++++++++++++++++++++++++++
							; таймер начал считать!!!


	ldi Temp,0b00000001				; ВЫВОДИМ "0b00000001" В ПОРТ "Б" (12 ножка) //или включам светодиод//
	out PortB,Temp

	rjmp metka

;***********************************************************************************************
вот проект студии
urok5.rar
(18.31 КБ) 174 скачивания
немного слов об этом
в основном цикле программы находится опрос клавиатуры и идентификация любой нажатой кнопки.
если оказалось, что кнопка была нажата, то выполняется подпрограмма, которая включает таймер и зажигает светодиод.
после этого основной цикл выполняется дальше, пока его не прервет обработчик прерываний.
в обработчике прерываний программа потушит светодиод и отключит таймер.
----------------------------------
это оно?

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 06, 2012 13:59:35
ВитГо
clawham писал(а):если на выходе приёмника у вас нормальный PPM сигнал то декодер - это одна микруха и пара резюков-кондюков
неее, у нас пока свой формат.. нам 20 команд передавать нужно...

до ppm позже дейдем