Re: Пропорциональное управление на МК (Знание=Сила)
Добавлено: Вт сен 04, 2012 16:25:39
то-есть, если я правильно понял, основная задача - проверить читается ли клавиатура?
Здесь можно немножко помяукать :)
https://radiokot.ru/forum/
Код: Выделить всё
.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
;***********************************************************************************************
что за "оправка"?в прерывании будет только оправка !
это я "т" пропустил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
;***********************************************************************************************
Нет, даже не начинал. Нужно до конца с передатчиком разобраться...ВитГо писал(а):Кстати, а ты уже схему приемника придумал ?
а все остальное оставить в основном цикле .... (чЁ тут я торможу - пытаюсь додуматься....)в нашем варианте если зарегистрировано нажатие любой кнопки нужно будет просто вывести "1" на какой нить порт микроконтроллера - так мы проконтролируем что программа считывает значения с клавиатуры
нам таймер нужен для того что бы:ВитГо писал(а):нам важно выдерживать временные интервалы именно при отправке, поэтому отправку бум делать через таймер
по идее подпрограмма проверки кнопок просто должна сравнивать 5 байт считанных линий клавиатуры с 0x00
если значение не равно 0х00 - значит какая то кнопка была нажата и нужно начать передачу
в нашем варианте если зарегистрировано нажатие любой кнопки нужно будет просто вывести "1" на какой нить порт микроконтроллера - так мы проконтролируем что программа считывает значения с клавиатуры
Код: Выделить всё
.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
;***********************************************************************************************
неее, у нас пока свой формат.. нам 20 команд передавать нужно...clawham писал(а):если на выходе приёмника у вас нормальный PPM сигнал то декодер - это одна микруха и пара резюков-кондюков