Ассемблер (ASM) для AVR в вопросах и ответах
- MTF
- Нашел транзистор. Понюхал.
- Сообщения: 179
- Зарегистрирован: Чт янв 07, 2010 11:25:12
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Всем привет :
Почти доделал индикацию по исходнику предоставленную GP1 (все таки решил сделать 4 разряда)
вопрос: поскольку теперь 4 индикатора и у меня четыре кнопки , могу ли я подключится к 4
выводам для включения разрядов , через кнопки например на вывод portd4 ????
Загвозка теперь в том как отлавливать через pd4 какая кнопка нажата , схемы с таким подключением видел , а вот как они определяют не пойму , если не сложно обьясните как это делается ???
Почти доделал индикацию по исходнику предоставленную GP1 (все таки решил сделать 4 разряда)
вопрос: поскольку теперь 4 индикатора и у меня четыре кнопки , могу ли я подключится к 4
выводам для включения разрядов , через кнопки например на вывод portd4 ????
Загвозка теперь в том как отлавливать через pd4 какая кнопка нажата , схемы с таким подключением видел , а вот как они определяют не пойму , если не сложно обьясните как это делается ???
- Вложения
-
- knopki.JPG
- (55.54 КБ) 502 скачивания
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
вполне.
алгоритм примерно такой:
1. выводишь цифры на индикатор
2. переводишь портВ на вход
3. на PD4 выдаешь 0/1 (если 0 то PORTB должен быть с "подтяжкой", для 1 не обязательно)
4. читаешь PINB, маскируешь лишние разряды и анализируешь.
зы: не забывай про дребезг контактов.
и я бы еще на PD4 резуюк ом так на 470 поставил, так на всякий случай.
алгоритм примерно такой:
1. выводишь цифры на индикатор
2. переводишь портВ на вход
3. на PD4 выдаешь 0/1 (если 0 то PORTB должен быть с "подтяжкой", для 1 не обязательно)
4. читаешь PINB, маскируешь лишние разряды и анализируешь.
зы: не забывай про дребезг контактов.
и я бы еще на PD4 резуюк ом так на 470 поставил, так на всякий случай.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Помогите разобраться с обучалкой....
.cseg
.org 0
rjmp RESET
rjmp EXT_INT0
rjmp EXT_INT1
rjmp TIM2_COMP
rjmp TIM2_OVF
rjmp TIM1_CAPT
rjmp TIM1_COMPA
rjmp TIM1_COMPB
rjmp TIM1_OVF
rjmp TIM0_OVF
rjmp SPI_STC
rjmp USART_RXC
rjmp USART_UDRE
rjmp USART_TXC
rjmp ADCC
rjmp EE_RDY
rjmp ANA_COMP
rjmp TWSI
rjmp SPM_RDY
;RESET:
EXT_INT0:
EXT_INT1:
TIM2_COMP:
TIM2_OVF:
TIM1_CAPT:
;TIM1_COMPA:
TIM1_COMPB:
TIM1_OVF:
TIM0_OVF:
SPI_STC:
USART_RXC:
USART_UDRE:
USART_TXC:
ADCC:
EE_RDY:
ANA_COMP:
TWSI:
SPM_RDY:
reti
;****************************************************
; ИНИЦИАЛИЗАЦИЯ
;****************************************************
Reset: ldi Temp,0b11111111 ;настройка портов
out DDRD,Temp
ldi Temp,0b00010000 ;разрешить прерывание компаратора
out TIMSK,Temp
ldi Temp,0b00000011 ;тактовый сигнал = CK/64, увилечение деление замедляет ход
out TCCR1B,Temp
ldi Temp,0x75 ;инициализация компаратора
out OCR1AH,Temp ;уменьшение имп. повышает скорость
ldi Temp,0x10
out OCR1AL,Temp
ldi Temp,high(RamEnd)
out SPH,Temp
ldi Temp,low(RamEnd)
out SPL,Temp
ldi Temp1,0b00000001 ;инициализация индикатора
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
sei ;разрешить прерывания
;****************************************************
; ОСНОВНОЙ ЦИКЛ
;****************************************************
Inf: rjmp Inf ;бесконечный цикл
;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************
TIM1_COMPA:
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
Shift: сpi Temp1,0b10000000 ;сравнить с крайним знач.
breq Init ;если равно - загрузка нач. знач.
lsl Temp1 ;иначе - сдвиг влево
rjmp Output ;перейти на вывод в порт
Init: ldi Temp1,0b00000001 ;загрузить нач. значение
Output: out PortD,Temp1 ;вывод в порт
reti ;выход из обработчика
----------
Не пойму, как работает прога,
с чего начинается прога - с метки ресет?
т.к. прерывание срабатывает по какому-то внешнему воздействию - где оно "воздействие"?
reti в метке TIM1_COMPA: возвращает к др. меткам, а там тоже reti идет, куда оно то возвращает?
ИНИЦИАЛИЗАЦИЯ загружается раз в память, так как ее прога в цикле не повторяет из-за sei?
бесконечный цикл работает, как +1 и как он циклит прогу?
Почему при перестановке строк:
Init: ldi Temp1,0b00000001
Shift: cpi Temp1,0b10000000
breq Init
lsl Temp1
out PortD,Temp1
цикл запирается?
Спасибо за ответы, хоть при таком кол-ве вопросов наверно сообщение останется без ответа
.cseg
.org 0
rjmp RESET
rjmp EXT_INT0
rjmp EXT_INT1
rjmp TIM2_COMP
rjmp TIM2_OVF
rjmp TIM1_CAPT
rjmp TIM1_COMPA
rjmp TIM1_COMPB
rjmp TIM1_OVF
rjmp TIM0_OVF
rjmp SPI_STC
rjmp USART_RXC
rjmp USART_UDRE
rjmp USART_TXC
rjmp ADCC
rjmp EE_RDY
rjmp ANA_COMP
rjmp TWSI
rjmp SPM_RDY
;RESET:
EXT_INT0:
EXT_INT1:
TIM2_COMP:
TIM2_OVF:
TIM1_CAPT:
;TIM1_COMPA:
TIM1_COMPB:
TIM1_OVF:
TIM0_OVF:
SPI_STC:
USART_RXC:
USART_UDRE:
USART_TXC:
ADCC:
EE_RDY:
ANA_COMP:
TWSI:
SPM_RDY:
reti
;****************************************************
; ИНИЦИАЛИЗАЦИЯ
;****************************************************
Reset: ldi Temp,0b11111111 ;настройка портов
out DDRD,Temp
ldi Temp,0b00010000 ;разрешить прерывание компаратора
out TIMSK,Temp
ldi Temp,0b00000011 ;тактовый сигнал = CK/64, увилечение деление замедляет ход
out TCCR1B,Temp
ldi Temp,0x75 ;инициализация компаратора
out OCR1AH,Temp ;уменьшение имп. повышает скорость
ldi Temp,0x10
out OCR1AL,Temp
ldi Temp,high(RamEnd)
out SPH,Temp
ldi Temp,low(RamEnd)
out SPL,Temp
ldi Temp1,0b00000001 ;инициализация индикатора
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
sei ;разрешить прерывания
;****************************************************
; ОСНОВНОЙ ЦИКЛ
;****************************************************
Inf: rjmp Inf ;бесконечный цикл
;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************
TIM1_COMPA:
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
Shift: сpi Temp1,0b10000000 ;сравнить с крайним знач.
breq Init ;если равно - загрузка нач. знач.
lsl Temp1 ;иначе - сдвиг влево
rjmp Output ;перейти на вывод в порт
Init: ldi Temp1,0b00000001 ;загрузить нач. значение
Output: out PortD,Temp1 ;вывод в порт
reti ;выход из обработчика
----------
Не пойму, как работает прога,
с чего начинается прога - с метки ресет?
т.к. прерывание срабатывает по какому-то внешнему воздействию - где оно "воздействие"?
reti в метке TIM1_COMPA: возвращает к др. меткам, а там тоже reti идет, куда оно то возвращает?
ИНИЦИАЛИЗАЦИЯ загружается раз в память, так как ее прога в цикле не повторяет из-за sei?
бесконечный цикл работает, как +1 и как он циклит прогу?
Почему при перестановке строк:
Init: ldi Temp1,0b00000001
Shift: cpi Temp1,0b10000000
breq Init
lsl Temp1
out PortD,Temp1
цикл запирается?
Спасибо за ответы, хоть при таком кол-ве вопросов наверно сообщение останется без ответа
- Pooher
- Мучитель микросхем
- Сообщения: 491
- Зарегистрирован: Вс янв 07, 2007 01:45:48
- Откуда: Российская Федерация, будь она неладна...
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Программа выполняется с RESET.
"воздействие" - в данном случае, это момент, когда таймер досчитает до определённого значения.
reti - возвращает программу в то место, где произошло прерывание.
ИНИЦИАЛИЗАЦИЯ происходит только по внешнему сигналу RESET и при включении питания.
Вопроса не понял.
Вопроса не понял.
"воздействие" - в данном случае, это момент, когда таймер досчитает до определённого значения.
reti - возвращает программу в то место, где произошло прерывание.
ИНИЦИАЛИЗАЦИЯ происходит только по внешнему сигналу RESET и при включении питания.
бесконечный цикл работает, как +1 и как он циклит прогу?
Вопроса не понял.
Код: Выделить всё
Inf:
rjmp Inf ;безусловный переход по метке InfПочему при перестановке строк:
Init: ldi Temp1,0b00000001
Shift: cpi Temp1,0b10000000
breq Init
lsl Temp1
out PortD,Temp1
цикл запирается?
Вопроса не понял.
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Pooher писал(а):бесконечный цикл работает, как +1 и как он циклит прогу?
Вопроса не понял.Код: Выделить всё
Inf:
rjmp Inf ;безусловный переход по метке Inf
Все сводилось, а как образуется цикл программы....
Pooher писал(а):Почему при перестановке строк:
Init: ldi Temp1,0b00000001
Shift: cpi Temp1,0b10000000
breq Init
lsl Temp1
out PortD,Temp1
цикл запирается?
Вопроса не понял.
В проге код обработчика такой:
Shift: cpi Temp1,0b10000000
breq Init
lsl Temp1
rjmp Output
Init: ldi Temp1,0b00000001
Output: out PortD,Temp1
----------
Я решил переставить строки, как это показано выше и прога перестала выполнятся циклически, т.е. повисла на элементе инициализыциии и не туда не сюда...
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
vit007 писал(а):Все сводилось, а как образуется цикл программы....
......
......
......
В проге код обработчика такой:
Shift: cpi Temp1,0b10000000
breq Init
lsl Temp1
rjmp Output
Init: ldi Temp1,0b00000001
Output: out PortD,Temp1
----------
Я решил переставить строки, как это показано выше и прога перестала выполнятся циклически, т.е. повисла на элементе инициализыциии и не туда не сюда...
1. Цикл образуется из безконечного повторения инструкции rjmp на саму себя, а в определенные моменты выполняются прерывания.
2. потому что при каждом вхождении в прерывание идет присваивание temp=0b00000001, поэтому после выполнения всего прерывания в порт будет постоянно выводиться значение temp=0b00000010, а так все работает, а в исходном коде присвоение temp=0b00000001 идет только после того как 1 "пройдет" по всем разрядам temp
Re: Ассемблер (ASM) для AVR в вопросах и ответах
GP1 писал(а):2. потому что при каждом вхождении в прерывание идет присваивание temp=0b00000001, поэтому после выполнения всего прерывания в порт будет постоянно выводиться значение temp=0b00000010, а так все работает, а в исходном коде присвоение temp=0b00000001 идет только после того как 1 "пройдет" по всем разрядам temp
Не понял, пока еще сложно написано....
Хотелось обобщить, что понял...
Прога начинается с метки ресет, где происходит инициализация, раз или после кнопки сброса.
Также там ограничивается кол-во имп. для таймера, кот., в последствие, станет "воздействием" для прерывания.
После глоб. разрешения запускается таймер и считаются бесконечные циклы.
При достижении огр. таймера происходит прерывание и переходим в обработчик прерывания.
Скорее всего, я так думаю там допускается линейный алгоритм, а не ветвящийся...
происходит сброс таймера в "0" и возвращение в бесконечный цикл и по новой.
Поправьте если че не так...
- Pooher
- Мучитель микросхем
- Сообщения: 491
- Зарегистрирован: Вс янв 07, 2007 01:45:48
- Откуда: Российская Федерация, будь она неладна...
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вроде того...
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
таймер запускается послеvit007 писал(а):После глоб. разрешения запускается таймер и считаются бесконечные циклы.
Код: Выделить всё
ldi Temp,0b00000011 ;тактовый сигнал = CK/64
out TCCR1B,Tempперед разрешением прерываний просто обнуляют таймер:
Код: Выделить всё
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
Ставим плюсы: )
Re: Ассемблер (ASM) для AVR в вопросах и ответах
vit007 писал(а):Прога начинается с метки ресет
Не совсем. Исполнение программы начинается с вектора сброса (в этом МК он равен нулю), т.е. первой выполняется команда записанная после директивы
Код: Выделить всё
.org 0В данном случае там находится команда безусловного перехода на метку RESET:
Код: Выделить всё
.org 0
rjmp RESETvit007 писал(а):и считаются бесконечные циклы.
В бесконечном цикле вида
Код: Выделить всё
loop:
rjmp loopничего не считается, и если предварительно не разрешить прерывания от периферии, он будет выполняться бесконечно, для чего он собственно и предназначен. Точнее, он предназначен для того, чтобы чем-нибудь занять контроллер, пока нам от него ничего не нужно.
vit007 писал(а):При достижении огр. таймера происходит прерывание и переходим в обработчик прерывания.
Верно, только с учетом вышесказанного: таймер является периферийным устройством, работает независимо от ядра, он считает импульсы тактового генератора, а не количество выполненных инструкций.
vit007 писал(а):Скорее всего, я так думаю там допускается линейный алгоритм, а не ветвящийся...
Ветвление в обработчике есть, посмотри внимательно, там же все закомментировано. Инструкция BREQ - BRanch if EQual - "ветвление, если равно", иначе (если не равно), ветвления не происходит, а выполняется следующая инструкция.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Подскажите пожалуйста, как можно решить такую задачу:
С помощью АЦП получаю номер нажатой кнопки и кладу его в переменную буфер. (Key_buf равен от 1 до 6)
в зависимости от того, номер какой кнопки содержит буфер, нужно подставить данные соответствующих массивов в один и тот же цикл.
значения массива берутся с помощью ZH/ZL и lpm...
button_1:
.db 1,2,3,4,5
button_2:
.db 6,7,8,9,10
... и т.д.
цикл от 1 до 5.
out portb,temp <- сюда (в темп) нужно подставлять по порядку 1,2,3,4,5 если буфер кнопки содержит номер 1 и 6,7,8,9,10 если содержит номер 2
к началу цикла.
как так сделать?
С помощью АЦП получаю номер нажатой кнопки и кладу его в переменную буфер. (Key_buf равен от 1 до 6)
в зависимости от того, номер какой кнопки содержит буфер, нужно подставить данные соответствующих массивов в один и тот же цикл.
значения массива берутся с помощью ZH/ZL и lpm...
button_1:
.db 1,2,3,4,5
button_2:
.db 6,7,8,9,10
... и т.д.
цикл от 1 до 5.
out portb,temp <- сюда (в темп) нужно подставлять по порядку 1,2,3,4,5 если буфер кнопки содержит номер 1 и 6,7,8,9,10 если содержит номер 2
к началу цикла.
как так сделать?
- Meteor
- Друг Кота
- Сообщения: 3961
- Зарегистрирован: Пн июл 13, 2009 14:37:39
- Откуда: Московская область, наукоград.....
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А почему именно АЦП за кнопками следит?
Ведь достаточно объявить входы с подтяжкой и замыкать кнопку на корпус/землю.
АЦП есть смысл применить только при плавающих потенциалах, да и то не всегда.
Код мог быть и таким:
Ведь достаточно объявить входы с подтяжкой и замыкать кнопку на корпус/землю.
АЦП есть смысл применить только при плавающих потенциалах, да и то не всегда.
Код мог быть и таким:
Код: Выделить всё
ldi temp, 0x00;Начальная инициализация
ldi tmp, 0xFF
out DDRC, temp;
out PORTC, tmp;
out DDRB, tmp;
out PORTB, temp;
main:
sbis pinc, 1; Если не нажали кнопку 1
rjmp button1;пропускаем переход
....
rjmp main;
button1:; Обработка кнопки
ldi temp, 1;Грузим число
out portb, temp;
nop
ldi temp, 2;Другое
out portb, temp;
nop
...
rjmp main;выходим в основной цикл
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Re: Ассемблер (ASM) для AVR в вопросах и ответах
вышеописанное понятно, но у меня другая цель. как я получаю номер нажатой кнопки- вообще не нужно, вопрос в подстановке массивов. Попробую еще объяснить (может и сам заодно пойму
)
вобщем тут жестко задан массив из которого по порядку нужно брать цифры. Хочется отвязаться от конкретного массива и поставить туда переменную типа Key_buf в которая будет содержать номер кнопки =1,2,3 ... 6 и в зависимости от номера кнопки брать значения из одного или другого массива- массив не будет жестко задан, а будет определяться переменной.
что то вроде того:
вобщем очень надеюсь что понятно, а то писал, писал... ) сам пока не понял.
Код: Выделить всё
короче есть массивы:
button1: .db 23,45,45,66,33,44,55,65,45,5,66,5,4,33,98
button2: .db 23,34,45,56,67,78,89,12,12,12,23,34,45,56
button3: .db 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,3,2,3,2,
button4... -//-
button5... -//- примерно то же самое, числа.
button6... -//-
вот так примерно обрабатывается:
temp=0
couter=0 и т.п.
start:
cpi counter,15 ;цикл выполняется 15 раз. за цикл все 15 цифр массива
breq exit
ldi ZH,high(button3*2) ;загружаем адрес первого числа массива button3
ldi ZL,low(button3*2) ;
ldi temp1,0
add ZL,temp ;загрузить адрес первого числа, второго, третьего... инкрименируем адрес в цикле
adc ZH,temp1 ;
lpm ;загрузить значение по данному адресу в регистр R0
inc temp ;инкриминировать адрес
mov R16,R0 ;переместить число из регистра памяти в регистр общего назначения
* тут обрабатываю регистр R16 ; в общей сумме 15 раз обрабатываю *
inc counter ;просто счетчик сколько циклов отработано
rjmp start
exit:вобщем тут жестко задан массив из которого по порядку нужно брать цифры. Хочется отвязаться от конкретного массива и поставить туда переменную типа Key_buf в которая будет содержать номер кнопки =1,2,3 ... 6 и в зависимости от номера кнопки брать значения из одного или другого массива- массив не будет жестко задан, а будет определяться переменной.
что то вроде того:
Код: Выделить всё
ldi ZH,high(Key_buf*2) ;загружаем адрес первого числа не массива button3, а смотря какое число в key_buf
ldi ZL,low(Key_buf*2) ; если число 3, то из массива button3, если там число 5, то из массива button5
......вобщем очень надеюсь что понятно, а то писал, писал... ) сам пока не понял.
- Meteor
- Друг Кота
- Сообщения: 3961
- Зарегистрирован: Пн июл 13, 2009 14:37:39
- Откуда: Московская область, наукоград.....
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А команда LPM Вас устраивает? Например так:
Или я опять не допонял? Вполне возможно что малость надо подправить...
Код: Выделить всё
ldi Zl, low(Key_buf*2);Загружаем адрес данных в памяти
ldi Zh, high(Key_buf*2); программ
ldi count, 0x05;Счетчик на некоторое число (тут 5)
cycle:
lpm tmp, Z+;считываем
out portx, tmp;отсылаем
dec count;
cpi count, 0;сравниваем с 0
brne cycle;Если не 0 - циклимся
....
Или я опять не допонял? Вполне возможно что малость надо подправить...
Последний раз редактировалось Meteor Пт апр 16, 2010 19:02:23, всего редактировалось 1 раз.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Alexeus писал(а):что то вроде того:
Код: Выделить всё
ldi ZH,high(Key_buf*2) ;загружаем адрес первого числа не массива button3, а смотря какое число в key_buf
ldi ZL,low(Key_buf*2) ; если число 3, то из массива button3, если там число 5, то из массива button5
......
1. при таком способе ты не получишь нужного значения.
2. я бы сделал так:
-организовал 6 массивов по 16 байт, потеря 6 байт думаю не смертельна
-затем вычисляем смещение (key-1)*16 (просто после вычитания 4 раза сдвигаем значение влево)
-загружаем в Z адрес начальной таблицы и прибавляем смещение (оно у нас кратно № кнопки)
-в цикле последовательно перебираем все значения.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Meteor писал(а):Например так:Код: Выделить всё
ldi Zl, low(Key_buf*2);Загружаем адрес данных в памяти
ldi Zh, high(Key_buf*2); программ
ldi count, 0x05;Счетчик на некоторое число (тут 5)
cycle:
lpm tmp, Z+;считываем
out portx, tmp;отсылаем
dec count;
cpi count, 0;сравниваем с 0
brne cycle;Если не 0 - циклимся
....
вы снова привязались к конкретному массиву -key_buf и из него тянете 5 чисел... а подразумевается, что Key_buf это переменная, а не массив, в которой находится число от 1 до 6, показывающее, какая кнопка нажата. Цикл с Zрегистром всегда считывает одно и то же количество цифр- пятнадцать штук, а вот ОТКУДА, из какого массива он их будет брать, должна определять переменная Key_buf. То есть если в переменной кейбуф будет число 4, то берем из массива button_4, если в кейбуф число 2, то берем все так же 15 цифр, но уже из массива button_2.
идея в том, что цикл один. в нем последовательно из массива считывается 15 цифр, а сами массивы, откуда считывать задаются значением переменной (1й массив, 2й массив... 6й массив).
вот это не корректно, это не работает с переменной:
Код: Выделить всё
ldi Zl, low(Key_buf*2);Загружаем адрес данных в памяти
ldi Zh, high(Key_buf*2); программпросто я не знаю как выразить такую операцию, вот хоть что то начеркал для примерного понятия.
GP1 по-моему ближе к тому что я хочу, я правда не совсем понял что он написал, могли бы вы, GP1 по-подробнее, может на примере показать...
массивы даны, вот они, их 6 штук:
Код: Выделить всё
button1: .db 23,45,45,66,33,44,55,65,45,5,66,5,4,33,98
button2: .db 23,34,45,56,67,78,89,12,12,12,23,34,45,56
button3: .db 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,3,2,3,2,
button4... -//-
button5... -//- примерно то же самое, числа.
button6... -//-вот как связать значения в переменной Key_buf (например там число 3) с тем, что нужно считать 15 цифр из массива button3, а если в переменной Key_buf было бы число 5, то нужно было бы считать все в том же цикле, все то же количество цифр -15 (это не минус пятнадцать, а дефис), НО из массива button5.
Последний раз редактировалось Alexeus Пт апр 16, 2010 21:02:12, всего редактировалось 1 раз.
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Alexeus писал(а):вот как связать значения в переменной Key_buf (например там число 3) с тем, что нужно считать 15 цифр из массива button3, а если в переменной Key_buf было бы число 5, то нужно было бы считать все в том же цикле, все то же количество цифр -15, НО из массива button5.
так как ты организовал цикл это не получится, а будет примерно так:
читаются данные из массива-3, предположим прочиталось 7 значений, и тут мы меняем массив-3 на массив-5, а до конца цикла осталось всего 8 повторов.
с примером конечно можно, но ....
может сам попробуешь?
для затравки:
Код: Выделить всё
dec key ;уменьшаем значение клавиши на 1, я так понимаю 0 - клавиша не нажата
;и умножаем на 16, как я говорил, иначе придется умножать на 15, а не все АВРки умеют это делать аппаратно
lsl key
lsl key
lsl key
lsl key
;и вуаля в key у нас смещение адреса для выбора массива
ldi ZL,low(button1*2) ;грузим в Z адрес первого массива
ldi ZH.high(button1*2)
;складываем адрес и смещение
add ZL,key
adc ZH,tmp ;tmp=0
;естественно при key=1 мы получим смещение 0, и получится адрес первого массива.
;дальше цикл
ну что-то типа такого.
Последний раз редактировалось GP1 Пт апр 16, 2010 21:09:43, всего редактировалось 1 раз.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
не, ничего менять не нужно, наверное (-15) вас смутило. это не минус, а дефис.
просто в переменной Key_buf всегда находиться значение кнопки. Если никакая кнопка не нажата, то там "0", а если нажимаются кнопки от 1 до 6, то там будет значение нажатой в данный момент кнопки. Mне нужно вызвать функцию в которой есть цикл обработки массива. А массив туда нужно будет подставить в зависимости от того, какая цифра в переменной Key_buf.
Можно наверное было бы сделать типа "если в кейбуф цифра "1", то идем на цикл, где жестко прописана обработка массива баттон1, в противном случае, если в кейбуф цифра два, то идем в другой цикл, где обрабатываем только массив баттон2..." все это будет работать, но хотелось бы оптимизировать до одного цикла, в который подставляется нужный массив в зависимости от числа в переменной keybuf.
просто в переменной Key_buf всегда находиться значение кнопки. Если никакая кнопка не нажата, то там "0", а если нажимаются кнопки от 1 до 6, то там будет значение нажатой в данный момент кнопки. Mне нужно вызвать функцию в которой есть цикл обработки массива. А массив туда нужно будет подставить в зависимости от того, какая цифра в переменной Key_buf.
Можно наверное было бы сделать типа "если в кейбуф цифра "1", то идем на цикл, где жестко прописана обработка массива баттон1, в противном случае, если в кейбуф цифра два, то идем в другой цикл, где обрабатываем только массив баттон2..." все это будет работать, но хотелось бы оптимизировать до одного цикла, в который подставляется нужный массив в зависимости от числа в переменной keybuf.
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
пока писал ты уже напостил
см.выше
см.выше

Re: Ассемблер (ASM) для AVR в вопросах и ответах
О!
Спасибо большое. Поизучаю. Вроде то что нужно.
