;************************************************* **********************************************
; scan.asm
;
PIC16F873 Кварц 4 мГц.
;================================================= ==============================================
LIST p=16F873 ; Установка типа микроконтроллера.
__CONFIG 3F71h ; Включено XT генератор ,PWRT, сброс BOR. Выключена защита ,WDT,LVP, Debug
;================================================= ==============================================
; Определение положения регистров специального назначения.
;================================================= ==============================================
Status equ 03h ; Регистр выбора банка.
TrisB equ 06h ; Регистр выбора направления работы В
TrisC equ 07h ; Регистр выбора направления работы выводов порта С.
PortB equ 06h ; Регистр управления защелками порта В.
OptionR equ 01h ; Регистр выбора работы прерываний по фронту, подключения подтягивающих резисторов
Intcon equ 0Bh ; Регистр разрешения прерываний
SSPStat equ 14h ; Регистр статуса модуля MSSP
SSPCon equ 14h ; Регистр управления модуля MSSP
SSPCon2 equ 11h ; Регистр управления модуля MSSP (б1)
SSPAdd equ 13h ; Регистр управления скоростью обмена (б1)
SSPBuf equ 13h ; Регистр передающего буфера
PIR1 equ 0Ch ; Регистр флагов прерываний от переферийных модулей
;================================================= ==============================================
; Определение названия и положения регистров общего назначения.
;================================================= ==============================================
Registr equ 21h ; Регистр сохранения данных перед записью в EEprom
W_Temp equ 22h ; Регистр сохранения W перед записью
Stat_Temp equ 23h ; Регистр сохранения данных Status перед записью
SecH equ 24h ; Старшый байт счетчика сканирования изменения уровня на R0
SecL equ 25h ; Младшый байт счетчика сканирования R0
Adr_L equ 26h ; Младший Регистр используемый для временной записи адреса записи
Adr_H equ 27h ; Старшый регистр записи адреса
CountPagL equ 28h ; Количестов байтов в одном блоке(256)
CountPagH equ 29h ; Количество блоков (32)
;================================================= ==============================================
; Определение места размещения результатов операций и бита выбора банка
;================================================= ==============================================
F equ 1 ; Результат направить в регистр
SSPIF equ 3 ; Флаг прерываний от модуля MSSP
SEN equ 0 ; Бит включения "старта"
PEN equ 2 ; Бит включения "стопа"
ACKSTAT equ 6 ; Бит подтверждения от ведомого
SMP equ 7 ; Бит управления длительностью фронта
W equ 0 ; Результат направить в W
RP0 equ 5 ; Поставить 5 биту регистра status название RP0(регстр смены банков)
;================================================= ==============================================
org 0 ; Начать выполнение программы с адреса 0 PC.
goto START ; Переход в ПП Start.
;================================================= ==============================================
org 4 ; Назначение вектора прерываний
;************************************************* **********************************************
; Текст рабочей части программы.
;************************************************* **********************************************
INT movwf W_Temp ; стандартные процедуры сохранения регистров W и Status
movf Status,W
movwf Stat_Temp
Proverk btfss PortB,1 ; Если на 2 ноге 0, то в регистр Reristr записывается число 1
goto ONE
movlw .2 ; Если нет ,то в Registr Записывается число 2
movwf Registr
goto WRITE ; Собственно переходим к записи во внешний еепром
ONE movlw .1
movwf Registr
goto WRITE
WRITE bcf PIR1,SSPIF ; Сброс флага прерываний от модуля MSSP
bsf Status,RP0 ; Переход в первый банк
bsf SSPCon2,SEN ; Начало формирования условия "Старт"
bcf Status,RP0 ; Переход в нулевой банк
btfss PIR1,SSPIF ; Формирование условия старт завершено или нет?
goto $-1 ; Если нет-то ожидание, если да-то далее
;*************************Режимный байт**********************************
movlw b'10100000' ; Режимный байт 1010 код функциональности 000 адрес микрухи,0 режим записи
call WR_I2C
;*****************************Старшый байт адреса**************************
movf Adr_H,W ; Записываем в W первый(старшый байт адреса)
call WR_I2C
;***********************Младшый байт адреса********************************
movf Adr_L,W ; Записываем в W младший байт адреса
call WR_I2C
;*************************Байт данных**************************************
movf Registr,W ; Записываем в W содержание Registr
call WR_I2C
;*********************Стоп условие****************************
bcf PIR1,SSPIF ; Сброс флага прерываний от модуля MSSP
bsf Status,RP0 ; Переход в 1 банк
bsf SSPCon2,PEN ; начало формирования условия стоп
bcf Status,RP0 ; переход в 0 банк
btfss PIR1,SSPIF ; Формирование условия завершено??
goto $-1 ; Нет-снова проверяем флаг, да- далее
;******************Изменнеие битов адреса************************
incf Adr_L,F ; Увеличиваем младший бит адреса на 1
decfsz CountPagL ; Уменьшаем кол-во байтов в блоке на 1 , если результат не 0, то на завершение пррывания (EndInt)
goto EndInt
clrf Adr_L ; Если 0 (блок записан), то обнуляем младший счетчик адресов.
movlw .255 ; Записываем 255 в счетчик кол-ва байт в блоке
movwf CountPagL
incf Adr_H,F ; Увеличиваем старшый адресс на 1
decfsz CountPagH,F ; Уменьшаем на 1 кол-во блоков
goto EndInt ; Если не 0, то на завершение ПП Прерывания
goto $ ; Если 0-вечное кольцо
;*******************Выход из ПП прерываний*****************************
EndInt bcf Intcon,1 ; Сброс флага прерываний
movf Stat_Temp,W ; Стандартная процедура возврата содержимого
movwf Status
swapf W_Temp,F
swapf W_Temp,W
retfie
POVTOR bcf Status,RP0
WR_I2C movwf SSPBuf ; Закрузка в буфер байта для записи
bcf PIR1,SSPIF ; Сброс флага прерываний
btfss PIR1,SSPIF ; Флаг поднялся(запись окончена)?
goto $-1 ;Нет-ожидание, да- дальше
;*************************анализ АСК*************************
bsf Status,RP0 ; Первый банк
btfsc SSPCon2,ACKSTAT ; Подтверждение от ведомого принято?
goto POVTOR ; Нет- повтор, да -далее
bcf Status,RP0 ; Переход в 0 банк
return ; возврат по стеку
START clrf Intcon ; Запрещаем все прерывания
bsf Status,RP0 ; Первый банк
movlw .7 ; записываем в W число 0000 0111
movwf TrisB ; Соответсвенно RB0, RB1, RB2 работают на вход.
movlw .255 ; Записываем в W число 1111 1111
movwf TrisC ; Все порты С на вход (можно не писать по умолчанию все стоят на вход)
movlw .128 ; Записываем в W 0100 0000
movwf OptionR ; !!Преывания по переднему фронту 0/1 включены!!
movlw .9 ; Установка стандартной скорости обмена
movwf SSPAdd ; Скрость равна 100 Кгц
bsf SSPStat,SMP ; управление длительностью фронта выключено
bcf Status,RP0 ; переход в нулевой банк
movlw b'00101000' ; Включение модуля MSSP
movwf SSPCon ; ---!!---
movlw .255 ; Задание колличества битов в блоке
movwf CountPagL
movlw .32 ; Задание кол-ва блоков
movwf CountPagH
clrf Adr_L ; Очистить младший байт адреса ( с нулевого начнется запись)
clrf Adr_H ; Очистить старшый байт адреса ( с нулевого начнется запись)
Pause movlw .1 ; закладываю паузы для ожидания прерываний. Все взял из программы Евгения Александровича
movwf SecH
movlw .255
movwf SecL
;************************************************* ***********************************************
movlw .144
movwf Intcon ; Записываю число 1001 0000( разрешаю глобальные и прерывания по RB0)
Pause1 decfsz SecL,F ; Собственно ожидаю этого прерывания
goto Pause1
Pause2 incfsz SecH,F
goto Pause2
goto Pause ; Если прерывания не произошло то снова закладываем паузы и ждем
end