Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Rtmip писал(а):... Получится элемент И-НЕ :idea: ...
... А вот действительно, за счет чего? Думаю - подтягивающие резисторы нужны. Поэтому, меняйте схему подключения и все "взлетит" :beer: ...
... По поводу программы, если надумаете ее модернизировать, то я бы посоветовал это сделать так: ...
Спасибо, я просто когда макетировал все это, держал в уме принцип выводов MCS-51 - кто сильнее, тот и пересилит (и почему-то возомнил, что в логике сильнее 1 :))) ), а оно не так))

Насчет подтягивающих резисторов, никоим образом не пытаюсь в Вами спорить (глупо спорить с тем, кто тебе помогает :beer: ), просто руководствовался вот этим http://chipnews.gaw.ru/html.cgi/arhiv/00_09/stat_58.htm Там четко указано, что "Выходы порта P0 на самом деле также имеют транзисторы Q1, которые включаются при выводе младшего байта адреса и при выводе данных в командах записи во внешнюю память. Поэтому при работе порта P0 только в качестве шины данных внешние подтягивающие резисторы не нужны." Так как я избавился от вывода значения в порт, и вывожу только по шине, то я думаю, что можно не ставить их. И просто я допустил просчет не этапе проектирования макета, и у меня порт P0 микроконтроллера и разъем для подключения дисплея на самом краю макетки, красиво впаять туда резисторы не получится :( Так что буду пока пробовать без них...

По поводу программы, спасибо, постараюсь все это учесть :write:

П.С. Зработало !!! Еще в даташите на дисплей была ошибочка, команду очистки дисплея надо было ставить в конце инициализации. Ох уж мне эти Сусанины, не могут в мир документ без ошибки выпустить :kill:

Изображение
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Доброго времени суток. Учусь оптимизировать свои наработки. Есть у меня подпрограмма обработки нажатия матричной клавиатуры. В ней я опускаю столбец и побитно проверяю каждую строку (jnb X MetkaX), и уже на МеткеХ присваиваю код нажатой клавиши, и так 12 раз (если 12 кнопок). Хочется все это дело сделать "Быстрее, выше, сильнее". Попытался использовать массив в памяти программ:
Спойлер

Код: Выделить всё

Key_scan:
mov	DPTR,#Key_Tab1		; Загрузка адреса кодовой таблицы 1
	mov     keyport,#11101111b	; Опустим 1 столбец
	mov	A,keyport            	; Считаем порт клавиатуры в А
	cpl     A                       ; Инвертируем состояние порта, чтобы уменьшить таблицу символов
	anl     A,#00001111b		; Маскируем разряды столбцов
	movc	A,@A+DPTR		; Достаем символ из таблицы
 	jz      Column_2                ; Если ноль - не было нажатия, проверяем следующий столбец
	mov     symbol,A		; Не ноль, было нажатие
	jmp     Key_End			; Пропустим остальные для экономии времени

Column_2:
	mov	DPTR,#Key_Tab2		; Загрузка адреса кодовой таблицы 2
	mov     keyport,#11011111b	; Поднимем назад 1 столбец, и опустим 2 столбец
	mov	A,keyport            	; Считаем порт клавиатуры в А
	cpl     A                       ; Инвертируем состояние порта, чтобы уменьшить таблицу символов
        anl     A,#00001111b		; Маскируем разряды столбцов
 	movc	A,@A+DPTR               ; Достаем символ из таблицы
	jz      Column_3                ; Если ноль - не было нажатия, проверяем следующий столбец
        mov     symbol,A		; Не ноль, было нажатие
	jmp	Key_End                 ; Пропустим остальные для экономии времени

Column_3:
	mov	DPTR,#Key_Tab3		; Загрузка адреса кодовой таблицы 3
	mov     keyport,#10111111b	; Поднимем назад 2 столбец, и опустим 3 столбец
	mov	A,keyport            	; Считаем порт клавиатуры в А
	cpl     A                       ; Инвертируем состояние порта, чтобы уменьшить таблицу символов
        anl     A,#00001111b		; Маскируем разряды столбцов
 	movc	A,@A+DPTR               ; Достаем символ из таблицы
	jz      No_press                ; Если ноль - не было нажатия
        mov     symbol,A		; Не ноль, было нажатие

Key_End:
Проверка введенных символов и прочая ерунда
No_press:				; Если мы прыгнули сюда джампом, значит ни одна кнопка не была нажата
	mov     keyport,#0FFh		; Поднимем все столбцы, ну и строки заодно
        reti

Key_Tab1:				; Клавиатурная таблица 1 столбца
	db      '1','4',0,'7',0,0,0,'*'
	
Key_Tab2:				; Клавиатурная таблица 2 столбца
	db      '2','5',0,'8',0,0,0,'0'
	
Key_Tab3:				; Клавиатурная таблица 3 столбца
	db      '3','6',0,'9',0,0,0,'#'
Сразу предупреждаю, приведенный код не отлаженный и скорее всего не рабочий, мне просто нужно понять концепцию.
Вот до чего я дошел. Использую таблицу символов, разделенную на 3 части, чтобы занимать меньше места в памяти программ (если бы я использовал 1 таблицу, мне пришлось бы сделать ее размерностью 256 ячеек). С той же целью инвертирую состояние считанного порта, чтобы в младшей тетраде получить максимум 1000 (8 в дес. системе) и тем самым ограничить длину таблицы 8 значениями.
Но как видите, у меня 3 раза дублируется кусок кода по опросу. И что еще досаднее, в моей совмещенной клавиатурной таблице половина ячеек пропадает впустую (забиты 0). Помогите мне избавится от этих недостатков. Можете даже предложить иную реализацию. Основная идея - избавиться от кучи джампов и меток (все мои программы от этого страдают, хочу научится писать красиво).

П.С. Допридумал оформить повторяющийся кусок кода в макрос:

Код: Выделить всё

Get_symbol	macro
		mov	A,keyport	; Считаем порт клавиатуры в А
		cpl	A		; Инвертируем состояние порта, чтобы уменьшить таблицу символов
		anl	A,#00001111b	; Маскируем разряды столбцов
		movc	A,@A+DPTR	; Достаем символ из таблицы
		endm
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение ARV »

рекомендую вам вспомнить про циклы, а не только про макросы.

Код: Выделить всё

   маска = 0b00010000; первый столбец
   счетчик = 4
цикл:
   mov  R, маска
   инверсия R
   вывод R ; активируем столбец
   ввод строка ; считываем состояние строк
   сравнить строка, #пусто
   jnz выход
   сдвиг_влево маска
   djnz счетчик, цикл
выход:
   ; здесь у нас код нажатой кнопки в ячейке "строка"
как-то так.

P.S. прошу прощения за волапюк - отвык я о ассемблера, тем более 51-го :dont_know:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Получился вот такой код, он полностью рабочий:
Спойлер

Код: Выделить всё

Key_scan:                               ; Подпрограмма опроса матричной клавиатуры
	clr	TR0             	; Остановим Timer0
	mov	TH0,#3Ch		; Заново занесем значение в счетный регистр Timer0
	mov	TL0,#0AFh               ; При данном значении прерывание возникает каждые 50 мс
	mov	counter,#3              ; Загружаем количество столбцов
	mov	column,#11101111b	; Первый столбец
Loop:
	mov	keyport,column		; Опустим столбец
	mov	A,keyport		; Считаем порт клавиатуры в А
	cpl	A			; Инвертируем состояние порта, чтобы на месте нажатой кнопки получить 1
	anl	A,#00001111b		; Маскируем разряды столбцов (старшие биты АСС)
	jnz	Skip_Repeat		; Если на выходе не 0, значит что-то нажато, гоу проверять
 	mov	A,column		; В аккумуляторе 0, опять загрузим наш столбец
	rl	A                       ; Переведем на следующий
	mov	column,A		; И выгрузим новый столбец назад
	djnz	counter,Loop            ; Повторяем столько раз, сколько всего столбцов
	jmp     No_press                ; Не было нажатия
Skip_Repeat:                            ; Таки что-то нажали
	cjne	counter,#3,Out_1        ; Если counter=3, значит опустили 1 столбец
	mov	DPTR,#Key_Tab1		; Загрузка адреса клавиатурой таблицы 1 столбца
	jmp     Out
Out_1:
	cjne	counter,#2,Out_2        ; Если counter=2, значит опустили 2 столбец
	mov	DPTR,#Key_Tab2		; Загрузка адреса клавиатурой таблицы 2 столбца
	jmp     Out
