
Список литературы:
Шагурин И. И. Архитектура, программирование и применение 8-разрядных микроконтроллеров семейства Motorola 68HC08. Лабораторный практикум.-МИФИ.-2002,-98с.
Шагурин И. И. Микропроцессоры и микроконтроллеры фирмы Motorola": Справочное пособие. -М. :Радио и связь, 1998- 560с.: ил.
Ремизевич Т.В. Микроконтроллеры для встраиваемых приложений. Под редакцией Кирюхина И.С. –М: Додека, 2000.-272с.
Предко М. Руководство по микроконтроллерам в 2-х томах. М.: Постмаркет, 2001.
Солонина А.И., Улахович Д. А., Яковлев Л. А. Цифровые процессоры обработки сигналов фирмы Motorola. – СПб.:БХВ-Петербург, 2000.-512 с. ил.
Сулимов А. И. Управление периферийными устройствами в системах, построенных на базе микроконтроллера МС68НС908GP32. Выпускная (квалификационная) работа бакалавра радиофизики.
Приложение 1
Алгоритм и программа формирования номера нажатой клавиши
В предыдущих пунктах были описаны основные методы работы с клавиатурой, позволяющие решать задачи формирования кода нажатой клавиши. Рассмотрим алгоритм формирования номера нажатой клавиши, взяв за основу полученный код клавиши и используя команды побитового тестирования и сравнения.
Присвоим клавишам номера.
Таблица 3.5. Соответствие клавиш и их номеров | ||||||||||||
имвол клавиши |
«1» |
«2» |
«3» |
«4» |
«5» |
«6» |
«7» |
«8» |
«9» |
«*» |
«0» |
«#» |
Номер клавиши |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
В соответствии с данной нумерацией клавиши, располагающиеся в одном столбце и в соседних строках, отличаются по номеру на 3. В первом столбце расположены клавиши с номерами: 1, 4, 7, 10; во втором – с номерами: 2, 5, 8, 11и в третьем – с номерами: 3, 6, 9, 12.
Таким образом, засылая сканирующий код, выбирающий столбец с номером n (n = 1, 2, 3) мы можем получить следующие номера клавиш:
k = n + 3·(m – 4), где m – номер бита в старшей тетраде (m = 4 7).
Так как номер n мы задаём сами, то вся задача формирования номера нажатой клавиши сводится к определению m. Для хранения текущего предполагаемого номера клавиши k целесообразно выделить ячейку памяти.
Для определения m можно использовать соответственно 4 команды поразразрядной проверки содержимого старшей тетрады кода. Также возможно использование изменяемой маски, которая логически перемножается с содержимым регистра А, и значение интересующего бита будет противоположно значению флага Z. Однако, при этом необходимо возобновлять код в регистре А перед следующей проверкой и изменять маску, что также ведёт к избыточности выполняемых операций.
В реализации алгоритма был выбран простой и компактный сдвиговый способ.
С
0Операнд
Стандартной командой логического сдвига код в аккумуляторе продвигается в сторону флага переноса. Эти сдвиги производятся в цикле, выход из которого происходит при обнаружении нуля в бите признака переноса. Соответственно для обнаружения значащего нуля требуется произвести не более 4-х сдвигов. Анализ кода в данной схеме осуществляется от старшего информационного бита (седьмого) к младшему (четвёртому), что по схеме подключения клавиатуры к линиям порта А соответствует анализу от нижней строки клавиатуры – к верхней. Поэтому при выборе очередного столбца клавиатуры следует в ячейку, содержащую текущее предполагаемое значение номера, засылать максимально возможный в данном столбце номер. Если, к примеру, ноль в седьмом бите, который после первого сдвига должен оказаться в бите переноса, не будет обнаружен, то содержимое ячейки памяти текущего номера нужно уменьшить на 3, и далее аналогичным образом поступать и в отношении следующих битов. Приведём пример: выясним номер клавиши "5", имеющей код $DA = 1101 1010. Пусть предварительный анализ уже указал, что клавиша "5" находится во втором столбце. Таким образом, в ячейку текущего номера будет записано число 11 = 0В16.
Таблица 3.6. К пояснению алгоритма формирования номера нажатой клавиши
№ шага |
Содержимое флага С |
Содержимое регистра А |
Предполагаемое значение k |
1 |
не определено |
1101 1010 |
11 |
2 |
1 |
1011 0100 |
8 |
3 |
1 |
0110 1000 |
5 |
4 |
0 |
1101 0000 |
5 |
Как видно из таблицы, потребовалось три сдвиговых операций для обнаружения информационного нуля. После обнаружения каждой единицы в бите переноса, предполагаемое значение k уменьшается на 3. Анализ оканчивается при обнаружении нуля в бите переноса. Из таблицы 3.5 видно, что клавише с символом "5", действительно, присвоен номер 5.
Процедура, реализующая данный алгоритм выглядит следующим образом:
MAKENUMBER: LDA $42
DETECT: LSLA
BHS RETURN
DEC RAMStart
DEC RAMStart
DEC RAMStart
JMP DETECT
Здесь $42 – ячейка памяти, в которую предварительно засылается код, соответствующий нажатию заданной клавиши. Команда LSLA производит логический сдвиг влево содержимого регистра А по приведённой выше схеме. Ячейка памяти с именем RAMStart (обычно её адрес $40) хранит текущее значение номера клавиши k. Приведём текст программы, реализующей запись номеров нажатых клавиш и кодов, соответствующих этим нажатиям, в ячейки памяти, начиная с адреса $140.
Программа, реализующая запись номеров нажатых клавиш и кодов, соответствующих этим нажатиям, в ячейки ОЗУ, начиная с адреса $140
$Include 'gpgtregs.inc'
RAMStart EQU $0040
ROMStart EQU $8000
VectorStart EQU $FFDC
org ROMStart
*************
* Процедуры *
*************
***************************************
* Ожидание нажатия какой-либо клавиши *
***************************************
WAIT: CLRA
STA PTA
LDA PTA
CMP #$F0
BEQ WAIT
RTS
**************************************
* Ожидание окончания нажатия клавиши *
**************************************
WAIT_END_PRESSING: CLRA
STA PTA
LDA PTA
CMP #$F0
BNE WAIT_END_PRESSING
RTS
***************************************
* Формирование номера нажатой клавиши *
***************************************
MAKENUMBER: LDA $42
DETECT: LSLA
BHS RETURN
DEC RAMStart
DEC RAMStart
DEC RAMStart
JMP DETECT
*****************************************
* Анализ наличия нуля в старшей тетраде *
*****************************************
ANALYSIS: STA PTA
LDA PTA
STA $42 ;$42-хранение кода нажатой клавиши
CMP #$F0
BLO MAKENUMBER
RTS
****************************************************
* Сканирование клавиатуры, анализ получаемых кодов *
* и формирование номеров нажатых клавиш *
****************************************************
GETNUMBER: MOV #10T,RAMStart
LDA #$0C
JSR ANALYSIS
MOV #11T,RAMStart
LDA #$0A
JSR ANALYSIS
MOV #12T,RAMStart
LDA #$06
JSR ANALYSIS
RTS
***************************
* Тело основной программы *
***************************
Program_Init:
LDA CONFIG1 ;Отключение сторожевого таймера
ORA #1
STA CONFIG1
LDA #$0F ; Программирование линий порта
STA DDRA ; на ввод/вывод
MOV #$F0,PTAPUE ; подключение подтягивающих резисторов к старшей тетраде
LDHX #$140
MOV #$0C,$41
BEGIN: JSR WAIT ; ожидание нажатия клавиши
JSR GETNUMBER ; формирование номера нажатой клавиши
RETURN: LDA RAMStart
STA ,X ; пересылка
INCX ; номера и
LDA $42 ; кода нажатой
STA ,X ; клавиши в ячейки ОЗУ
INCX
JSR WAIT_END_PRESSING ; ожидание окончания нажатия клавиши
DBNZ $41,BEGIN ; декремент счётчика внешнего цикла
STOP
dummy_isr:
RTI; return
org VectorStart
dw dummy_isr; Time Base Vector
dw dummy_isr; ADC Conversion Complete
dw dummy_isr; Keyboard Vector
dw dummy_isr; SCI Transmit Vector
dw dummy_isr; SCI Receive Vector
dw dummy_isr; SCI Error Vector
dw dummy_isr; SPI Transmit Vector
dw dummy_isr; SPI Receive Vector
dw dummy_isr; TIM2 Overflow Vector
dw dummy_isr; TIM2 Channel 1 Vector
dw dummy_isr; TIM2 Channel 0 Vector
dw dummy_isr; TIM1 Overflow Vector
dw dummy_isr; TIM1 Channel 1 Vector
dw dummy_isr; TIM1 Channel 0 Vector
dw dummy_isr; ICG/CGM Vector
dw dummy_isr; ~IRQ1 Vector
dw dummy_isr; SWI Vector
dw Program_Init; Reset Vector
Приложение 2
Программа вывода на ЖКИ символьного отображения нажатой клавиши
RAMStart EQU $0040
ROMStart EQU $8000
VectorStart EQU $FFDC
$Include 'gpgtregs.inc'
LCD_CTRL EQU PORTC
LCD_DATA EQU PORTC
LCD_RS EQU 6
LCD_RW EQU 5
LCD_E EQU 4
org RAMStart
DELAYREG1 DS 1
DELAYREG2 DS 1
DELAYREG3 DS 1
TIME DS 1
org ROMStart
DDRAM_ADDRES:
ORA #$80
BCLR LCD_RS,LCD_CTRL
JSR LCD_WRITE
BSET LCD_RS,LCD_CTRL
RTS
VAR_DELAY:
LDA #33T
L6: DECA
BNE L6
DEC TIME
BNE VAR_DELAY
RTS
LCD_DELAY_40US:
PSHA ;2 CYCLES
LDA #14T ;2 CYCLES
L5: DECA ;1 CYCLE
BNE L5 ;3 CYCLES
PULA ;2 CYCLES
RTS ;4 CYCLES
***************************************************
*LCD_Write,LCD_Write_Nibble - *
***************************************************
LCD_WRITE_NIBBLE:
PSHA
AND #$0F
PSHA
SEI
LDA LCD_DATA
AND #$F0
ORA 1,SP
STA LCD_DATA
CLI
BSET LCD_E,LCD_CTRL
BCLR LCD_E,LCD_CTRL
BSR LCD_DELAY_40US
PULA
PULA
RTS
LCD_WRITE:
NSA
BSR LCD_WRITE_NIBBLE
NSA
BSR LCD_WRITE_NIBBLE
RTS
*******************************************************
*LCD_INIT - Подпрограмма инициализации дисплея *
*******************************************************
LCD_INIT:
*** Задержка 15мс
LDA #150T
STA TIME
JSR VAR_DELAY
*** Команда:выбор 8-битного режима
LDA #$03
JSR LCD_WRITE_NIBBLE
*** ЗАДЕРЖКА 4.1МС
LDA #41T
STA TIME
JSR VAR_DELAY
*** Команда:выбор 8-битного режима
LDA #$03
JSR LCD_WRITE_NIBBLE
*** Задержка 100 мкс
LDA #10
STA TIME
JSR VAR_DELAY
*** Команда :выбора 8-битного режима
LDA #$03
JSR LCD_WRITE_NIBBLE
*** Установка функций (4-битный режим обмена, 2 строки, 5x7 точек.)
LDA #$02
JSR LCD_WRITE_NIBBLE
LDA #$28
JSR LCD_WRITE
*** Управление дисплеем (дисплей-вкл,курсор-выкл,мигание курсора-выкл.)
LDA #$0C
JSR LCD_WRITE
*** Управление дисплеем (очистка дисплея,адрес курсора = 0)
LDA #$01
JSR LCD_WRITE
LDA #200T
STA TIME
JSR VAR_DELAY
*** Установка режима ввода (инкремент, без сдвига дисплея)
LDA #$06
JSR LCD_WRITE
BSET LCD_RS,LCD_CTRL
RTS
***************************************
* Ожидание нажатия какой-либо клавиши *
***************************************
WAIT: CLRA
STA PTA
LDA PTA
CMP #$F0
BEQ WAIT
RTS
**************************************
* Ожидание окончания нажатия клавиши *
**************************************
WAIT_END_PRESSING: CLRA
STA PTA
LDA PTA
CMP #$F0
BNE WAIT_END_PRESSING
RTS
***************************************
* Формирование номера нажатой клавиши *
***************************************
MAKENUMBER: LDA $42
DETECT: LSLA
BHS RETURN
DEC RAMStart
DEC RAMStart
DEC RAMStart
JMP DETECT
*****************************************
* Анализ наличия нуля в старшей тетраде *
*****************************************
ANALYSIS: STA PTA
LDA PTA
STA $42 ;$42-хранение кода нажатой клавиши
CMP #$F0
BLO MAKENUMBER
RTS
****************************************************
* Сканирование клавиатуры, анализ получаемых кодов *
* и формирование номеров нажатых клавиш *
****************************************************
GETNUMBER: MOV #10T,RAMStart
LDA #$0C
JSR ANALYSIS
MOV #11T,RAMStart
LDA #$0A
JSR ANALYSIS
MOV #12T,RAMStart
LDA #$06
JSR ANALYSIS
RTS
MAIN_INIT:
RSP
LDA CONFIG1 ;Отключение сторожевого таймера.
ORA #1
STA CONFIG1
LDA #$0F ; Программирование линий порта
STA DDRA ; на ввод/вывод
MOV #$F0,PTAPUE ; подключение подтягивающих резисторов к старшей тетраде
LDHX #$140
MOV #$0A,$41
BEGIN:
MOV #$7F,DDRC
MOV #$00,PORTC
JSR WAIT ; ожидание нажатия клавиши
JSR GETNUMBER ; формирование номера нажатой клавиши
RETURN: LDA RAMStart
STA ,X ; пересылка номера и
JSR WAIT_END_PRESSING ; ожидание окончания нажатия клавиши
JSR LCD_INIT
LDA ,X
CBEQA #0B,Nol
CBEQA #0A,ZVEZDA
CBEQA #0C,RESHETKA
ADD #$30 ;ASCII-код цифры
Next: JSR LCD_Write
LDA #$80 ; Вывод цифры с 1 позиции первой строки
JSR DDRAM_ADDRES
INCX
JMP BEGIN
STOP
Nol: LDA #30
JMP Next
ZVEZDA: lda #2A
JMP Next
RESHETKA: lda #23
JMP Next
************************
Dummy_Isr:
RTI ; Return
******************************************************************
* Область векторов прерываний. *******************************************************************
org VectorStart
dw Dummy_Isr ; Time Base Vector
dw Dummy_Isr ; ADC Conversion Complete
dw Dummy_Isr ; Keyboard Vector
dw Dummy_Isr ; SCI Transmit Vector
dw Dummy_Isr ; SCI Receive Vector
dw Dummy_Isr ; SCI Error Vector
dw Dummy_Isr ; SPI Transmit Vector
dw Dummy_Isr ; SPI Receive Vector
dw Dummy_Isr ; TIM2 Overflow Vector
dw Dummy_Isr ; TIM2 Channel 1 Vector
dw Dummy_Isr ; TIM2 Channel 0 Vector
dw Dummy_Isr ; TIM1 Overflow Vector
dw Dummy_Isr ; TIM1 Channel 1 Vector
dw Dummy_Isr ; TIM1 Channel 0 Vector
dw Dummy_Isr ; PLL Vector
dw Dummy_Isr ; ~IRQ1 Vector
dw Dummy_Isr ; SWI Vector
dw Main_Init ; Reset Vector