M2: MOV A,R7 ;Формирование последнего знакоместа
MOV dptr,#N_mas ;т. к. данный разряд является одновременно
MOVC A,@A+dptr ;и смещением на соответствующую битовую ;комбинацию и
MOV @R1,A ;сохранение этой комбинации в ;соответствующую знакоместу ячейку памяти
;инициализация таймера для работы от прерывания
MOV TH0,#high(65;установка отсчета (ст. байт)
MOV TL0,#low(65;таймером времени 6 мс (мл. байт)
SETB TR0 ;Запуск таймера 0
MOV R1,#Razr ;Загрузка начального адреса
MOV R2,#Addr ;массива битовых комбинаций знакомест
MOV R4,#0
RET
;Функция для пересылки данных на ЦАП
DAC_SEND:
;Подготовка данных для отправки
MOV R1,#BUF1
MOV R5,@R1
MOV R1,#BUF2
MOV R6,@R1
MOV IE,#B ;Запрет прерываний Т0,Т1
ST_I2C:
CALL I2CStart
MOV A,#B ;Адрес ЦАПа (у нас одно устройство I2C) CALL I2COutPut ;Передача адреса ЦАПа по I2C
CALL I2CErrorOut ;Подтверждение от ЦАПа
JC ST_I2C ;Если низкого уровня, то все нормально
MOV A,R5 ;Старший байт Q4
CALL I2COutPut
CALL I2CErrorOut
JC ST_I2C
MOV A,R6 ;Младший байт Q4
CALL I2COutPut
CALL I2CErrorOut
JC ST_I2C
CALL I2CStop
MOV IE,#B ;Разрешение всех прерываний
RET
;Функция начала передачи
I2CStart:
SETB SDA ;установка данных
NOP
SETB SCL ;установка синхросигнала
NOP
CLR SDA ;установка сигнала начала передачи
NOP
CLR SCL ;сброс синхросигнала
NOP
RET
;Функция конца передачи
I2CStop:
CLR SDA
NOP
SETB SCL ;установка синхросигнала
NOP
NOP
SETB SDA ;установка сигнала данных
NOP
NOP
RET
;Функция передачи данных из микроконтроллера в ЦАП
I2COutPut:
MOV R1,#8 ;размер считываемого фрагмента байт
SEN:
RLC A ;перенос старшего байта А в С для передачи
MOV SDA, C ;передача бита
NOP
SETB SCL ;установка синхросигнала
NOP
NOP
CLR SCL ;сброс синхросигнала
NOP
DJNZ R1,SEN ;повтор 8 раз
RET
;Функция подтверждения приема данных ЦАПом
I2CErrorOut:
NOP
SETB SCL ;установка синхросигнала
NOP
NOP
MOV C, SDA ;прием бита подтверждения приема
CLR SCL ;сброс синхросигнала
NOP
RET
;Обработчик прерывания от таймера 0 (вывод на индикаторы)
INT_SV: ;Обработчик прерывания от таймера 0
CLR TR0 ;Остановка таймера 0
MOV A,@R1
MOV R3,@R2
MOV dptr,R3 ;адрес 1ого индикатора
MOVX @dptr, A ;кода выбора
MOV TH0,#high(65;установка отсчета (ст. байт)
MOV TL0,#low(65;таймером времени 6 мс (мл. байт)
SETB TR0 ;Запуск таймера 0
INC R1 ;Смещение адреса массива битовых ;комбинаций на след. комбинацию
INC R2 ;Смещение на след. адрес индикатора
INC R4 ;Считаем кол-во индикаторов
CJNE R4,3,IN1 ;Если был вывод на все индикаторы, то ;инициализация снова
MOV R1,#Razr
MOV R2,#Addr
MOV R4,#0
IN1:
RETI ;Возврат из обработчика прерывания
;Обработчик прерывания от аварийного датчика (ALARM)
INT1_DAT:
MOV IE, # ;Маскирование всех прерываний, кроме
;прерываний от таймера Т2(0.5 с) и от ;таймера Т0 (индикация для вывода Q4)
MOV R1,#BUF1 ;Из памяти считываем значение Q4
MOV R6,@R1
MOV R1,#BUF2
MOV R7,@R1
ACALL Q4_OUT ;Выводим текущее значение Q4
SETB TR1 ;запускаем таймер 1 для отсчета времени ;для звуковой сигнализации
ALARM:
;вывод сигнала аварийной звуковой сигнализации с частотой 500 Гц
;f = 500 Гц, Т = 2 мс
;2 мс = 2 мкс * 1000 - период аварийной сигнализации
;1000 – число, которое необходимо отсчитать таймеру до
;переполнения для формирования периода 2 мс
;1000 = 3E8h, FFFFh – 3E8h = FC17h
;загружаем регистры таймера
MOV TMOD,#B ;Режим 1 - таймер Т0 и режим 1 - Т1
MOV TH1, #high(0FC17h)
MOV TL1, #low(0FC17h)
CPL P1.0 ;включение/выключение аварийного ;сигнала
CJNE TF1, #1, $ ;ждем переполнения таймера
JMP ALARM ;переход на начало цикла аварийной ;сигнализации
;Выход из подпрограммы обработки аварийного прерывания - только по ;сбросу
;Обработка прерывания по сигналу отказа источника питания
INT2_P:
MOV C, P3.0
JNC PIT
ACALL INT3_K
RETI
PIT:
PUSH ACC ;Cохраняем аккумулятор в стек
PUSH R0 ;Cохраняем регистр R0 в стек
PUSH R1 ;Cохраняем регистр R1 в стек
;Cохраняем регистры специальных функций
MOV R0, 0F0h ;Адрес регистра с самым старшим адресом (B)
MOV R1, 0F0h ;Адрес во внешнем ОЗУ
SAVE_SFR:
MOV A, @R0 ;В аккумулятор заносим регистры, начиная с ;регистра В
MOVX @R1, A ;Заносим регистр из аккумулятора во внешнее
;энергонезависимое ОЗУ по тому же адресу
DEC R0 ;Уменьшаем адрес внешнего ОЗУ
DEC R1 ;Уменьшаем адрес копируемого регистра
CJNE R1,#7Fh, SAVE_SFR ;Проверка: все ли SFR сохранены
;Сохраняем четыре банка регистров R0 - R7
MOV R0, 1Fh ;Адрес регистра R7 из 3 банка регистров
MOV R1, 1Fh ;Адрес во внешнем ОЗУ
SAVE_Rx:
MOV A, @R0 ;В аккумулятор заносим регистры, начиная с ;R7 (банк 3)
MOVX @R1, A ;Заносим регистр из аккумулятора во внешнее
;энергонезависимое ОЗУ по тому же адресу
DEC R0 ;Уменьшаем адрес внешнего ОЗУ
DJNZ R1, SAVE_Rx ;Уменьшаем адрес копируемого регистра
;Сохраняем аккумулятор, а также R0 и R1 (банк 0)
;В ОЗУ сохранены не те значения A, R0 и R1, т. к. они менялись в ;подпрограмме
PUSH DPTR
POP R1 ;Извлекаем R1 из стека
MOV A, R1 ;Помещаем R1 в аккумулятор
MOV DPTR, #1 ;Задаем в DPTR адрес R1 во внешнем ОЗУ
MOVX @DPTR, A ;Сохраняем R1
POP R0 ;Извлекаем R0 из стека
MOV A, R0 ;Помещаем R0 в аккумулятор
MOV DPTR, #0 ;Задаем в DPTR адрес R0 во внешнем ОЗУ
MOVX @DPTR, A ;Сохраняем R0
POP ACC ;Извлекаем аккумулятор из стека
MOV DPTR, #0E0h ;Задаем адрес аккумулятора во внешней памяти
MOVX @R1, A ;Сохраняем аккумулятор во внешнее ОЗУ
POP DPTR
RETI
;Обработчик прерывания от таймера 2 (счет 0.5 с)
INT_UPR:
CLR TF2 ;сброс бита переполнения
MOV R5,#T2_I ;Т2_I – индекс циклов счета
MOV R4,#T2_K ;Т2_К – флаг окончания цикла управления
MOV R6,@R5 ;если Т2_К=1, то прошло 0.5 с
MOV R3,@R4
INC R6
MOV @R5,R6
CJNE R6,#5,UPR1 ;если Т2_I=5, то T2_K=1
MOV R3,#1
MOV @R4,R3
UPR1:
SETB TR2 ;новый счет 100 мс
RETI
;Обработчик прерывания от таймера 1 (реализация синхросигнала SCL, необходимого для ЦАПа, а также опрос линий клавиатуры)
INT_SCL:
CLR TF0 ;Сброс бита переполнения
SETB TR1 ;новый счет таймера 1
CPL SCL ;инвертируем вывод SCL процессора
RETI
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |


