Светодиод с кнопочным управлением Arduino со сборкой AVR

Я пытаюсь создать простой светодиод, управляемый кнопкой, но не могу получить от кнопки никаких входных данных, которые могли бы изменить состояние светодиода. Другими словами, программа продолжает переходить к включению света, сохраняя светодиод всегда включенным, независимо от состояния кнопки. Я использую Elegoo Uno R3.

Схема:

Код:

.текст
.глобальная настройка
.глобальный цикл

настраивать:
сер р16
стс ДДРБ, р16
лди r16, 0b00000000
стс ДДРД, р16
лди r16, 0b00100000
стс ПОРТБ, р16
клр р16
стс ПОРТД, р16

петля:
лдс р20, ПОРТД
cpi r20, 0x00 ; PORTD всегда равен 0x00?
Брек Лайтон
клр р16
стс ПОРТБ, р16
цикл rjmp
включить свет:
лди r16, 0b00100000
стс ПОРТБ, р16
цикл rjmp

Изменить: я также реализовал этот метод в https://stackoverflow.com /questions/39361410/creating-a-toggle-switch-in-avr-assembly, чтобы создать короткую задержку с помощью r18 вместо del, но это не помогло Поможешь; см. измененный метод цикла ниже:

петля:
ЦПИ R18, 0
Брне dec_jmp
лдс р20, ПОРТД
cpi r20, 0x00 ; PORTD всегда равен 0x00?
Брек Лайтон
клр р16
стс ПОРТБ, р16
лди р18, 250
цикл rjmp
включить свет:
лди r16, 0b00100000
стс ПОРТБ, р16
лди р18, 250
цикл rjmp

dec_jmp:
декабрь 18
цикл rjmp

С задержкой:

включить свет:
лди r16, 0b00100000
стс ПОРТБ, р16
задержка звонка150
лди r16, 0b00000000
стс ПОРТБ, р16
задержка звонка150
цикл rjmp

, 👍0

Обсуждение

Дубликат: https://stackoverflow.com/questions/39361410/creating-a-toggle-switch-in-avr-assembly, @Jot

Смотрите правку в посте, @Bgeo25

У вас есть две потенциальные проблемы в настройке: 1. Вы тестируете не только PortB-bit2 (= контакт 2 Arduino), но и все контакты PortB. Поскольку они являются плавающими, ваш тест (cpi r20 0x00) никогда не выполнится, и переход к Lighton никогда не произойдет. 2. Ваша кнопка будет подпрыгивать (погуглите по этому поводу). Из-за первой проблемы светодиод должен оставаться выключенным. Но он остается включенным, значит, что-то не так. Разбейте программу на более мелкие части и протестируйте каждую часть отдельно. Вы пытались включать и выключать светодиод только программным способом (с задержкой между ними и без учета состояния переключателя)?, @PimV

Бит 2 PORTB соответствует контакту Pin13, который я использую. Насколько я понимаю, переход к «lighton» происходит всегда, и в этом проблема. Например, я удалил строку, которая устанавливает PORTB в методе setup, и светодиод остается включенным. Итак, Pin13 постоянно устанавливается на «lighton». Также я попробовал светодиод сам по себе с задержкой, и он работает нормально., @Bgeo25

Вы уверены, что кнопка подключена правильно? меняется ли напряжение на контакте 3 при нажатии кнопки?, @jsotola

Почему вы подключили второй светодиод к контакту 13? Вы также можете использовать светодиод, который уже есть (на Arduino). Измените тест, чтобы проверять только бит 2, а не все байты из Por tD (замаскируйте их bij И с помощью 0x04). Даже если вы это сделаете, у вас все равно останется проблема с подпрыгиванием. Добавьте задержку на пару секунд, чтобы вы могли видеть, что происходит в каждом цикле. Что произойдет, если вы замените кнопку куском проволоки (например, кнопка всегда закрыта) или когда вы вытащите кнопку (например, кнопка всегда открыта)?, @PimV

Смотрите ответ ниже, @Bgeo25

Для справки: если вы работаете с Arduino Uno, то контакт 13 на плате подключен к желтому светодиоду через неинвертирующий операционный усилитель и резистор. Из-за ОУ нагрузка на вывод незначительна. — Настройка остальных контактов PORTD не столь важна. Важно то, что вы проверяете только состояние контакта 2: lds r20 PORTD / andi r20 0b00000100 / breq Lighton (инструкция andi устанавливает остальные биты в ноль, так что breq основан на только от значения Pin2)., @PimV


1 ответ


1

Исправлено с помощью приведенного ниже кода цикла:

петля:
СБИК ПИНД, 2
позвони в нопрессб
; кнопка нажата
лди r16, 0b00100000
выход PORTB, r16
цикл rjmp
нопрессб:
лди r16, 0b00000000
выход PORTB, r16
цикл rjmp
,

Почему вы используете вызов для перехода к nopressb? call предназначен для вызова подпрограммы и сохраняет адрес возврата в стеке. Поскольку вы никогда не возвращаетесь из подпрограммы, стек переполнится., @PimV