Out_2:
	cjne	counter,#1,Out		; Значит опустили 3 столбец
	mov	DPTR,#Key_Tab3		; Загрузка адреса клавиатурой таблицы 3 столбца
Out:
	jnb	correct_bit,No_Correction       ; Если нажата кнопка из 4 строки (*,0,#), то скорректируем содержимое АСС,
 	subb	A,#5                    ; чтобы попасть в нужнаю ячейку клавиатурной таблицы
No_Correction:
	movc	A,@A+DPTR		; Достаем символ из таблицы
        mov     symbol,A		; Загружаем его в переменную

	clr     zumer                   ; Озвучим нажатие
	setb	F0			; Запомним факт нажития кнопки
	call	Del_100ms               ; Потупим для подавления дребезга кнопки
        setb    zumer                   ; Закончим озвучку нажатия
No_press:				; Если мы прыгнули сюда джампом, значит ни одна кнопка не была нажата
	setb	TR0             	; Запустим Timer0
	reti

Del_100ms:
        mov	R2,#4h
	mov	R1,#0A0h
	mov	R0,#4Ch
 	djnz	R0,$
	djnz	R1,$-4
	djnz	R2,$-8
	mov	R0,#49h
	djnz	R0,$
        ret

Key_Tab1:				; Клавиатурная таблица 1 столбца
	db      0,'1','4','*','7'

Key_Tab2:				; Клавиатурная таблица 2 столбца
	db      0,'2','5','0','8'

Key_Tab3:				; Клавиатурная таблица 3 столбца
	db      0,'3','6','#','9'
ARV, спасибо за содействие :))
Rtmip
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Rtmip »

Пока_без_кота, приветствую! Спасибо за картинку с дисплеем. :)
Рад, что все заработало у вас! По поводу подтяжки Р0, вы правы, а я перепутал с режимом работы обычного ввода-вывода.
По поводу оптимизации сканирования матричной клавиатуры. Думаю можно еще короче написать.
В подпрограмме не учитываю защиту от дребезга, нажатий сразу двух клавиш и звук. Это вы и сами допишите,
если надо будет. Для примера возьмем "телефонную" клавиатуру:
Спойлер

Код: Выделить всё

klaviatura:
    mov DPTR, #0    ;
    mov R7,   #4    ;счетчик строк
    mov R6,   #1    ;маска сканирования строк
klav1:
    mov R4,   #4    ;счетчик столбцов
    mov R5,   #1    ;маска на результат сканирования
    mov A,    R6 
    rr  A           ;сдвиг вправо единицы из старшего в младший разряд
    mov R6,   A     ;сохранить
    cpl A           ;для вывода сканирующего нуля инверсия
    mov P1,   A     ;вывод сканирующего нуля в порт
klav2:
    mov A,    P1    ;считать результат
    anl A,    R5    ;накладываем маску 
    jz     klav3    ;если был 0, то кнопка нажата
    mov A,    R5    ;иначе сдвигаем маску влево для чтения
    rl  A           ;следующего бита
    mov R5,   A
    inc DPTR        ;увеличиваем, указатель таблицы кнопок
    djnz R4, klav2  ;перебор всех столбцов 
    djnz R7, klav1  ;перебор всех строк
    mov A,    #16  ; признак не нажатых кнопок, можно просто: setb  F0 , затем проверять флаг
    ret                  ; 
klav3:
    mov A,    DPL   ;результат сканирования от 0 до 15
    mov DPTR, #Tab_klav 
    movc A, @A+DPTR ;
    ret                  ;
;
Tab_klav:           ;для наглядности построчно
DB  0               ;1
DB  1               ;2
DB  2               ;3
DB  3               ;A
DB  4               ;4
DB  5               ;5
DB  6               ;6
DB  7               ;B
DB  8               ;7
DB  9               ;8
DB  10              ;9
DB  11              ;C
DB  12              ;*
DB  13              ;0
DB  14              ;#
DB  15              ;D
В результате, после сканирования можно получать сразу код символа из таблицы для вывода,
например, на дисплей или в уарт. Конечно, надо будет заполнить таблицу соответствующим образом.
Вместо чисел от 0 до 15 надо вписать нужные коды. Можно вообще, без таблицы, тогда на выходе будем
получать число от 0 до 15 и оно будет соответствовать нажатой клавише. Можно подключить матрицу не 4Х4,
а любую, меньшей размерности, логика работы и результаты не меняются.
Если подумать над программой, то может и можно будет ее еще сократить-оптимизировать.
Схема подключения клавиатуры:
---1-----2-----3-----A---- P1.7
---4-----5-----6-----B---- P1.6
---7-----8-----9-----C---- P1.5
---*-----0-----#-----D--- P1.4
P1.0...P1.1..P1.2..P1.3
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

