ldi Temp,low(RamEnd) ; инициализации стека out SPL,Temp ;
ldi Temp,0b00001111 ; настроили порт "В" (0-ввод, 1-вывод) out DDRB,Temp ; 0000х000 - "вывод" на передатчик (PB3- 15 ножка) ; хххх0000 - "ввод" для чтения строк клавиатуры ; 00000ххх - "вывод" для того что бы при чтении клавиатуры получить "0" ??????????????????
ldi Temp,0b00001111 ; настраиваем порт "D" (0-ввод, 1-вывод) out DDRD,Temp ; 0000хххх - на вывод столбцов клавы
ldi Temp,0b00000000 ; выводим на передатчик лог_0 ???????????????????????????????????????????????? out portB,Temp
ldi Temp,0b00000000 ; установили тактовый сигнал = CK 0 out TCCR1B,Temp ; таймер выключен!!!
sei ; глобальное разрешение прерываний
;******************************************************************************* ; главный цикл ;*******************************************************************************
;******************************************************************************* ; цикл Чтения клавы и запись данных в ОЗУ ;*******************************************************************************
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 R19, 2 ; зададим фиксированную длительность импульса ( 0x200 видимо ) OUT OCR1AH, R19 ; и выведем ее в порт сравнения LDI R19, 0 OUT OCR1AL ,R19
ldi Temp,0 ; обнуление таймера out TCNT1H,Temp out TCNT1L,Temp
ldi Temp,(1<<wgm12)|(1<<cs10) ; подключили режим "CTC" (вместе с *1) out TCCR1B,Temp ; и установили тактовый сигнал = CK 1:1 ; таймер начал считать!!!
ldi Temp,(1<<OCIE1A) ; разрешить прерывание компаратора out TIMSK,Temp
ldi R22, 0 ; фаза передачи
loop_wait_transmitt: ; цикл ожидания завершения передачи
cpi R22 , 7 brne loop_wait_transmitt
ldi temp1,0 ; обнулим "temp1", что бы точно выйти из цикла проверки нажатия клавиатуры ???????????????????
ldi R21,0 ; это будет счетчик единичек в передаче (четность)
ldi yl,low(key_buff) ; зададим адрес начала массива прочитанных кнопок в ргистровую пару "Y" ldi yh,high(key_buff)
ldi R17,5 ; количество байт для передачи
transmitt_byte: ; фаза начала передачи - передача байта
ld temp,y+ ; прочитаем байт для передачи, увеличим на единицу адрес в "Y"
ldi r18,8 ; количество бит в байте для передачи
pop temp ; извлекаем "SREG" ??????????????????????????????????????????????????????????? out SREG, temp
transmitt_bite_imp: ; фаза передачи импульса в передаваемом бите
in temp,SREG ; сохраняем "SREG" ??????????????????????????????????????????????????????????? push temp
LDI R19 ,high(ImpLen) ; зададим фиксированную длительность импульса OUT OCR1AH, R19 ; и выведем ее в порт сравнения LDI R19,low(ImpLen) OUT OCR1AL ,R19
LDI R22, 3 ; в следующий раз передаем паузу
int_reti:
pop temp ; извлекаем "SREG" //////////////////////////////////////////////////////////// out SREG, temp
теперь при нажатии одной из кнопок, появляются импульсы длительностью примерно 13 мили секунд и паузы длительностью 5 мили секунд shock все исправления отмечены знаками вопроса
Quote
так, не хватает принудительной установки состояния вывода OC1A вот так устанавливается в "1" этот код нужно будет выполнять перед прерыванием (перед передачей первого импульса) ldi R16 , (1<<COM1A1)|(1<<COM1A0) ; установка вывода OC1A=1 out TCCR1A , R16 ldi R16 , (1<<COM1A1)|(1<<COM1A0)|(1<<FOC1A) out TCCR1A , R16
ldi R16 , (0<<COM1A1)|(1<<COM1A0) ; режим top=OCR1A, OC1A toggle out TCCR1A , R16
...............ни чего не понял
1) ни как не могу понять зачем это нужно ??? (главный вопрос)
1.1) для чего это ? ldi R16 , (1<<COM1A1)|(1<<COM1A0) ; установка вывода OC1A=1 out TCCR1A , R16
1.2) для чего это ? ldi R16 , (1<<COM1A1)|(1<<COM1A0)|(1<<FOC1A) out TCCR1A , R16
дело в том, что режим toggle OC1A не имеет начального состояния вывода, а просто меняет его состояние на противоположное...
то есть мы не можем заранее сказать перешли мы с лог."0" на лог."1" или наоборот..
для этого мы и установим сначала OC1A=1 (кодом который я дал выше) и потом сделаем запуск нашего прерывания это у нас все в блоке начинающемся с метки inform:
Code
;*********************************************************************************************** ; вывод информации о состоянии клавиатуры в порт "Б" ;***********************************************************************************************
inform: ; здесь мы включаем таймер
; начало добавленного блока ldi R16 , (1<<COM1A1)|(1<<COM1A0) ; установка вывода OC1A=1 out TCCR1A , R16 ldi R16 , (1<<COM1A1)|(1<<COM1A0)|(1<<FOC1A) out TCCR1A , R16 ; конец добавленного блока
ldi Temp,(1<<COM1A0) ; переключать ножку "OC1A" по совпадению (PB3- 15 ножка) out TCCR1A,Temp ; *1
после этого мы должны с каждым нажатием на кнопки получать импульсы одинаковой длинны (до этого они по длительности могли меняться с паузами)
в коде по метке transmit_complete не нужно сохранять SREG !! (это я что ли написал ?!! гм.. глючил наверное... на метку transmit_complete мы попадаем из процедуры старта прерывания и там мы уже SREG сохранили
Code
transmitt_complete: ; КОД ДЛЯ ОТКЛЮЧЕНИЯ ПРЕРЫВАНИЙ
; ниже код не нужен !!! ; in temp,SREG ; сохраняем "SREG" ??????????????????????????????????????????????????????????? ; push temp ; вот до сюда не нужен !
если указанный выше код оставить то нормального возврата из прерываний нам не увидеть как своих ушей ! ТАК! это сохранение SREG точно не я делал !!! зачем ты его везде добавил ?!! мы сохранили его при входе в прерывание !!! больше нигде сохранять не нужно !!! иначе ты не выйдешь из прерывания в то место откуда ушел !!! Виталий (аka ВитГо)
и ни чего, что (1<<FOC1A) находится в регистре TCCR1C ???????
опс! конечно "чего"!!!! значит вторая запись в TCCR1C ! (в 32ой меге этот бит в TCCR1A :-( - хорошо что ты за мной проверяешь !
по коду
Code
; этот код определяет состояние в которое нужно установить O1A ldi R16,(1<<COM1A1)|(0<<COM1A0) ; Очистить OC1A/OC1B по совпадению (указан выход на низком уровне). out TCCR1A,R16 ; а этот код устанавливает ldi R16,(1<<FOC1A) ; этот участок кода за что отвечает ???? out TCCR1С,R16
; а этот код служит для принудительного изменения состояния выходов OC1A и OC1B. ldi R16,(1<<FOC1A) out TCCR1С,R16
ну тогда совсем не понятно..............
( смотрим страницу 108 датащита) вот гугл перевод
Quote
FOC1A/FOC1B биты активны только при WGM13: 0 бит определяет не-PWM режиме. Тем не менее, для обеспечения совместимости с будущими устройствами, эти биты должны быть установлены в нуль, когда TCCR1A написана при работе в режиме ШИМ. При написании логических один FOC1A/FOC1B немного, немедленно матч сравнения вынужден на осциллограмме Поколение устройства.Выход OC1A/OC1B изменяется в соответствии с ее COM1x1: 0 биты установки. Обратите внимание, что FOC1A/FOC1B бит реализованы в виде вспышек. Поэтому Значение присутствует в COM1x1: 0 биты, которые определяют влияние вынуждены сравнивать. стробоскоп FOC1A/FOC1B не будет генерировать любое прерывание не будет очищено, таймер в Чистом Таймера по совпадению (CTC) режиме с использованием OCR1A как TOP. FOC1A/FOC1B биты всегда читаются как ноль.
интересует эта строка FOC1A/FOC1B биты активны только при WGM13
теперь идем смотреть таблицу на страннице 106 из датащита в нашем режиме CTC (4 строка) WGM13 очищен в нуль но есть еще один режим CTC (12 строка) но у него в TOP ICR1, а не OCR1A не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Четверг, 04.10.2012, 12:50
смысл такой: в TCCR1A мы задаем нужное нам состояние выхода, потом в TCCR1C говорим установить вывод в нужное состояние, и потом уже работаем с таймером.. и WGM13 у тебя и будет равен нулю (для CTC top=OCR1A)
сделай новый маленький проект с изменением состояния выхода OC1A и проверь! (я часто проверяю даташит на простых примерах, где только инициализация и потом rjmp указывающий сам на себя) - запускаю и проверяю состояние выводов.. Виталий (аka ВитГо)
Добавлено (04.10.2012, 21:04) --------------------------------------------- может я сам попробую сигнал записать с помощью осциллографа из звуковой карты ? там предел 22 килогерца, а у нас максимум 3 кГц....
не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Четверг, 04.10.2012, 20:58
попробовал программой для записи звука Sony Sound Forge Audio Studio 10.0, но ни фига не ясно ( та же картинка что и на простом осциллографе) ЗЫ вход у звуковухи закрытый.. не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Четверг, 04.10.2012, 23:14