• Название:

    часы


  • Размер: 0.03 Мб
  • Формат: ODT
  • или
  • Сообщить о нарушении / Abuse

Установите безопасный браузер



  • #include <P16F628A.INC>

  • LIST p=16F628A

  • __CONFIG H'3F10' ;Конфигурация микроконтроллера

  • errorlevel -302 ;не выводить сообщения с ошибкой 302 в листинге

  • Sec equ 0020h ;вспомогательные регистры счета

  • Sec1 equ 0021h ;

  • Sec2 equ 0022h ;

  • scetbit equ 0024h ;вспомогательный регистр счета кол-ва бит

  • perem equ 0025h ;вспомогательный регистр приема/передачи байта по spi, i2c

  • temp equ 0026h ;регистр температуры

  • perem_1 equ 0027h ;вспомогательный регистр двоично-десятичного преобр.

  • result equ 0028h ;вспомогательный регистр двоично-десятичного преобр.

  • dat_ind equ 0029h ;регистр данных для передачи по протоколу spi

  • adr_ind equ 002Ah ;регистр адреса для передачи по протоколу spi

  • second equ 002Bh ;регистр хранения секунд для установки времени

  • minut equ 002Ch ;регистр хранения минут для установки времени

  • hour equ 002Dh ;регистр хранения часов для установки времени

  • adr_i2c equ 002Eh ;регистры подпрограммы передачи данных интерфейса i2c

  • tmp_i2c equ 002Fh

  • slave_adr equ 0030h

  • data_i2c equ 0031h

  • flag equ 007Fh ;регистр флагов

  • #DEFINE int PORTB,0 ;линия прерывания INT/SQW DS3231

  • #DEFINE sda PORTB,1 ;линия SDA для подключения DS3231

  • #DEFINE scl PORTB,2 ;линия SCL для подключения DS3231

  • #DEFINE sda_io TRISB,1 ;направление линии SDA

  • #DEFINE scl_io TRISB,2 ;направление линии SCL

  • #DEFINE datai PORTB,5 ;линия входа данных драйвера MAX7219

  • #DEFINE cs PORTB,6 ;линия выбора драйвера MAX7219

  • #DEFINE clk PORTB,7 ;линия тактирования драйвера MAX7219

  • #DEFINE led PORTB,4 ;светодиод ошибки i2c

  • #DEFINE led_sec PORTB,3 ;светодиод индикации хода часов 1Гц

  • #DEFINE regim PORTA,2 ;кнопка Индикация - смены режима индикации

  • #DEFINE nast PORTA,3 ;кнопка Настройка - входа в режим настройки времени

  • #DEFINE ust PORTA,4 ;кнопка Установка - установка значения часов

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • org 0000h ;начать выполнение программы с адреса 0000h

  • goto Start ;переход на метку Start

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • ;Основная программа

  • Start movlw b'00000000' ;установка значений выходных защелок порта A

  • movwf PORTA ;

  • movlw b'01000000' ;установка значений выходных защелок порта B

  • movwf PORTB ;

  • movlw b'00000111' ;выключение компараторов

  • movwf CMCON ;

  • bsf STATUS,RP0 ;выбрать 1-й банк

  • movlw b'00000111' ;настройка линий ввода\вывода порта B

  • movwf TRISB ;RB0-RB2 - на вход, остальные на выход

  • movlw b'11111111' ;настройка линий ввода\вывода порта A

  • movwf TRISA ;все линии на вход

  • bcf STATUS,RP0 ;выбрать 0-й банк

  • clrf flag ;сброс регистра флагов

  • call init_lcd ;вызов подпрограммы инициализации драйвера (MAX7219)

  • call viv_not ;вывод на индикаторы символов тире " ------ "

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • movlw b'11010000' ;адрес устройства (DS3231)

  • movwf slave_adr

  • ;Запись 4-х байт в регистры приема/передачи по i2c

  • ;здесь выполняется настройка 1-го будильника, сигнал каждую секунду

  • movlw data_i2c ;установка первого регистра приема/передачи по i2c

  • movwf FSR ;

  • movlw b'10000000' ;данные для регистра секунд 1-го будильника

  • movwf INDF ;

  • incf FSR,F ;

  • movlw b'10000000' ;данные для регистра минут 1-го будильника

  • movwf INDF ;

  • incf FSR,F ;

  • movlw b'10000000' ;данные для регистра часов 1-го будильника

  • movwf INDF ;

  • incf FSR,F ;

  • movlw b'10000000' ;данные для регистра даты/дня недели 1-го будильника

  • movwf INDF ;

  • movlw .4 ;передача 4-х байта по i2c

  • movwf tmp_i2c ;

  • movlw 0x07 ;установка адреса регистра секунд 1-го будильника

  • movwf adr_i2c ;

  • call write_i2c ;вызов подпрограммы записи по интерфейсу i2c

  • call err_prov ;проверка на ошибки записи/чтения I2C

  • movlw .1 ;передача 1-го байта по i2c

  • movwf tmp_i2c ;

  • movlw 0x0E ;установка адреса регистра Control

  • movwf adr_i2c ;

  • movlw data_i2c ;установка первого регистра приема/передачи по i2c

  • movwf FSR ;

  • movlw b'00000101' ;запуск тактового генератора, запрет функционирования вывода INT/SQW для

  • movwf INDF ;режима питания от батареи, частота импульсов на выходе INT/SQW 1Гц,

  • ;выход INT/SQW задействован для генерации прерываний по будильнику,

  • ;разрешение прерываний по 1-му будильнику

  • call write_i2c ;вызов подпрограммы записи по интерфейсу i2c

  • call err_prov ;проверка на ошибки записи/чтения I2C

  • met_2 movlw .1 ;передача 1-го байта по i2c

  • movwf tmp_i2c ;

  • movlw 0x0F ;установка адреса регистра Status

  • movwf adr_i2c ;

  • movlw data_i2c ;установка первого регистра приема/передачи по i2c

  • movwf FSR ;

  • movlw b'00000000' ;сброс бита OSF, запрет генерирования импульсов на выходе EN32kHz,

  • movwf INDF ;сброс флагов прерываний будильников A2F, A1F

  • call write_i2c ;вызов подпрограммы записи по интерфейсу i2c

  • call err_prov ;проверка на ошибки записи/чтения I2C

  • met_1 btfsc int ;опрос линии прерывания будильника

  • goto met_3 ;

  • bsf led_sec ;включение светодиода индикации хода часов

  • goto met_4 ;

  • met_3 bcf led_sec ;выключение светодиода индикации хода часов

  • btfsc nast ;опрос кнопки настройки часов

  • goto met_5 ;

  • call nast_time ;вызов подпрограммы установки времени

  • goto met_2 ;

  • met_5 btfsc regim ;опрос кнопки режима индикации

  • goto met_1 ;

  • met_6 call paus_knp ;

  • btfss regim ;

  • goto met_6 ;

  • btfss flag,2 ;изменение значения флага режима индикации

  • goto met_7 ;

  • bcf flag,2 ;сброс флага индикации, режим отображения часов

  • goto met_1 ;

  • met_7 bsf flag,2 ;установка флага индикации, режим отображения температуры и часов

  • goto met_1 ;

  • met_4 movlw .1 ;передача 1-го байта по i2c

  • movwf tmp_i2c ;

  • movlw 0x11 ;установка адреса старшего регистра температуры

  • movwf adr_i2c ;

  • call read_i2c ;вызов подпрограммы чтения по I2C

  • call err_prov ;проверка на ошибки записи/чтения I2C

  • movf INDF,W ;копирование значения температуры в регистр temp

  • movwf temp

  • rd_time movlw .3 ;передача 3-х байт по i2c

  • movwf tmp_i2c ;

  • movlw 0x00 ;установка адреса регистра секунд

  • movwf adr_i2c ;

  • call read_i2c ;вызов подпрограммы чтения по I2C

  • call err_prov ;проверка на ошибки записи/чтения I2C

  • btfsc flag,2 ;опрос флага режима индикации

  • goto met_8 ;

  • call vivod ;вызов подпрограммы вывода значения часов на цифровое табло

  • goto met_2 ;

  • met_8 call vivod_temp ;вызов подпрограммы вывода температуры и часов на цифровое табло

  • goto met_2

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • vivod movlw data_i2c ;установка первого регистра приема/передачи по i2c

  • movwf FSR ;

  • movlw 0x01 ;вывод единиц секунд на 1-й индикатор

  • movwf adr_ind ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x02 ;вывод десятков секунд на 2-й индикатор

  • movwf adr_ind ;

  • swapf INDF,F ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • call send ;

  • incf FSR,F ;выбор регистра хранения минут

  • movlw 0x03 ;вывод единиц минут на 3-й индикатор

  • movwf adr_ind ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • bsf dat_ind,7 ;установка точки разделителя минут и секунд

  • call send ;

  • movlw 0x04 ;вывод десятков минут на 4-й индикатор

  • movwf adr_ind ;

  • swapf INDF,F ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • call send ;

  • incf FSR,F ;выбор регистра хранения часов

  • movlw 0x05 ;вывод единиц часов на 5-й индикатор

  • movwf adr_ind ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • bsf dat_ind,7 ;установка точки разделителя часов и минут

  • call send ;

  • movlw 0x06 ;вывод десятков часов на 6-й индикатор

  • movwf adr_ind ;

  • swapf INDF,F ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x07 ;очистка 7-го индикатора

  • movwf adr_ind ;

  • movlw 0x0F ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x08 ;очистка 8-го индикатора

  • movwf adr_ind ;

  • movlw 0x0F ;

  • movwf dat_ind ;

  • call send ;

  • return

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • vivod_temp movlw data_i2c ;установка первого регистра приема/передачи по i2c

  • movwf FSR ;

  • incf FSR,F ;выбор регистра хранения минут

  • movlw 0x01 ;вывод единиц минут на 1-й индикатор

  • movwf adr_ind ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x02 ;вывод десятков минут на 2-й индикатор

  • movwf adr_ind ;

  • swapf INDF,F ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • call send ;

  • incf FSR,F ;выбор регистра хранения часов

  • movlw 0x03 ;вывод единиц часов на 3-й индикатор

  • movwf adr_ind ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • btfss flag,0 ;мигание разделителя часов и минут

  • goto viv_1 ;

  • bcf dat_ind,7 ;

  • bcf flag,0 ;

  • goto viv_2 ;

  • viv_1 bsf dat_ind,7 ;

  • bsf flag,0 ;

  • viv_2 call send ;

  • movlw 0x04 ;вывод десятков часов на 4-й индикатор

  • movwf adr_ind ;

  • swapf INDF,F ;

  • movlw b'00001111' ;

  • andwf INDF,W ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x05 ;очистка 5-го индикатора

  • movwf adr_ind ;

  • movlw 0x0F ;

  • movwf dat_ind ;

  • call send ;

  • bcf flag,1 ;сброс флага отриц температуры

  • btfss temp,7 ;проверка отрицательной температуры

  • goto viv_3 ;

  • comf temp,F ;

  • incf temp,F ;

  • bsf flag,1 ;установка флага отриц температуры

  • viv_3 movf temp,W ;

  • call bin2bcd ;вызов подпрограммы преобразования десятичного

  • ;числа в двоично-десятичное

  • movlw b'00001111' ;вывод разряда единиц температуры

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x06 ;

  • movwf adr_ind ;

  • call send ;

  • swapf result,F ;вывод разряда десятков температуры

  • movlw b'00001111' ;

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x07 ;

  • movwf adr_ind ;

  • call send ;

  • btfsc flag,1 ;опрос флага знака температуры

  • goto viv_4 ;

  • movlw 0x08 ;очистка 8-го индикатора

  • movwf adr_ind ;

  • movlw 0x0F ;

  • movwf dat_ind ;

  • call send ;

  • return

  • viv_4 movlw 0x08 ;вывод тире на 8-й индикатор

  • movwf adr_ind ;

  • movlw 0x0A ;

  • movwf dat_ind ;

  • call send ;

  • return

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • nast_time call paus_knp ;ожидание отпускания кнопки настройки часов

  • btfss nast ;

  • goto nast_time ;

  • call viv_not ;вывод на индикаторы символов тире " ------ "

  • clrf hour ;очистка регистров хранения времени

  • clrf minut ;

  • clrf second ;

  • nst_a1 movf hour,W ;

  • call bin2bcd ;

  • movlw b'00001111' ;вывод разряда единиц часов

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x05 ;

  • movwf adr_ind ;

  • bsf dat_ind,7 ;

  • call send ;

  • swapf result,F ;вывод разряда десятков часов

  • movlw b'00001111' ;

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x06 ;

  • movwf adr_ind ;

  • call send ;

  • nst_a3 btfsc ust ;опрос кнопки Установка

  • goto nst_a2 ;

  • call paus_ust ;инкремент значения часов

  • incf hour,F ;

  • movlw .24 ;

  • xorwf hour,W ;

  • btfsc STATUS,Z ;

  • clrf hour ;

  • goto nst_a1 ;

  • nst_a2 btfsc nast ;опрос кнопки Настройка

  • goto nst_a3 ;

  • nst_a4 call paus_knp ;

  • btfss nast ;

  • goto nst_a4 ;

  • nst_b1 movf minut,W ;

  • call bin2bcd ;

  • movlw b'00001111' ;вывод разряда единиц минут

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x03 ;

  • movwf adr_ind ;

  • bsf dat_ind,7 ;

  • call send ;

  • swapf result,F ;вывод разряда десятков минут

  • movlw b'00001111' ;

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x04 ;

  • movwf adr_ind ;

  • call send ;

  • nst_b3 btfsc ust ;опрос кнопки Установка

  • goto nst_b2 ;

  • call paus_ust ;инкремент значения минут

  • incf minut,F ;

  • movlw .60 ;

  • xorwf minut,W ;

  • btfsc STATUS,Z ;

  • clrf minut ;

  • goto nst_b1 ;

  • nst_b2 btfsc nast ;опрос кнопки Настройка

  • goto nst_b3 ;

  • nst_b4 call paus_knp ;

  • btfss nast ;

  • goto nst_b4 ;

  • nst_c1 movf second,W ;

  • call bin2bcd ;

  • movlw b'00001111' ;вывод разряда единиц секунд

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x01 ;

  • movwf adr_ind ;

  • call send ;

  • swapf result,F ;вывод разряда десятков сеекунд

  • movlw b'00001111' ;

  • andwf result,W ;

  • movwf dat_ind ;

  • movlw 0x02 ;

  • movwf adr_ind ;

  • call send ;

  • nst_c3 btfsc ust ;опрос кнопки Установка

  • goto nst_c2 ;

  • call paus_ust ;инкремент значения секунд

  • incf second,F ;

  • movlw .60 ;

  • xorwf second,W ;

  • btfsc STATUS,Z ;

  • clrf second ;

  • goto nst_c1 ;

  • nst_c2 btfsc nast ;опрос кнопки Настройка

  • goto nst_c3 ;

  • nst_c4 call paus_knp ;

  • btfss nast ;

  • goto nst_c4 ;

  • movlw data_i2c ;установка первого регистра приема/передачи по i2c

  • movwf FSR ;преобразования значений часов, минут, секунд

  • movf second,W ;в двоично-десятичные

  • call bin2bcd ;

  • movf result,W ;

  • movwf INDF ;

  • incf FSR,F ;

  • movf minut,W ;

  • call bin2bcd ;

  • movf result,W ;

  • movwf INDF ;

  • incf FSR,F ;

  • movf hour,W ;

  • call bin2bcd ;

  • movf result,W ;

  • movwf INDF ;

  • ;запись нового значения времени

  • movlw .3 ;передача 3-х байт по i2c

  • movwf tmp_i2c ;

  • movlw 0x00 ;установка адреса регистра счета секунд

  • movwf adr_i2c ;

  • call write_i2c ;вызов подпрограммы записи по интерфейсу i2c

  • call err_prov ;проверка на ошибки записи/чтения I2C

  • return

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • err_prov btfss flag,6 ;проверка ошибок передачи данных I2C

  • return ;нет ошибок: выход из подпрограммы

  • err_1 bsf led ;ошибка: включить светодиод led

  • goto err_1 ;переход на метку err_1: зацикливание программы

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • ;Подпрограмма вывода символов тире на 1-6 индикаторы, очистка 7,8 индикатора

  • viv_not movlw 0x08 ;очистка 8-го индикатора

  • movwf adr_ind ;

  • movlw 0x0F ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x07 ;очистка 7-го индикатора

  • movwf adr_ind ;

  • movlw 0x0F ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x06 ;вывод тире на 6-й индикатор

  • movwf adr_ind ;

  • movlw 0x0A ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x05 ;вывод тире на 5-й индикатор

  • movwf adr_ind ;

  • movlw 0x0A ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x04 ;вывод тире на 4-й индикатор

  • movwf adr_ind ;

  • movlw 0x0A ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x03 ;вывод тире на 3-й индикатор

  • movwf adr_ind ;

  • movlw 0x0A ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x02 ;вывод тире на 2-й индикатор

  • movwf adr_ind ;

  • movlw 0x0A ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x01 ;вывод тире на 1-й индикатор

  • movwf adr_ind ;

  • movlw 0x0A ;

  • movwf dat_ind ;

  • call send ;

  • return ;выход из подпрограммы

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • ;Подпрограмма инициализации драйвера(MAX7219) цифрового табло

  • init_lcd call pauslcd ;вызов подпрограммы паузы 2 мс

  • movlw 0x0F ;выключить тестовый режим

  • movwf adr_ind ;

  • movlw 0x00 ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x0C ;включение индикатора

  • movwf adr_ind ;

  • movlw 0x01 ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x0A ;интенсивность 15/32

  • movwf adr_ind ;

  • movlw 0x07 ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x09 ;использовать BCD Code B для всех индикаторов

  • movwf adr_ind ;

  • movlw 0xFF ;

  • movwf dat_ind ;

  • call send ;

  • movlw 0x0B ;использовать 8 индикаторов

  • movwf adr_ind ;

  • movlw 0x07 ;

  • movwf dat_ind ;

  • call send ;

  • return ;выход из подпрограммы

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • ;Подпрограмма отправки 2-х байт на драйвер (MAX7219) цифрового табло по пртоколу SPI

  • send bcf cs ;Сбросить линию выбора драйвера CS

  • movlw .8 ;Отправка содержимого адресного байта adr_ind

  • movwf scetbit ;

  • povtor bcf clk ;

  • btfsc adr_ind,7 ;

  • bsf datai ;

  • btfss adr_ind,7 ;

  • bcf datai ;

  • bsf clk ;

  • rlf adr_ind,F ;

  • decfsz scetbit,F ;

  • goto povtor ;

  • movlw .8 ;Отправка содержимого байта данных dat_ind

  • movwf scetbit ;

  • povtr1 bcf clk ;

  • btfsc dat_ind,7 ;

  • bsf datai ;

  • btfss dat_ind,7 ;

  • bcf datai ;

  • bsf clk ;

  • rlf dat_ind,F ;

  • decfsz scetbit,F ;

  • goto povtr1 ;

  • bcf clk ;

  • bsf cs ;установить в 1 линию выбора драйвера CS

  • return ;выход из подпрограммы

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • ;подпрограмма преобразования двоичного числа в двоично-десятичное

  • ;результат в регистре result

  • bin2bcd movwf perem_1 ; загружаем число в ячейку единиц

  • ; делим число на 10 - получим десятки

  • d_10 clrf result

  • movlw .10

  • bcf STATUS,C

  • d_10_cikl subwf perem_1,F ; вычитаем из преобразуемого числа 10

  • btfss STATUS,C

  • goto dd_ed ; перенос (результат отрицательный),

  • ; прекращаем вычитание пререноса нет

  • incf result,F ; увеличиваем на 1 регистр десятков

  • goto d_10_cikl

  • dd_ed addwf perem_1,F ; прибавив 10, получим единицы

  • movlw .4

  • movwf scetbit

  • swapf perem_1,F

  • dd1 rlf perem_1,F

  • rlf result,F

  • decfsz scetbit,F

  • goto dd1

  • return

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • ;подпрограмма чтения/записи по интерфейсу I2C

  • write_i2c bsf flag,4 ;установка флага записи

  • goto i2c_1 ;переход на метку i2c_1

  • read_i2c bcf flag,4 ;сброс флага (для чтения)

  • bcf flag,5 ;сброс окончания приема данных

  • i2c_1 bcf flag,6 ;сброс флага ошибки I2C

  • call starti2c ;вызов подпрограммы "Старт" для I2C

  • bcf slave_adr,0 ;бит на запись

  • movf slave_adr,W ;копируем адрес ведомого

  • call peredi2c ;передача байта

  • btfsc flag,6 ;проверка флага ошибки

  • goto err_i2c ;ошибка:переход на метку err_i2c

  • movf adr_i2c,W ;адреса необходимого регистра DS3231

  • call peredi2c ;передача байта

  • btfsc flag,6 ;проверка флага ошибки

  • goto err_i2c ;ошибка:переход на метку err_i2c

  • movlw data_i2c

  • movwf FSR

  • decf FSR,F

  • btfss flag,4 ;проверка флага запись/чтение I2C

  • goto rd_i2c ;переход на метку rd_i2c (чтение)

  • i2c_2 incf FSR,F

  • movf INDF,W ;передача старшего байта данных

  • call peredi2c ;передача байта по I2C

  • btfsc flag,6 ;проверка флага ошибки

  • goto err_i2c ;ошибка:переход на метку err_i2c

  • decfsz tmp_i2c,F

  • goto i2c_2

  • call stopi2c

  • return

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • rd_i2c call starti2c ;вызов подпрограммы (повторный Старт)

  • bsf slave_adr,0 ;бит на чтение

  • movf slave_adr,W ;копируем адрес ведомого

  • call peredi2c ;передача байта

  • btfsc flag,6 ;проверка флага ошибки

  • goto err_i2c ;ошибка:переход на метку err_i2c

  • rd_i2c_2 decfsz tmp_i2c,F

  • goto rd_i2c_1

  • bsf flag,5

  • rd_i2c_1 incf FSR,F

  • call priemi2c ;прием байта

  • movwf INDF

  • movlw .0

  • xorwf tmp_i2c,F

  • btfss STATUS,Z

  • goto rd_i2c_2

  • call stopi2c ;передача стоп

  • return

  • err_i2c call stopi2c ;вызов подпрограммы "Стоп" для I2C

  • return ;выход после двух неудачных попыток передачи данных по I2C

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • starti2c call scl_1 ;отпустить линию scl

  • call pausi2c ;пауза I2C (5 мкс)

  • call sda_0 ;притянуть к 0 линию sda

  • call pausi2c ;пауза I2C (5 мкс)

  • call scl_0 ;притянуть к 0 линию scl

  • call pausi2c ;пауза I2C (5 мкс)

  • return ;возврат из подпрограммы

  • stopi2c call sda_0 ;притянуть к 0 линию sda

  • call pausi2c ;пауза I2C (5 мкс)

  • call scl_1 ;отпустить линию scl

  • stpi2c_1 call pausi2c ;пауза I2C (5 мкс)

  • btfss scl ;

  • goto stpi2c_1 ;

  • call sda_1 ;отпустить линию sda

  • call pausi2c ;пауза I2C (5 мкс)

  • return ;возврат из подпрограммы

  • sda_1 bsf STATUS,RP0 ;перенастройка линии sda на вход

  • bsf sda_io ;

  • bcf STATUS,RP0 ;

  • return ;возврат из подпрограммы

  • sda_0 bcf sda ;перенастройка линии sda на выход

  • bsf STATUS,RP0 ;

  • bcf sda_io ;

  • bcf STATUS,RP0 ;

  • return ;возврат из подпрограммы

  • scl_1 bsf STATUS,RP0 ;перенастройка линии scl на вход

  • bsf scl_io ;

  • bcf STATUS,RP0 ;

  • return ;возврат из подпрограммы

  • scl_0 bcf scl ;перенастройка линии scl на выход

  • bsf STATUS,RP0 ;

  • bcf scl_io ;

  • bcf STATUS,RP0 ;

  • return ;возврат из подпрограммы

  • peredi2c movwf perem ;подпрограмма передачи байта по i2c

  • movlw .8 ;

  • movwf scetbit ;

  • prd_i2c_1 btfsc perem,7 ;

  • call sda_1 ;отпустить линию sda

  • btfss perem,7 ;

  • call sda_0 ;притянуть к 0 линию sda

  • call scl_1 ;отпустить линию scl

  • prd_i2c_2 call pausi2c ;пауза I2C (5 мкс)

  • btfss scl ;

  • goto prd_i2c_2 ;

  • call scl_0 ;притянуть к 0 линию scl

  • call pausi2c ;пауза I2C (5 мкс)

  • rlf perem,F ;

  • decfsz scetbit,F ;

  • goto prd_i2c_1 ;

  • call sda_1 ;отпустить линию sda

  • call scl_1 ;отпустить линию scl

  • prd_i2c_3 call pausi2c ;пауза I2C (5 мкс)

  • btfss scl ;

  • goto prd_i2c_3 ;

  • movlw .20 ;прием потверждения 100 мкс

  • movwf scetbit ;

  • prd_i2c_4 btfss sda ;

  • goto prd_i2c_5 ;

  • decfsz scetbit,F ;

  • goto prd_i2c_4 ;

  • bsf flag,6 ;нет потверждения, устанавливаем флаг ошибки

  • prd_i2c_5 call scl_0 ;притянуть к 0 линию scl

  • call pausi2c ;пауза I2C (5 мкс)

  • return ;возврат из подпрограммы

  • priemi2c movlw .8 ;подпрограмма приема байта по i2c

  • movwf scetbit ;

  • call sda_1 ;отпустить линию sda

  • prm_i2c_1 rlf perem,F ;

  • call scl_1 ;отпустить линию scl

  • prm_i2c_2 call pausi2c ;пауза I2C (5 мкс)

  • btfss scl ;

  • goto prm_i2c_2 ;

  • btfsc sda ;

  • bsf perem,0 ;

  • btfss sda ;

  • bcf perem,0 ;

  • call scl_0 ;притянуть к 0 линию scl

  • call pausi2c ;пауза I2C (5 мкс)

  • decfsz scetbit,F ;

  • goto prm_i2c_1 ;

  • btfss flag,5 ;

  • call sda_0 ;притянуть к 0 линию sda

  • call scl_1 ;отпустить линию scl

  • prm_i2c_3 call pausi2c ;пауза I2C (5 мкс)

  • btfss scl ;

  • goto prm_i2c_3 ;

  • call scl_0 ;притянуть к 0 линию scl

  • call pausi2c ;пауза I2C (5 мкс)

  • movf perem,W ;

  • return ;возврат из подпрограммы

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • pausi2c nop ;Подпрограмма паузы I2C (5 мкс)

  • return ;возврат из подпрограммы

  • ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  • pauslcd movlw .4 ;подпрограмма пауза 2 мс

  • movwf Sec1 ;

  • p_l2 movlw .166 ;

  • movwf Sec ;

  • p_l1 decfsz Sec,F ;

  • goto p_l1 ;

  • decfsz Sec1,F ;

  • goto p_l2 ;

  • return ;выход из подпрограммы

  • paus_knp movlw .20 ;подпрограмма пауза 15 мс

  • movwf Sec1 ;

  • pa_l2 movlw .255 ;

  • movwf Sec ;

  • pa_l1 decfsz Sec,F ;

  • goto pa_l1 ;

  • decfsz Sec1,F ;

  • goto pa_l2 ;

  • return ;выход из подпрограммы

  • paus_ust movlw .255 ;подпрограмма пауза 200 мс

  • movwf Sec1 ;

  • pb_l2 movlw .255 ;

  • movwf Sec ;

  • pb_l1 decfsz Sec,F ;

  • goto pb_l1 ;

  • decfsz Sec1,F ;

  • goto pb_l2 ;

  • return ;выход из подпрограммы

  • end ;конец всей программы