После просмотра Вашего кода, мои потуги уже не кажуться мне значительной оптимизацией :))
Правда вот 1 нюанс мне кажется лучше в моей реализации: лучше выставлять флаг нажатой кнопки, чем флаг, то ни одна кнопка не нажата. Потому что в общем времени работы МК, гораздо больше времени кнопки не нажимаются, чем нажимаются, а значит мы экономим 1 команду в цикле почти каждого опроса :beer:
Правда все это нивелируется последующей задержкой антидребезга. Но я ведь и ее когда-то надеюсь устранить, заюзав внутри подпрограммы таймер, который все равно остановлен и проставивает :)))
Rtmip
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Rtmip »

Здравствуйте! Спасибо за комментарии :beer:
Пока_без_кота писал(а):...лучше выставлять флаг нажатой кнопки, чем флаг, то ни одна кнопка не нажата...
для этого можно переставить одну команду, поставив ее после метки "klav3" :

Код: Выделить всё

    setb  F0 
Пока_без_кота писал(а):...заюзав внутри подпрограммы таймер, который все равно остановлен и проставивает...
интересно, как вы это будете делать? Надеюсь не будете "зависать" в подпрограмме ожидая сработки таймера?!
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Rtmip писал(а):... Надеюсь не будете "зависать" в подпрограмме ожидая сработки таймера?!
Нет конечно :))) Я еще не все продумал, но я планирую вываливаться в специально отведенную часть главного цикла, в которой будут выполняться критичные ко времени выполнения операции, которые тем не менее не будут требовать мгновенной реакции (такое я вывожу в обработчики прерываний). Оттуда, по истечении времени антидребезга, я буду возвращаться в цикл обработки нажатия, завершать его, и возвращаться уже в основной главный цикл по reti. Как-то так... :dont_know:
Rtmip
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Rtmip »

Понятно, но становится интересно, а что это будет, такое, с матричной клавиатурой?
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Охранная сигнализация. Придеться еще освоить I2C (чтобы приделать EEPROM память) и научиться работать с GSM-модулем (слать СМС). Возможно потом прикручу экранчик для удобства, и DS1307 в качестве часов. И финальная стадия, это отделение клавиатурного блока и вынос его на расстояние 15-20 метров от основного блока, который будет где-то заныкан (для безопасности). Как-то так. Сейчас работаю над алгоритмом распознавания пароля))
Rtmip
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Rtmip »

Хорошие планы, мне нравится! Вот только расстояние в 15-20 метров сильно смущает :))
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

А чем смущает такое расстояние ? Я читал, что по RS-232 (тот который +-12 В) можно передавать на 10-15 метров. Если не получится, буду пробовать RS-485, но чесно говоря - не хотелось бы, слишком "тяжелая артиллерия" для моих масштабов. Есть еще токовая петля, но это тоже надо спец микросхемы применять, а я хотел что попроще. А MAX232 на каждом углу куча продается.
Насилу дописал алгоритм проверки введенного пароля, думал мозг сломаю, пока все нюансы учту :shock:
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение BOB51 »

Для токовой петли никаких "спец" не требуется, ежли только не притензии к скорости обмена.
8)
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Нет, к максимальным 19200 б\сек токовой петли претензий нет никаких, я сейчас UART юзаю на скорости 9600 б\сек. Просто С МАX232 уже имел дело и проблем там не было (правда расстояния было пару метров всего). Вот и хотелось бы использовать то, что знаешь, и умеешь готовить (хе-хе, это я пока только думаю, что умею).
Покритикуйте кто-то заодно мой алгоритм распознавания пароля. Код рабочий (я всегда все проверяю на макете), функционал устраивает, просто хочу видеть, где можно сделать лучше:
Спойлер

