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