пока пойдет...uwrtey писал(а):сейчас еще попробую один вариант............![]()
.....
и вот что получилось...
теперь нужно написать процедуру отправки..
сейчас подумаю как проще это сделать...
пока пойдет...uwrtey писал(а):сейчас еще попробую один вариант............![]()
.....
и вот что получилось...
ВитГо писал(а):до ppm позже дейдем
Код: Выделить всё
push R16
push R17
; здесь можем использовать R16 и R17 в своей подпрограмме обработчике прерывания
pop R17
pop R16
reti
Код: Выделить всё
push R16
push R17
push R18
push R19
pop R19
pop R18
pop R17
pop R16
Код: Выделить всё
push R16
push R17
push R18
push R19
pop R16
pop R17
pop R18
pop R19
Код: Выделить всё
push R16 ; сохраним значение регистра R16 на стеке
in R16 , SREG ; прочитаем значение регистра SREG
push R16 ; сохранили значение SREG
Код: Выделить всё
pop R16 ; прочитаем значение SREG
out SREG , R16 ; запишем значение регистра SREG
pop R16 ; прочитаем значение SREG
вектор прерывания задан правильно ? укажите лучше константу из файла .include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m48def.inc"спящий писал(а):Подскажите какого художника у меня на одно нажатие кнопки пуьта происходит 6 прерываний?и всегда разные значения?
.org 0x000
rjmp init;
.org 0x0001
rjmp preriv; настраиваем прерывание PCINTo
код инициализирующий стек обычно выполняют в самом начале.. и поверьте не зря..спящий писал(а):
ldi r16,high(RAMEND) ;
out SPH,r16 ;
ldi r16,low(RAMEND) ;
out SPL,r16 ;
я не телепатспящий писал(а):
;прерывание по INTO
ldi temp,0b00000001 ;устанавливаем контроль
out EIMSK,temp; ; прирывания на PCINT0-7
ldi temp,0b00000000;
sts EICRA,temp;
ldi temp,0b00000001 ;
sts EIfr,temp;
прикольная конструкция, но лучше так написатьспящий писал(а): start:
sei;
nop;
nop;
rjmp start;
Код: Выделить всё
sei;
start:
rjmp start;
это лишнее, при входе в прерывание процессор сам запрещает все прерыванияспящий писал(а): preriv:
cli;
Код: Выделить всё
ldi R16, 0x00000100
out PortD, R16
Код: Выделить всё
ldi temp,0b00000001 ;
sts EIfr,temp;
Код: Выделить всё
sei
start:
sts UDR0,r19 ; этот код мы будим пересылать в ПК
rcall USART_Transmit;
sts UDR0,r20
rcall USART_Transmit;
rjmp start;
об этом я уже говорилВитГо писал(а):когда процессор переходит в прерывание мы за редким случаем не знаем какую часть программы мы прервали и что находится в рабочих регистрах, вполне возможно что там важная информация - и мы работая в прерывании ее просто потеряем.
и по этому я решил в прерывании использовать регистр (Temp4) который не используется в основном циклеuwrtey писал(а):Прерывание может произойти в любой момент - когда опрашивается клавиатура или когда происходит проверка нажатой кнопки.
После того, как обработчик прерываний закончит свою работу - то программа вернется в главный цикл и в это время значения некоторых регистров будут заполнены "левыми" данными (с которыми работал обработчик прерываний)
ну раз надо - значит надо - сейчас модифицирую кодНаконец, нужно учитывать, что регистр SREG не сохраняется при переходе к обработке прерывания, и если в прерывании встречаются команды, его модифицирующие, то его содержимое может быть испорчено. Поэтому если есть теоретическая возможность того, что прерывание "вклинится" между командой сравнения (или другой, устанавливающей биты SREG) и командой условного перехода, то SREG нужно сохранять и восстанавливать принудительно
Код: Выделить всё
.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 ; циклимся
;*******************************************************************************
;обработка прерывания
;*******************************************************************************
push temp2 ;сохраняем в стеке рабочую переменную
push temp1 ;сохраняем в стеке рабочую переменную
push temp ;сохраняем в стеке рабочую переменную
in temp,SREG
push temp ;сохраняем в стеке SREG
;*****************
TIM1_COMPA: ; включен режим CTC
; обнуление таймера происходит автоматически
; "OC1A" меняет свое логическое состояние автоматически
ldi Temp4,0b00000000 ; ВЫВОДИМ "0b00000000" В ПОРТ "Б" (12 ножка) //или выключам светодиод//
out PortB,Temp3
ldi Temp4,0b00000000 ; выключаем таймер
out TCCR1A,Temp4 ;
ldi Temp4,0b00000000 ;
out TCCR1B,Temp3 ; установили тактовый сигнал = CK 0 +++++++++++++++++++++++++++++++++++++++
; таймер выключен!!!
;******************
pop temp
out SREG,temp ;извлекаем SREG
pop temp ;извлекаем рабочую переменную
pop temp1 ;извлекаем рабочую переменную
pop temp2 ;извлекаем рабочую переменную
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
;***********************************************************************************************
Код: Выделить всё
.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: ; включение микроконтроллера
Код: Выделить всё
.cseg
.org 0
; СТАРТ
rjmp RESET ; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset
.org OC1Aaddr; = 0x0004 ; Timer/Counter1 Compare Match A
rjmp TIM1_COMPA
.org INT_VECTORS_SIZE
;----------------------------------------------------------------------
TIM1_COMPA:
;Код обработчика прерывания
reti
;******************************************************************************
;старт
;******************************************************************************
RESET: ; включение микроконтроллера
;Ну и далее
извини, чуток занят пока, постараюсь завтра появитьсяuwrtey писал(а):попробую залить эту прошивку в мк и проверить....
ан нет, не получится прикошачить клавиатуру к моей панельке для прошивания! схема передатчика не поддерживает внутрисхемную прошивку!uwrtey писал(а):попробую залить эту прошивку в мк и проверить....
как это не подключено ??? - mosi подключено, а вот RESET забыл подключитьь...ВитГо писал(а):а почему mosi не подключено на схеме ?
возможность внутрисхемной прошивки необязательна - у меня панелька как-раз для этих целей служит...ВитГо писал(а):в принципе можно еще раз подумать как переделать схему
ура!ВитГо писал(а):я придумал алгоритм передачи !!
ВитГо писал(а): теперь бы придумать как его тебе попроще объяснить