Код: Выделить всё

;============== Проверка пароля ====================
Pass_Check:				; Проверка пароля
	cjne	A,#'#',Skip		; Проверим, или это # (символ ввода пароля)
	mov	A,	pass_counter    ; Это #, проверим, сколько правильных символов подряд до этого было введено
	cjne	A,#3,Error		; Если не 3, то это не наш пароль
	mov	A,	symbol_counter	; Проверим, сколько всего символов было введено до #
	cjne	A,#3,Error		; Если не 3, то это не наш пароль
	jmp	Yes_pass		; 3, так что это наш пароль 
Skip:                                   ; Пока еще не #, будем проверять дальше
	inc	symbol_counter          ; +1 введенный символ	
	mov	DPTR,	#Pass_Tab	; Загрузка адреса кодовой таблицы
	mov	A,	pass_counter	; Загрузка порядкового номера цифры пароля
	movc	A,	@A+DPTR		; Запись очередной цифры пароля в А
	cjne	A,symbol,Error_2	; Сравним введенный символ с символом пароля
	inc	pass_counter            ; Символ принят, в следующий раз возьмем для сравнения следующую цифру пароля
	jmp	No_End	
Yes_pass:
	setb	password_ok             ; Пароль принят !!!
	mov	error_counter,#4        ; Восстановим счетчик попыток ввода пароля
        inc	pass_counter            ; Чтобы пикнуть 3 раза
PiPiPi:                                 ; Озвучим принятый пароль тройным пиканьем
	call	Del_125ms
	cpl	zumer
	djnz	pass_counter,PiPiPi
Error:					; До # было введено больше/меньше символов, чем должно быть в пароле, либо просто количество введенных подряд правильных символов не совпадает
	mov	symbol_counter,#0	; Обнулим счетчик введенных символов, ввод пароля начнется сначала
Error_2:                     		; Введен неправильный символ, счетчик правильно введенных символов необходимо обнулить
	mov	pass_counter,#0         ; Обнулим счетчик правильно введенных символов, ввод пароля начнется сначала
	jb	password_ok,No_End      ; Если введен пароль, нечего уже проверять
	mov	A,symbol
        cjne	A,#'#',No_End
	clr	zumer                   ; Если введен неправильный пароль, то надо сделать длинный ПИИИИИИК
        call	Del_1s
	djnz	error_counter,No_End    ; Проверим сколько неправильных попыток уже было сделано
	clr	sirena_copy_1		; Достаточно, гавкнем сиреной !!!
No_End:                                 ; Была нажата правильная кнопка, но не последняя
        call	Del_125ms		; Потупим для подавления дребезга кнопки
       	setb	zumer                   ; Закончим озвучку нажатия
;============== Конец проверки пароля ====================

Pass_Tab:				; Таблица паролей
	db	'1','2','3'		; Пароль, после всегда символ #
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Jack_A »

Вот эта простая токовая петля работала у меня без замечаний.
Изображение
Вложения
TP1.JPG
(11.59 КБ) 824 скачивания
Изображение
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение ARV »

Пока_без_кота писал(а):Нет, к максимальным 19200 б\сек токовой петли претензий нет никаких, я сейчас UART юзаю на скорости 9600 б\сек. Просто С МАX232 уже имел дело и проблем там не было (правда расстояния было пару метров всего). Вот и хотелось бы использовать то, что знаешь, и умеешь готовить (хе-хе, это я пока только думаю, что умею).
Покритикуйте кто-то заодно мой алгоритм распознавания пароля. Код рабочий (я всегда все проверяю на макете), функционал устраивает, просто хочу видеть, где можно сделать лучше:
Спойлер

Код: Выделить всё

;============== Проверка пароля ====================
Pass_Check:				; Проверка пароля
	cjne	A,#'#',Skip		; Проверим, или это # (символ ввода пароля)
	mov	A,	pass_counter    ; Это #, проверим, сколько правильных символов подряд до этого было введено
	cjne	A,#3,Error		; Если не 3, то это не наш пароль
	mov	A,	symbol_counter	; Проверим, сколько всего символов было введено до #
	cjne	A,#3,Error		; Если не 3, то это не наш пароль
	jmp	Yes_pass		; 3, так что это наш пароль 
