Опрос кнопок на ассемблере

Тема в разделе "Микроконтроллеры AVR", создана пользователем Борис144, 6 мар 2017.

  1. Борис144

    Борис144 Нуб

    Доброго времени. Задача: управлять матрицей светодиодов (3*3) с помощью матрицы кнопок (3*3).
    Схема:
    123456.jpg
    Код:
    чтобы не загромождать программу, приведу код опроса первой строки, т.е кнопок SW1-Sw3 и соответственно включение светодиодов D1-D3.
    Код (Text):
    .include "tn2313def.inc"

    .def temp=R16
    .def counter=R17

    .def R_0 = R18 ;разряды задержки
    .def R_1 = R19
    .def R_2 = R20





    ;=============Загрузка указателя стека========================

            ldi temp,RAMEND ;загрузка указателя стека
            out SPL,temp

    ;=============Установка I/O========================
            ldi temp, 0b00000111    ; установка  битов 0,1,2 на выход порта D
            out DDRD,temp            ; битов 3,4,5 на вход

            ldi temp, 0b11111111    ; установка битов в HIGH
            out PORTD,temp            ;

            ldi temp, 0b00111111    ; установка  битов  на выход,
            out DDRB,temp            ;

            ldi temp, 0b00000000    ; установка битов
            out PORTB,temp            ; установка битов в LOW


    ;============ Инициализация компаратора=============

            ldi     temp, 0x80    ; Выключение компаратора
            out        ACSR, temp
           
    ;================= Основной цикл======================  
    ;----------------------------Опрос первой кнопки-----------
    main:    ldi temp, 0b11111110   ;  устанавливаем выход 2 в ноль
            out PORTD,temp

            sbic PIND,3                         ; если кнопка нажата -  переходим к задержке
            rjmp     main_1                  ; если не нажата, то переходим к метке 1
            rcall Delay                      ; задержка

            ldi temp, 0b00001110   ; включаем первый светодиод
            out PORTB,temp

    main_:    sbis PinD,3       ; если кнопка нажата, то ждем отпускания. Если отпущена переходим к задержке
            rjmp main_    
            rcall Delay    ; задержка

            ldi temp,0b00000000   ; выключаем светодиод
            out PORTB,temp
            rjmp     main       ; идем в начало опроса

    ;-----------Опрос второй кнопки------------

    main_1:    ldi temp, 0b11111101   ;  устанавливаем выход 3 в ноль. Дальше точно также опрашиваем
            out PORTD,temp

            sbic PIND,3
            rjmp     main_3
            rcall Delay

            ldi temp, 0b00001101  
            out PORTB,temp

    main_2:    sbis PinD,3
            rjmp main_2
            rcall Delay

            ldi temp,0b00000000  
            out PORTB,temp
            rjmp     main
    ;-----------Опрос третьей кнопки------------


    main_3:    ldi temp, 0b11111011  
            out PORTD,temp

            sbic PIND,3
            rjmp     main
            rcall Delay

            ldi temp, 0b00001011  
            out PORTB,temp

    main_4:    sbis PinD,3
            rjmp main_4
            rcall Delay

            ldi temp,0b00000000  
            out PORTB,temp
            rjmp     main

    Delay:  
            ldi R_0,0b11111111
            ldi R_1,0b11111111
            ldi R_2,0b00000001


    Delay_1:dec R_0
            brne Delay_1
            dec R_1
            brne Delay_1
            dec R_2
            brne Delay_1
            ret
     
    Так вот, в протеусе моделирует все правильно. Но если прошиваю реально, то при нажатии кнопки 1 зажигается не первый светодиод, а другой, причем мигает, хотя должен гореть постоянно. При опросе всей матрицы клавиатуры, неправильно работает только первая строка. А строки 2 и 3 работают правильно. Уверен, что дело в коде, но как исправить эту ситуацию остается загадкой. Может кто сталкивался с такой ситуацией?
     
  2. AlexU

    AlexU Гуру

    По схеме:
    RESET нужно подтянуть к питанию иначе микроконтроллер либо вообще не будет стартовать, либо будет перегружаться когда вздумается.
    Из матричной клавиатуры нужно убрать резисторы, т.к. в паре с резисторами подтяжки создают делители напряжения с непонятным уровнем на входных пинах микроконтроллера (непонятным из-за большого разброса в номиналах подтяжки).

    В общем немного удивлён, что схема в реале хоть как-то работает...
     
    Борис144 нравится это.
  3. Борис144

    Борис144 Нуб

    AlexU, благодарю за подсказку. Проблема устранена.