|
"Домашнее задание"
| |
GranDAD | Дата: Понедельник, 28.05.2012, 00:28 | Сообщение # 1 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| Сергей, проверь пожалуйста, правильно ли я написал программы из "второго шага"(http://sokolsp.at.ua/publ/assembler_dlja_nachinajushhikh_vtoroj_shag/1-1-0-13)
Первая: Code .include "F:\Prog\AVR\asm\Appnotes\tn13def.inc" sbi DDRB, 4 ;РВ4 - выход (светодиод LED2) sbi PORTB, 2 ;Включение подтягивающего резистора на РВ2 (кнопка SB1) sbis PINB, 2 ;Если РВ2=1 (кнопка отпущена), пропустить след. строку sbi PORTB, 4 ;Установка РВ4 в 1 (выключение светодиода) sbic PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку cbi PORTB, 4 ;Установка РВ4 в 0 (включение светодиода)
Вторая: Code .include "F:\Prog\AVR\asm\Appnotes\tn13def.inc" sbi DDRB, 4 ;РВ4 - выход (светодиод LED2) sbi PORTB, 2 ;Включение подтягивающего резистора на РВ2 (кнопка SB1) sbi PORTB, 1 ;Включение подтягивающего резистора на РВ1 (кнопка SB2)
loop1: sbis PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку rjmp loop1 ;Повторить цикл проверки состояния кнопки SB1
label: cbi PORTB, 4 ;Установка РВ4 в 0 (включение светодиода)
loop2: sbic PINB, 1 ;Если РВ1=0 (кнопка нажата), пропустить след. строку rjmp loop2 ;Повторить цикл проверки состояния кнопки SB2
sbi PORTB, 4 ;Установка РВ4 в 1 (выключение светодиода) rjmp loop1 ;прыжок в начало программы
P.S. Почему-то мне кажется, что вторую программу можно как-то оптимизировать. Не подскажешь как?
Сообщение отредактировал GranDAD - Понедельник, 28.05.2012, 00:31 |
|
| |
mimino | Дата: Понедельник, 28.05.2012, 01:04 | Сообщение # 2 |
Полковник
Группа: Администраторы
Сообщений: 227
Статус: Offline
| GranDAD, интересное у вас решение второй задачи. Я бы сам сделал немного не так. Но все же мне кажется, что в нем есть ошибка. Code loop1: sbis PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку rjmp loop1 ;Повторить цикл проверки состояния кнопки SB1 Не должна ли тут использоваться команда sbic?
А в остальном на первый взгляд правильно.
|
|
| |
GranDAD | Дата: Понедельник, 28.05.2012, 03:08 | Сообщение # 3 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| Quote (mimino) Не должна ли тут использоваться команда sbic? Да, не то вставил из буфера обм.
Quote (mimino) Я бы сам сделал немного не так. Если тебе не сложно можешь показать как.
Кстати сделал сегодня задание из третьей статьи Code
.include "F:\Prog\AVR\asm\Appnotes\tn13def.inc"
sbi DDRB, 4 ; Линия PB4- выход sbi DDRB, 0 ; Линия PB0- выход main: ; Основной цикл программы
led1: sbic PINB, 4 ; Если PB4=0, то пропустить след. строку cbi PORTB,4 ; Установка PB4 в 0 sbis PINB, 4 ; Если PB4=1, то пропустить след. строку sbi PORTB,4 ; Установка PB4 в 1 rcall loop ; Вызов подпрограммы по метке loop
led2: sbic PINB, 0 ; Если PB4=0, то пропустить след. строку cbi PORTB,0 ; Установка PB0 в 0 sbis PINB, 0 ; Если PB4=1, то пропустить след. строку sbi PORTB,0 ; Установка PB0 в 1 rcall loop ; Вызов подпрограммы по метке loop rjmp main
loop: ldi r16, 255 ; Загрузка значения в r16 ldi r17, 223 ; Загрухка значения в r17 ldi r18, 6 ; Загрузка значения в r18 delay: subi r16, 1 ; Вычетание 1 из к16 sbci r17, 0 ; Вычетание с переносом из r17 sbci r18, 0 ; Вычетание с переносом из r18 brcc delay ; Если не было переноса вернеться к метке delay ret
P.S. Твои статьи легко читаются и запоминаются, спасибо. Жаль только, что я твой сайт раньше не увидел.
Сообщение отредактировал GranDAD - Понедельник, 28.05.2012, 11:19 |
|
| |
mimino | Дата: Понедельник, 28.05.2012, 17:58 | Сообщение # 4 |
Полковник
Группа: Администраторы
Сообщений: 227
Статус: Offline
| GranDAD, я старался придумать такие задания, чтоб их можно было выполнить, зная только то, что я описывал раньше. Поэтому я бы сделал из второго шага второе задание где-то так: Code .include "F:\Prog\AVR\asm\Appnotes\tn13def.inc" sbi DDRB, 4 ;РВ4 - выход (светодиод LED2) sbi PORTB, 2 ;Включение подтягивающего резистора на РВ2 (кнопка SB1) sbi PORTB, 1 ;Включение подтягивающего резистора на РВ1 (кнопка SB2) sbis PINB, 1 ;Если РВ1=1 (кнопка SB2 не нажата), пропустить след. строку sbi PORTB, 4 ;Установка РВ4 в 1 (выключение светодиода) sbis PINB, 2 ;Если РВ2=1 (кнопка SB1 не нажата), пропустить след. строку cbi PORTB, 4 ;Установка РВ4 в 0 (включение светодиода)
А насчет 3-го задания, мне кажется, что лучше было бы вот эти коды слить в один: Quote led1: sbic PINB, 4 ; Если PB4=0, то пропустить след. строку cbi PORTB,4 ; Установка PB4 в 0 sbis PINB, 4 ; Если PB4=1, то пропустить след. строку sbi PORTB,4 ; Установка PB4 в 1 rcall loop ; Вызов подпрограммы по метке loop
led2: sbic PINB, 0 ; Если PB4=0, то пропустить след. строку cbi PORTB,0 ; Установка PB0 в 0 sbis PINB, 0 ; Если PB4=1, то пропустить след. строку sbi PORTB,0 ; Установка PB0 в 1 rcall loop ; Вызов подпрограммы по метке loop rjmp main То есть, сделать сразу переключения обоих светодиодов, а потом один раз вызвать задержку, а иначе получится в два раза дольше, чем нужно.
|
|
| |
GranDAD | Дата: Понедельник, 28.05.2012, 18:14 | Сообщение # 5 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| Спасибо.
Code .include "F:\Prog\AVR\asm\Appnotes\tn13def.inc" sbi DDRB, 4 ;РВ4 - выход (светодиод LED2) sbi PORTB, 2 ;Включение подтягивающего резистора на РВ2 (кнопка SB1) sbi PORTB, 1 ;Включение подтягивающего резистора на РВ1 (кнопка SB2) sbis PINB, 1 ;Если РВ1=1 (кнопка SB2 не нажата), пропустить след. строку sbi PORTB, 4 ;Установка РВ4 в 1 (выключение светодиода) sbis PINB, 2 ;Если РВ2=1 (кнопка SB1 не нажата), пропустить след. строку cbi PORTB, 4 ;Установка РВ4 в 0 (включение светодиода)
Я немножко запутался. Что произойдет после последней строчке в программе (cbi PORTB, 4 ...). Программа сама начнет выполняится сначала или нужно все таки испозьовать rjmp?
Сообщение отредактировал GranDAD - Понедельник, 28.05.2012, 19:32 |
|
| |
mimino | Дата: Понедельник, 28.05.2012, 22:26 | Сообщение # 6 |
Полковник
Группа: Администраторы
Сообщений: 227
Статус: Offline
| Вообще-то она сама начнет выполняться сначала. Но такой подход немного неправильный, так как каждый раз будет выполняться инициализация портов ввода-вывода, поэтому лучше сделать так, конечно: Code .include "F:\Prog\AVR\asm\Appnotes\tn13def.inc" sbi DDRB, 4 ;РВ4 - выход (светодиод LED2) sbi PORTB, 2 ;Включение подтягивающего резистора на РВ2 (кнопка SB1) sbi PORTB, 1 ;Включение подтягивающего резистора на РВ1 (кнопка SB2) loop: sbis PINB, 1 ;Если РВ1=1 (кнопка SB2 не нажата), пропустить след. строку sbi PORTB, 4 ;Установка РВ4 в 1 (выключение светодиода) sbis PINB, 2 ;Если РВ2=1 (кнопка SB1 не нажата), пропустить след. строку cbi PORTB, 4 ;Установка РВ4 в 0 (включение светодиода) rjmp loop
|
|
| |
GranDAD | Дата: Понедельник, 28.05.2012, 22:33 | Сообщение # 7 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| Понятно, тогда у сеня к вам будет еще один вопрос.
Если использовать Atmega8 и порты PBx, нужно ли вносить изменения в программу.
|
|
| |
mimino | Дата: Понедельник, 28.05.2012, 22:39 | Сообщение # 8 |
Полковник
Группа: Администраторы
Сообщений: 227
Статус: Offline
| Единственно, нужно будет подключить другой заголовочный файл в первой строке, а так остальное должно быть то же самое
|
|
| |
GranDAD | Дата: Вторник, 29.05.2012, 23:53 | Сообщение # 9 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| mimino, Можешь дать хоть какую то подсказку ко 2 заданию из 4 шага. Как то не представляю как такое можно реализовать без многопоточности
Сообщение отредактировал GranDAD - Вторник, 29.05.2012, 23:54 |
|
| |
mimino | Дата: Среда, 30.05.2012, 00:09 | Сообщение # 10 |
Полковник
Группа: Администраторы
Сообщений: 227
Статус: Offline
| Да тут просто по очереди опрашивать кнопки можно. Частота опроса-то высокая, задержку никто не заметит.
|
|
| |
GranDAD | Дата: Среда, 30.05.2012, 00:12 | Сообщение # 11 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| Да., об этом я думал. Но что если обе кнопки одновременно нажать?
Вот между прочем мой пример программы: Code .include "C:\Users\Sevos\Desktop\asm\Appnotes\tn13def.inc" ldi r16, RAMEND ;Загрузка в регистр r16 адреса верхней границы ОЗУ out SPL, r16 ;Копирование значения из r16 в регистр указателя стека SPL ldi r17,(1<<4) ;Загрузка в регистр r17 "1", смещенной на 4 разряда влево out DDRB, r17 ;Копирование из r17 в DDRB (РВ4 - выход) ldi r16,(1<<2) ;Загрузка в регистр r16 "1", смещенной на 2 разряда влево sbi DDRB, 0 ;РВ0 - выход (светодиод LED2) sbi PORTB, 1 ;Включение подтягивающего резистора на РВ1 (кнопка SB1) sbi PORTB, 0 ;Установка РВ0 в 1 (выключение светодиода)
main: ;Основной цикл программы rcall led out PORTB,r16 ;Копирование из r16 в PORTB sbic PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку rjmp main ;Возврат к началу цикла rcall delay ;Вызов подпрограммы задержки на дребезг контактов wait: ;Цикл ожидания, пока нажата кнопка sbis PINB, 2 ;Если РВ2=1 (кнопка отпущена), пропустить след. строку rjmp wait ;иначе перейти к началу цикла ожидания rcall delay ;Вызов подпрограммы задержки на дребезг контактов sbic PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку eor r16,r17 ;Исключающее ИЛИ регистров r16 и r17 rjmp main ;Возврат к метке main
led: sbic PORTB, 0 rjmp led1 sbic PINB, 1 ;Если РВ1=0 (кнопка нажата), пропустить след. строку rcall null rcall delay sbi PORTB, 0 ;Установка РВ0 в 1 (выключение светодиода)
led1: sbic PINB, 1 ;Если РВ1=0 (кнопка нажата), пропустить след. строку rcall null rcall delay cbi PORTB, 0 ;Установка РВ0 в 0 (включение светодиода) ret
delay: ;Начало подпрограммы задержки ldi r18, 255 ;Загрузка значения в регистр r18 ldi r19, 31 ;Загрузка значения в регистр r19 del: ;Цикл задержки subi r18, 1 ;Вычитание 1 из регистра r18 sbci r19, 0 ;Вычитание 0 из регистра r19 с учетом переноса brcc del ;Если не было переноса вернуться к метке del ret ;Возврат из подпрограммы
null: ; Ничего неделание, Что бы "sbic PINB, 1" было что пропускать <img src="http://s105.ucoz.net/sm/1/smile.gif" border="0" align="absmiddle" alt="smile" /> ret
Сообщение отредактировал GranDAD - Среда, 30.05.2012, 00:24 |
|
| |
mimino | Дата: Среда, 30.05.2012, 00:38 | Сообщение # 12 |
Полковник
Группа: Администраторы
Сообщений: 227
Статус: Offline
| Если обе кнопки одновременно нажать, сработает та, которую нажали раньше. Чтобы этого избежать, надо несколько поизвращаться.
А вы программы пишете просто умозрительно или проверяете их на контроллере? Алгоритмы у вас такие интересные, видать, у вас несколько иной склад мышления, чем у меня.
И кстати, вместо rcall null можно использовать команду ничегонеделания nop. Так оно и короче, и понятней
|
|
| |
GranDAD | Дата: Среда, 30.05.2012, 00:45 | Сообщение # 13 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| Проверяю только в Proteus'e (и не каждый раз, комп. другими занат часто) так как у меня attiny13 только в smd, а плату травить пока нечем
Над аргоритмом сегодня целый день мучался Но никак не получается довести его до ума. Только что удалось проверить программу в Proteus'e, надеялся на чудо, не его не произошло , 1 светодиод безперерывно мигает, и на нажатия кнопки не реагирует.
Сообщение отредактировал GranDAD - Среда, 30.05.2012, 01:12 |
|
| |
mimino | Дата: Среда, 30.05.2012, 02:09 | Сообщение # 14 |
Полковник
Группа: Администраторы
Сообщений: 227
Статус: Offline
| Так оно по алгоритму и получается. У вас же части led и led1 выполняются по очереди, и притом, независимо от того, будет ли какая-то кнопка нажата, в первой части светодиод выключается, а во второй включается.
Я бы сделал эту задачу, как в примере, только поставил бы подряд два обработчика кнопок, и каждый завязал на один и тот же светодиод. Тогда должно получиться.
|
|
| |
GranDAD | Дата: Четверг, 31.05.2012, 21:26 | Сообщение # 15 |
Лейтенант
Группа: Проверенные
Сообщений: 49
Статус: Offline
| Не совсем понятно как сделать так чтобы два обработчика кнопок работали независимо друг от друга. Code main: ;Основной цикл программы out PORTB,r16 ;Копирование из r16 в PORTB sbic PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку rjmp main ;Возврат к началу цикла
Исходя из кода выше программа не продвинется вперед пока не будет нажата SB1. И из-за этого мне трудно придумать алгоритм. И еще не совсем понятно зачем завязывать обе кнопки на один светодиод, как же тогда зажигать второй?Добавлено (31.05.2012, 21:26) --------------------------------------------- Сергей, посмотри пожалуйста почему в этот раз не работает. Пеперисал кусок кода и был уверен что заработает. Но увы Code .include "C:\Users\Sevos\Desktop\asm\Appnotes\tn13def.inc" ldi r16, RAMEND ;Загрузка в регистр r16 адреса верхней границы ОЗУ out SPL, r16 ;Копирование значения из r16 в регистр указателя стека SPL ldi r17,(1<<4) ;Загрузка в регистр r17 "1", смещенной на 4 разряда влево out DDRB, r17 ;Копирование из r17 в DDRB (РВ4 - выход) ldi r16, 0b00000110 ;Загрузка в регистр r16 "1", смещенной на 2 разряда влево
main: ;Основной цикл программы rcall led out PORTB,r16 ;Копирование из r16 в PORTB sbic PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку rjmp main ;Возврат к началу цикла rcall delay ;Вызов подпрограммы задержки на дребезг контактов wait: ;Цикл ожидания, пока нажата кнопка sbis PINB, 2 ;Если РВ2=1 (кнопка отпущена), пропустить след. строку rjmp wait ;иначе перейти к началу цикла ожидания rcall delay ;Вызов подпрограммы задержки на дребезг контактов sbic PINB, 2 ;Если РВ2=0 (кнопка нажата), пропустить след. строку eor r16,r17 ;Исключающее ИЛИ регистров r16 и r17 rjmp main ;Возврат к метке main
led: sbis PORTB, 0 ;Если РВ0=1 (светодиод выключен), пропустить след. строку rjmp led1 sbic PINB, 1 ;Если РВ1=0 (кнопка нажата), пропустить след. строку ret rcall delay cbi PORTB, 0 ;Установка РВ0 в 0 (включение светодиода)
led1: sbic PORTB, 0 ;Если РВ0=0 (светодиод включен), пропустить след. строку ret sbic PINB, 1 ;Если РВ1=0 (кнопка нажата), пропустить след. строку ret rcall delay sbi PORTB, 0 ;Установка РВ0 в 1 (выключение светодиода) ret
delay: ;Начало подпрограммы задержки ldi r18, 255 ;Загрузка значения в регистр r18 ldi r19, 31 ;Загрузка значения в регистр r19 del: ;Цикл задержки subi r18, 1 ;Вычитание 1 из регистра r18 sbci r19, 0 ;Вычитание 0 из регистра r19 с учетом переноса brcc del ;Если не было переноса вернуться к метке del ret ;Возврат из подпрограммы
Сообщение отредактировал GranDAD - Четверг, 31.05.2012, 17:13 |
|
| |
| |