Skip:                                   ; Пока еще не #, будем проверять дальше
	inc	symbol_counter          ; +1 введенный символ	
	mov	DPTR,	#Pass_Tab	; Загрузка адреса кодовой таблицы
	mov	A,	pass_counter	; Загрузка порядкового номера цифры пароля
	movc	A,	@A+DPTR		; Запись очередной цифры пароля в А
	cjne	A,symbol,Error_2	; Сравним введенный символ с символом пароля
	inc	pass_counter            ; Символ принят, в следующий раз возьмем для сравнения следующую цифру пароля
	jmp	No_End	
Yes_pass:
	setb	password_ok             ; Пароль принят !!!
	mov	error_counter,#4        ; Восстановим счетчик попыток ввода пароля
        inc	pass_counter            ; Чтобы пикнуть 3 раза
PiPiPi:                                 ; Озвучим принятый пароль тройным пиканьем
	call	Del_125ms
	cpl	zumer
	djnz	pass_counter,PiPiPi
Error:					; До # было введено больше/меньше символов, чем должно быть в пароле, либо просто количество введенных подряд правильных символов не совпадает
	mov	symbol_counter,#0	; Обнулим счетчик введенных символов, ввод пароля начнется сначала
Error_2:                     		; Введен неправильный символ, счетчик правильно введенных символов необходимо обнулить
	mov	pass_counter,#0         ; Обнулим счетчик правильно введенных символов, ввод пароля начнется сначала
	jb	password_ok,No_End      ; Если введен пароль, нечего уже проверять
	mov	A,symbol
        cjne	A,#'#',No_End
	clr	zumer                   ; Если введен неправильный пароль, то надо сделать длинный ПИИИИИИК
        call	Del_1s
	djnz	error_counter,No_End    ; Проверим сколько неправильных попыток уже было сделано
	clr	sirena_copy_1		; Достаточно, гавкнем сиреной !!!
No_End:                                 ; Была нажата правильная кнопка, но не последняя
        call	Del_125ms		; Потупим для подавления дребезга кнопки
       	setb	zumer                   ; Закончим озвучку нажатия
;============== Конец проверки пароля ====================

Pass_Tab:				; Таблица паролей
	db	'1','2','3'		; Пароль, после всегда символ #
показалось сложновато и слегка запутанно.
я бы просто по мере ввода сравнивал каждый символ с паролем. если хотя бы один символ не совпал - устанавливал бы флаг, что не совпал пароль, и после того просто игнорировал бы ввод. когда введен символ конца пароля (у вас вроде #) - просто смотрел бы на флаг. если флаг стоит - ошибка, не стоит - все Ок.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение BOB51 »

Может есть смысл в плоскости KEELOQ поглядеть на реализацию обмена?
:roll:
Rtmip
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Rtmip »

Всех с новым годом!
Пока_без_кота, мне тоже показалась ваша программа неоднозначна и более того, мне показалось,
что там могут быть логические ошибки, но это трудно сказать, не видя, точек входа и выхода из подпрограммы.
Поэтому прислушайтесь к совету ARV, но может я и ошибаюсь, и все там нормально :dont_know:
По поводу клавиатуры на расстоянии 20 метров: а как вы будете ее подключать физически? Ведь у нее
как минимум 8 проводов будет? Не очень понял этот момент.
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Rtmip писал(а): По поводу клавиатуры на расстоянии 20 метров: а как вы будете ее подключать физически? Ведь у нее
как минимум 8 проводов будет? Не очень понял этот момент.
И Вас с наступившим. И всех завсегдатаев этой темы))
Клавиатура впоследствии будет выполнена на отдельном контроллере (часть программы из основного блока просто уйдет в нее), который будет подключатся к основному блоку с помощью последовательной шины. Какой именно, пока точно утверждать не берусь, пока ориентируюсь на RS-232, а в случае неудачи на токовую петлю (схема с рисунка Jack_A вроде несложная).

Уважаемый ARV, спасибо за наводку. На досуге еще обмозгую этот вопрос и возможно отпишу сюда результат.
Подскажите еще по такому вопросу. Для формирования Таблицы пароля я хочу использовать макрос IRPC (это тот, который выводит строку посимвольно), который выглядит вот так:
Спойлер

Код: Выделить всё

irpc	Pass,	'123'
	db	Pass
endm
и должен транслироваться вот в это:

Код: Выделить всё

db	'1'
db	'2'
db	'3'
Вместо этого он транслируется вот в это:

Код: Выделить всё

db	1
db	2
db	3
При использовании макроса IRP все транслируется корректно:

Код: Выделить всё

irp	Pass,	'1','2','3'
	db	Pass
endm
как положено транслируется в:

Код: Выделить всё

db	'1'
db	'2'
db	'3'
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Re: Мелкие вопросы по МК-51 а-ка MCS-51, ASM и не только..

Сообщение Пока_без_кота »

Доброго времени суток. Прошу подсказать, как правильнее реализовать отправку строки по UART. Вызывать процедуру отправки, в которой при каждом новом извлечении символа из памяти программ записывать его в SBUF, и тем самым вызывать прерывание, в котором он будет отправлятся. Или устанавливать вручную флаг TI, который вызовет прерывание, внутри которого и будет находится процедура отправки, и она будет крутится в цикле внутри прерывания, пока не отправит всю строку. Вот код 1 варианта:
Спойлер

Код: Выделить всё

; Где-то внутри главного цикла
	mov	DPTR,#AT_CMGS			; Загружаем адрес 1 символа команды
	call    Send_comm
;=======
Send_comm:                                              ; Подпрограмма отправки
	clr	A                                       ; Очистим АСС
	movc	A,	@A+DPTR                         ; Поместим очередной символ команды в АСС
	jz	Out					; Если конец команды, выходим
	mov	SBUF,	A                               ; Скопируем его в буфер передатчика
	call    Del_100ms                               ; Без этой задержки шлет мусор !!!
	inc	DPTR                                    ; Возьмем следующий символ
	jmp	Send_comm                              	; Зациклимся на передачу всей строки
Out:
	ret
;=======
Serial_int:						; Обработчик прерываний посл. порта
	clr	EA					; Запретим все прерывания
	jb	RI,	Receive				; Если есть флаг RI, значит это прием
	jnb     TI,$                    		; Нет флага ТІ (окончания посылки) - топчемся на месте
	clr	TI					; Был флаг ТІ, байт ушел, сбросим флаг ТІ
	jmp     Serial_end
Receive:						; Это прием
	mov	A,	SBUF				; Это прием, примем байт
	clr	RI					; Сбросим флаг RI
Serial_end:
	setb	EA					; Разрешим все прерывания
	reti
Проблема этого варианта в том, что без задержки на несколько десятков мс между символами, шлется мусор (почему??? ведь я каждый раз дожидаюсь флага TI). И вообще, этот вариант мне не нравится тем, что постоянно дергается прерывание последовательного порта.

Вот 2 вариант:
Спойлер

Код: Выделить всё

; Где-то внутри главного цикла
	mov	DPTR,#AT_CMGS			; Загружаем адрес 1 символа команды
	setb	TI				; Вызовем отправку команды
;=======
Serial_int:						; Обработчик прерываний посл. порта
	clr	EA					; Запретим все прерывания
	jb	RI,	Receive				; Если есть флаг RI, значит это прием
        clr	TI                                      ; Сбросим флаг ТІ, которым вызвали прерывание
Repeat:
	clr	A                                       ; Очистим АСС
	movc	A,	@A+DPTR                         ; Поместим очередной символ команды в АСС
	jz	Serial_end				; Если конец команды, выходим
	mov	SBUF,	A                               ; Скопируем его в буфер передатчика
	jnb     TI,$                    		; Нет флага ТІ (окончания посылки) - топчемся на месте
	clr	TI					; Был флаг ТІ, байт ушел, сбросим флаг ТІ
	inc	DPTR                                    ; Возьмем следующий символ
	jmp	Repeat                               	; Зациклимся на передачу всей строки
Receive:						; Это прием
	mov	A,	SBUF				; Это прием, примем байт
	clr	RI					; Сбросим флаг RI
Serial_end:
	setb	EA					; Разрешим все прерывания
	reti
Этот вариант работает нормально без введения всяких задержек. Но я везде читал, что надо как можно быстрее валить из прерывания, а я там кручусь в цикле, и меня это немного смущает.
Так как правильнее ?
Ответить

Вернуться в «Разные вопросы по МК»