Универсальный прибор для автомобиля: Часы, термометр, вольтметр, тахометр.
Данное устройство предназначено для контроля напряжения в бортовой сети с точностью 0.1в, измерения температуры в диапазоне от -50 до +125 градусов, измерения частоты вращения коленчатого вала от 0 до 9990 об/мин с точностью 100 об/мин в первом режиме и 10 об/мин во втором ( четырех цилиндровый двигатель), и имеет часы с питанием от встроеной литиевой батарейки. Предусмотрено изменение яркости индикатора - 10 уровней, режим корректировки часов, звуковая сигнализация при частоте вращения двигателя более 4000 об/мин, и напряжении более 14,9 вольт или менее 12 вольт.
Устройство имеет
- входы питания - от замка зажигания
- измерительный вход напряжения - к аккумулятору
- вход датчика цифрового термометра DS18b20
- вход датчика тахометра - подключается к клеме катушки зажигания , куда подходит провод от электронного коммутатора
- две кнопки управления
Питание осуществляется от бортсети автомобиля.Есть встроенная защита от переполюсовки.
Одной кнопкой осуществляется короткий выбор режимов - часы, термометр, вольтметр, тахометр.
Второй кнопкой осуществляется выбор всех режимов -часы, термометр, вольтметр, тахометр, регулировка яркости, коррекция минут, коррекция часов, тахометр с точностью 10 об/мин. При этом в режимах регулировка яркости, коррекция минут, коррекция часов - первой осуществляются изменения.
При включении зажигания прибор устанвливается в режим отображения времени, звуковая индикая отключена.
Схема
Кварц установить 4 МГц. Если есть проблема с вольтметром, то подключить 5 ногу процессора к +5 вольт.
Исходный текст программы
;**********************************************************************
; *
; Filename: AUTO_CH.asm *
; Date: 27.09.2004 *
; File Version: 1.2 *
; *
; Author: BY GARMASH G.V. *
; Company: *
; *
; *
;**********************************************************************
list p=16f73 ; list directive to define processor
#include ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC
;***** VARIABLE DEFINITIONS * IRQ *****
w_temp EQU 0x20 ; variable used for context saving
w_temp1 EQU 0xA0 ; reserve bank1 equivalent of w_temp
status_temp EQU 0x21 ; variable used for context saving
pclath_temp EQU 0x22 ; variable used for context saving
;********* 1 WIRE************
fCOUNTER: EQU 0x23 ; Счетчик только для локального пользования.
fCOUNTER2: EQU 0x24 ; Счетчик2.
fBIT_CNT: EQU 0x25 ; Счетчик прочитанных битов.
fBYTE_CNT: EQU 0x26 ; Счетчик прочитанных байтов.
fTEMP: EQU 0x27 ; Временный регистр только для локального использования.
CRC: EQU 0x28 ; Контрольная сумма.
#define _1WIRE PORTA,4 ; Выход на MicroLAN.
;*****************************
FLAG EQU 0x29 ; БИТОВЫЙ РЕГИСТР ФЛАГОВ
#define FLAG_CHANGE_LEVEL FLAG,0 ;
#define FLAG_CHANGE_LEVEL_1 FLAG,1 ;
#define FLAG_BEEP FLAG,2 ;
#define FLAG_3 FLAG,3 ;
#define FLAG_4 FLAG,4 ; FLAG
#define FLAG_5 FLAG,5 ; FLAG
#define FLAG_6 FLAG,6 ; FLAG
#define FLAG_7 FLAG,7 ; FLAG
;***************TEMP***************
TEMP EQU 0x2A
TEMP1 EQU 0x2B
TEMP2 EQU 0x2C
;********** I2C *************
_i2c_byte EQU 0x2D
_tmp EQU 0x2E
EE_DATA EQU 0x2F
EE_ADDR EQU 0x30
; ***********
#define SCL PORTA,2 ; I2C SCL PIN
#define SDA PORTA,5 ; I2C SDA PIN
#define TRIS_SCL TRISA^80,2 ; I2C SCL PIN
#define TRIS_SDA TRISA^80,5 ; I2C SDA PIN
;******** ЧАСЫ I2C *************
;БИТЫ | 8| 4| 2| 1| 8| 4| 2| 1|
SECONDS EQU 0x31 ;Секунды |CH| 10 SEC | SECOND | 00-59
MINUTES EQU 0x32 ;Минуты | 0| 10 MIN | MINUTS | 00-59
HOURS EQU 0x33 ;Часы |12/24| -|10hr | HOUR | 00-23/1-12 ;BIT8 = 0-24 HOUR
DAY EQU 0x34 ;День недели | 0| 0| 0| 0| 0 | DAY | 1-7
DATE EQU 0x35 ;День месяца | 0| 0|10DAT| DATE | 1-31
MONTH EQU 0x36 ;МЕСЯЦ | 0| 0| 0|10| MONTH | 1-12
YEAR EQU 0x37 ;ГОД | 10 YEAR | YEAR | 00-99
; |OUT|0|0|SQWE|0|0|RS1|RS0|
;*********** BEEP **************
#define BEEP_PIN PORTC,0
#define KEY1_PIN PORTB,1
#define KEY2_PIN PORTB,2
#define IN_N_PIN PORTB,0
;*********** DISPLAY ***********
#define SEGMENT_1 PORTB,6
#define SEGMENT_2 PORTB,5
#define SEGMENT_3 PORTB,4
#define SEGMENT_4 PORTB,3
#define SEGMENT_5 PORTB,7
#define SEGMENT_A PORTC,6
#define SEGMENT_B PORTC,7
#define SEGMENT_C PORTC,3
#define SEGMENT_D PORTC,1
#define SEGMENT_E PORTC,4
#define SEGMENT_F PORTC,2
#define SEGMENT_G PORTC,5
;*********** DASPLAY RAM ******
DISPLAY_S1 EQU 0x38
DISPLAY_S2 EQU 0x39
DISPLAY_S3 EQU 0x3A
DISPLAY_S4 EQU 0x3B
DISPLAY_S5 EQU 0x3C
fROM_ID0 EQU 0x3D
fROM_ID1 EQU 0x3E
fROM_ID2 EQU 0x3F
fROM_ID3 EQU 0x40
fROM_ID4 EQU 0x41
fROM_ID5 EQU 0x42
fROM_ID6 EQU 0x43
fROM_ID7 EQU 0x44
cicle EQU 0x45 ; НОМЕР ПРОХОДА ИНДИКАТОРА
MENU_LEVEL EQU 0x46
R0 EQU 0x47
R1 EQU 0x48
R2 EQU 0x49
R3 EQU 0x4A
R4 EQU 0x4B
R5 EQU 0x4C
LIGHT EQU 0x4D
CNT_KEY1 EQU 0x4E
CNT_KEY2 EQU 0x4F
POWER_LEVEL_BAT EQU 0x50
CNT_BEEP EQU 0x51
TTEMP EQU 0x52
DECIMAL EQU 0x53
TEMP_CICLE1 EQU 0x54
TEMP_CICLE2 EQU 0x55
COUNT_N1 EQU 0x56
COUNT_N2 EQU 0x57
N_COUNT1 EQU 0x58
N_COUNT2 EQU 0x59
LONG_COUNT_N1 EQU 0x5A
LONG_COUNT_N2 EQU 0x5B
LONG_N_COUNT1 EQU 0x5C
LONG_N_COUNT2 EQU 0x5D
COUNT_IRQ EQU 0x5E
LONG_COUNT_IRQ EQU 0x5F
; МАКРОСЫ
;***************
BANK0 macro ;------------------------------------------;
BCF STATUS,RP1
BCF STATUS,RP0
endm
;***************
BANK1 macro ;------------------------------------------;
BCF STATUS,RP1
BSF STATUS,RP0
endm
;***************
BANK2 macro ;------------------------------------------;
BSF STATUS,RP1
BCF STATUS,RP0
endm
;***************
BANK3 macro ;------------------------------------------;
BSF STATUS,RP1
BSF STATUS,RP0
endm
;***************
;**********************************************************************
ORG 0x000 ; processor reset vector
clrf PCLATH ; ensure page bits are cleared
goto START ; go to beginning of program
;**********************************************************************
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
bcf STATUS,RP0 ; ensure file register bank set to 0
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into w register
movwf pclath_temp ; save off contents of PCLATH register
movlw HIGH RETIRQ ;load high 8-bit address of Table
movwf PCLATH
; узнавания источника прерывания
BTFSS INTCON,INTF
GOTO IRQ_TIMER
BCF INTCON,INTF
; обработка прерывания не от таймера
INCFSZ COUNT_N1,F
GOTO RETIRQ_INT
INCF COUNT_N2,F
RETIRQ_INT
INCFSZ LONG_COUNT_N1,F
GOTO RETIRQ
INCF LONG_COUNT_N2,F
GOTO RETIRQ
IRQ_TIMER
; обработка прерывания таймера
BCF INTCON,T0IF ; RESET FLAG TIMER
CLRF TMR0
; СЧИТАТЬ ДО 256
MOVLW .22 ; таймер считает +1 от загруженного значения при переполнении
MOVWF TMR0 ; ЗДЕСЬ МЫ 25.6MKS+2,4= 29 MKS
INCF COUNT_IRQ,F
MOVLW .20
XORWF COUNT_IRQ,W
BTFSS STATUS,Z
GOTO IRQ_TIMER_1
CLRF COUNT_IRQ ; 0,3 SEC ON CICLE
MOVF COUNT_N1,W
MOVWF N_COUNT1
MOVF COUNT_N2,W
MOVWF N_COUNT2
CLRF COUNT_N1
CLRF COUNT_N2
IRQ_TIMER_1
INCF LONG_COUNT_IRQ,F
MOVLW .201
XORWF LONG_COUNT_IRQ,W
BTFSS STATUS,Z
GOTO RETIRQ
CLRF LONG_COUNT_IRQ ; 3 SEC ON CICLE
MOVF LONG_COUNT_N1,W
MOVWF LONG_N_COUNT1
MOVF LONG_COUNT_N2,W
MOVWF LONG_N_COUNT2
CLRF LONG_COUNT_N1
CLRF LONG_COUNT_N2
GOTO RETIRQ
RETIRQ
bcf STATUS,RP0 ; ensure file register bank set to 0
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
;**********************************************************************
;=================== LCD TABLE ==================================
; Подпрограмма вывода на семисегментный индикатор
;порт В0 -А ........ В7 - Н
;Исходные данные: В регистре W число от 0 до 7F
;Выходные данные: В регистре W код для индикатора
movlw HIGH LCDTable ;load high 8-bit
;address of Table
movwf PCLATH ;into PCLATH
LCDTable
ANDLW b'00001111'
addwf PCL,F ; W + PC -> PC
; retlw ; AFBDGCHE = '8,' hXX
retlw b'00100000' ; 0
retlw b'01110110' ; 1
retlw b'00001100' ; 2
retlw b'00010100' ; 3
retlw b'01010010' ; 4
retlw b'10010000' ; 5
retlw b'10000000' ; 6
retlw b'00110110' ; 7
retlw b'00000000' ; 8
retlw b'00010000' ; 9
retlw b'11111110' ;
retlw b'11111110' ;
retlw b'11111110' ;
retlw b'10001000' ; C
retlw b'11100100' ; u
retlw b'11000110' ; n
;**********************************************************************
;##########################################################
; Начало нашей программы
START
CALL _INIT
CLRF EE_ADDR ; ПРОВЕРИМ ЛОЯЛЬНОСТЬ ПОКАЗАНИЙ ЧАСОВ ЕСЛИ ВЫКЛЮЧЕНЫ(
CALL DSTIME_READ_BYTE
BTFSC EE_DATA,7
CALL INIT_TIMER ;СЕЛА БАТАРЕЯ ? ПРОИНИЦИАЛИЗМРУЕМ
CLRF MENU_LEVEL
START_MAIN
MOVLW .252
BTFSS FLAG_BEEP
MOVWF CNT_BEEP
BTFSC FLAG_BEEP
BSF BEEP_PIN
BTFSS FLAG_BEEP
BCF BEEP_PIN
CALL DISPLAY_CICLE ;ОТРАБОТКА ИНДИКАТОРА
INCFSZ TEMP1,F
GOTO START_MAIN_2
; РАБОТА СО ЗВУКОМ
INCFSZ CNT_BEEP,F
GOTO START_MAIN_BEEP
BCF FLAG_BEEP
START_MAIN_BEEP
; РАБОТА С КЛАВОЙ - КАЖДЫЕ 10 мс
BTFSS FLAG_CHANGE_LEVEL ; CMEНА РЕЖИМА БЕЗ СЕРВИСА
GOTO START_MAIN_1A
INCF MENU_LEVEL,F
MOVLW b'00000011'
ANDWF MENU_LEVEL,F
BCF FLAG_CHANGE_LEVEL
START_MAIN_1A
BTFSS FLAG_CHANGE_LEVEL_1 ; CMEНА РЕЖИМА С СЕРВИСНЫМИ РЕЖИМАМИ
GOTO START_MAIN_1
INCF MENU_LEVEL,F
MOVLW b'000000111'
ANDWF MENU_LEVEL,F
BCF FLAG_CHANGE_LEVEL_1
START_MAIN_1
CALL SCAN_KEY ; 10 MS
START_MAIN_2
; STANDART MODE
MOVLW .0
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL TIME_MODE
MOVLW .1
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL VOLT_MODE
MOVLW .2
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL TEMPERATUR_MODE
MOVLW .3
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL TAHOMETR_MODE
MOVLW .4
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL LIGHT_MODE
MOVLW .5
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL CHANGE_MIN_MODE
MOVLW .6
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL CHANGE_HOUR_MODE
MOVLW .7
XORWF MENU_LEVEL,W
BTFSC STATUS,Z
CALL LONG_TAHOMETR_MODE
;SERVICE MODE
GOTO START_MAIN
;**********************************************************************
;********* ПОДПРОГРАММЫ *********************************************
;**********************************************************************
;**********************************************************************
TAHOMETR_MODE
INCFSZ TEMP,F ; ИЗМЕРЯТЬ иногда
RETURN
MOVLW .255
MOVWF DISPLAY_S1
MOVLW b'11000111'
MOVWF DISPLAY_S4
MOVLW b'11110101'
MOVWF DISPLAY_S5
;N_COUNT1
; Деление.
; R1:R0 = R3:R2 / R5:R4
; В R3:R2 остаток.
MOVF N_COUNT1,W
MOVWF R2
MOVLW .10
MOVWF R4
CLRF R5
CALL div_16
MOVF R2,W
CALL LCDTable
MOVWF DISPLAY_S2
MOVF R0,W
CALL LCDTable
MOVWF DISPLAY_S3
;> 4000 ОБ.МИН
MOVLW .4
SUBWF R0,W
BTFSC STATUS,C
BSF FLAG_BEEP
RETURN
;**********************************************************************
LONG_TAHOMETR_MODE
; MOVLW .255
; MOVWF DISPLAY_S1
; MOVWF DISPLAY_S2
; MOVWF DISPLAY_S3
;
MOVLW b'11000111'
MOVWF DISPLAY_S4
MOVLW b'01111101'
MOVWF DISPLAY_S5
incfsz TEMP2,f
; BTFSS STATUS,Z
RETURN
; BTFSS FLAG_CHANGE_LEVEL ; CMEНА РЕЖИМА С СЕРВИСНЫМИ РЕЖИМАМИ
; RETURN
;
; BCF FLAG_CHANGE_LEVEL
; ДЕЙСТВИЕ
;LONG_N_COUNT1
;LONG_N_COUNT2
; Деление.
; R1:R0 = R3:R2 / R5:R4
; В R3:R2 остаток.
MOVF LONG_N_COUNT1,W
MOVWF R2
MOVF LONG_N_COUNT2,W
MOVWF R3
MOVLW .10
MOVWF R4
CLRF R5
CALL div_16_L
MOVF R2,W
CALL LCDTable
MOVWF DISPLAY_S1
MOVF R1,W
MOVWF R3
MOVF R0,W
MOVWF R2
MOVLW .10
MOVWF R4
CLRF R5
CALL div_16_L
MOVF R2,W
CALL LCDTable
MOVWF DISPLAY_S2
MOVF R0,W
CALL LCDTable
MOVWF DISPLAY_S3
;> 4000 ОБ.МИН
MOVLW .4
SUBWF R0,W
BTFSC STATUS,C
BSF FLAG_BEEP
RETURN
;**********************************************************************
CHANGE_HOUR_MODE
CALL TIME_MODE
MOVLW .255
MOVWF DISPLAY_S1
MOVWF DISPLAY_S2
MOVF TEMP1,W
BTFSS STATUS,Z
RETURN
BTFSS FLAG_CHANGE_LEVEL ; CMEНА РЕЖИМА С СЕРВИСНЫМИ РЕЖИМАМИ
RETURN
BCF FLAG_CHANGE_LEVEL
; ДЕЙСТВИЕ
MOVLW .2
MOVWF EE_ADDR ; HOUR
CALL DSTIME_READ_BYTE
MOVF EE_DATA,W
ANDLW b'00001111' ;HOUR
MOVWF R0
SWAPF EE_DATA,W
ANDLW b'00001111' ; DES HOUR
MOVWF R2
INCF R0,F
MOVLW .10
XORWF R0,W
BTFSC STATUS,Z
GOTO INC_DES_HOUR
MOVF R2,W
XORLW .2
BTFSS STATUS,Z
GOTO INC_DES_HOUR_2
MOVF R0,W
XORLW .4
BTFSC STATUS,Z
GOTO INC_DES_HOUR_1
INC_DES_HOUR_2
SWAPF R2,W
IORWF R0,W
MOVWF EE_DATA
CALL DSTIME_SAVE_BYTE
RETURN
INC_DES_HOUR
CLRF R0
INCF R2,F
MOVLW .3
XORWF R2,W
BTFSC STATUS,Z
GOTO INC_DES_HOUR_1
SWAPF R2,W
IORWF R0,W
MOVWF EE_DATA
CALL DSTIME_SAVE_BYTE
RETURN
INC_DES_HOUR_1
CLRF EE_DATA
CALL DSTIME_SAVE_BYTE
RETURN
;**********************************************************************
;**********************************************************************
CHANGE_MIN_MODE
CALL TIME_MODE
MOVLW .255
MOVWF DISPLAY_S4
MOVWF DISPLAY_S3
MOVF TEMP1,W
BTFSS STATUS,Z
RETURN
BTFSS FLAG_CHANGE_LEVEL ; CMEНА РЕЖИМА С СЕРВИСНЫМИ РЕЖИМАМИ
RETURN
BCF FLAG_CHANGE_LEVEL
; ДЕЙСТВИЕ
MOVLW .1
MOVWF EE_ADDR ; MIN
CALL DSTIME_READ_BYTE
MOVF EE_DATA,W
ANDLW b'00001111' ;MIN
MOVWF R0
SWAPF EE_DATA,W
ANDLW b'00001111' ; DES MIN
MOVWF R2
INCF R0,F
MOVLW .10
XORWF R0,W
BTFSC STATUS,Z
GOTO INC_DES_MIN
SWAPF R2,W
IORWF R0,W
MOVWF EE_DATA
CALL DSTIME_SAVE_BYTE
RETURN
INC_DES_MIN
CLRF R0
INCF R2,F
MOVLW .6
XORWF R2,W
BTFSC STATUS,Z
GOTO INC_DES_MIN_1
SWAPF R2,W
IORWF R0,W
MOVWF EE_DATA
CALL DSTIME_SAVE_BYTE
RETURN
INC_DES_MIN_1
CLRF EE_DATA
CALL DSTIME_SAVE_BYTE
RETURN
;**********************************************************************
LIGHT_MODE
MOVLW .255
MOVWF DISPLAY_S4
MOVWF DISPLAY_S5
MOVLW b'11101001'
MOVWF DISPLAY_S3
MOVLW b'11011111'
MOVWF DISPLAY_S2
MOVLW .5
SUBWF LIGHT,W
MOVWF R0
RRF R0,W
CALL LCDTable
MOVWF DISPLAY_S1
MOVF TEMP1,W
BTFSS STATUS,Z
RETURN
BTFSS FLAG_CHANGE_LEVEL ; CMEНА РЕЖИМА С СЕРВИСНЫМИ РЕЖИМАМИ
RETURN
BCF FLAG_CHANGE_LEVEL
DECF LIGHT,F ; (5 - 50_)
MOVF LIGHT,W
XORLW .5
MOVLW .25
BTFSC STATUS,Z
MOVWF LIGHT
DECF LIGHT,F ; (5 - 50_)
MOVF LIGHT,W
XORLW .5
MOVLW .25
BTFSC STATUS,Z
MOVWF LIGHT
RETURN
;**********************************************************************
VOLT_MODE
INCFSZ TEMP,F ; ИЗМЕРЯТЬ иногда
RETURN
GET_VOLUME_POWER
BCF ADCON0,ADON ; DISABLE ADC
BCF ADCON0,CHS0 ; SELECT CHANNEL 0
BCF ADCON0,CHS1
BCF ADCON0,CHS2
BSF ADCON0,ADON ; ENABLE ADC
CALL DELAY_15MKS ; 16 MKS
BSF ADCON0,GO_DONE ; START DAC
WAIT_CH0_DAC
BTFSC ADCON0,GO_DONE
GOTO WAIT_CH0_DAC
; DAC-OK
MOVF ADRES,W
MOVWF POWER_LEVEL_BAT
; CHANNEL 0 - END
;*****
BCF ADCON0,ADON ; DISABLE ADC
MOVF POWER_LEVEL_BAT,W
ANDLW b'00001111'
movwf R2
movwf R4
RLF R2,1
RLF R2,1
RLF R2,0
ADDWF R4,0
ADDWF R4,0
movwf R2 ; DECIMAL*10
movlw .16
movwf R4
; Деление.
;div_16 ; R0 = R2 / R4
; В R2 остаток.
CALL div_16
movf R0,W
CALL LCDTable
MOVWF DISPLAY_S2
SWAPF POWER_LEVEL_BAT,W
ANDLW b'00001111'
MOVWF R2 ; Деление.
;div_16 ; R1:R0 = R3:R2 / R5:R4
; В R3:R2 остаток.
MOVLW .10
MOVWF R4
CALL div_16
MOVF R0,W
CALL LCDTable
MOVWF DISPLAY_S4
MOVF R2,W
CALL LCDTable
MOVWF DISPLAY_S3
MOVLW b'11111101' ; XX.Xv
MOVWF DISPLAY_S5
MOVLW b'11100101'
MOVWF DISPLAY_S1
;> 15 V
MOVLW .5
XORWF R2,W
BTFSC STATUS,Z
BSF FLAG_BEEP
MOVLW .6
XORWF R2,W
BTFSC STATUS,Z
BSF FLAG_BEEP
MOVLW .7
XORWF R2,W
BTFSC STATUS,Z
BSF FLAG_BEEP
;-------------RB0 INT 0 to 1
; ||>------------TMR0 CONNECT TO CLK/4
; |||>-----------
; ||||>----------PRESCALER TO TMR0
; |||||>--\ Prescaler -> Timer0, Для часов
; ||||||>-->-----; 1:64, rising edge
; |||||||>/
movlw b'01000101'
movwf OPTION_REG^80
;*****************
; ПОКА ЕЩЕ БАНК 1
BCF TXSTA^80,TXEN ; ПЕРЕДАЧА OFF
; >--------------IRQ PSP
; |>-------------IRQ AD
; ||>------------IRQ USART RX
; |||>-----------IRQ USART TX
; ||||>----------IRQ SPP
; |||||>---------IRQ CPP1
; ||||||>--------IRQ TMR2
; |||||||>-------IRQ TMR1
; MOVLW b'11110000' ;
MOVLW b'00000000' ;
MOVWF PIE1^80 ;
; | >-------IRQ CCP2
; MOVLW b'11110000' ;
MOVLW b'00000000' ; IRQ MODULE
MOVWF PIE2^80 ;
BANK0
BSF _1WIRE ; ДЛЯ 1 WIRE
BCF RCSTA,SPEN ; USART OFF
; >--------------IRQ ON
; |>-------------IRQ ON PEREPHERIAL
; ||>------------IRQ ON TMR0
; |||>-----------IRQ ON RB0 INT
; ||||>----------OFF CHANGE PORTB
; |||||>---------
; ||||||>--------
; |||||||>-------
MOVLW b'10110000' ; IRQ ON
; MOVLW b'00000000' ; IRQ off
MOVWF INTCON ;
;**********************************************************************
; ЗАВЕРШЕНИЕ ИНИЦИАЛИЗАЦИИ *
;**********************************************************************
CLRF FLAG
CLRF DISPLAY_S1
CLRF DISPLAY_S2
CLRF DISPLAY_S3
CLRF DISPLAY_S4
CLRF DISPLAY_S5
MOVLW .10
MOVWF LIGHT
BCF BEEP_PIN ; OFF
RETURN
;**********************************************************************
DISPLAY_CICLE
; покажем индикатор полностью за 5 проходов
; MOVLW b'00000111'; ПОТУШИМ индикатор
; ANDWF PORTB,F
MOVLW b'11111000'; ПОТУШИМ индикатор
IORWF PORTB,F
MOVF LIGHT,W
XORWF cicle,W
BTFSC STATUS,Z
CLRF cicle
; узнаем номер прохода
MOVF cicle,W ; в W номер прохода
; табличное ветвление
btfsc STATUS,Z
GOTO MCICLE1
MOVLW .1
XORWF cicle,W
btfsc STATUS,Z
GOTO MCICLE2
MOVLW .2
XORWF cicle,W
btfsc STATUS,Z
GOTO MCICLE3
MOVLW .3
XORWF cicle,W
btfsc STATUS,Z
GOTO MCICLE4
MOVLW .4
XORWF cicle,W
btfsc STATUS,Z
GOTO MCICLE5
INCF cicle,F
RETURN
MCICLE1:
INCF cicle,F
MOVLW b'00000001'
ANDWF PORTC,F
MOVF DISPLAY_S1,W
ANDLW b'11111110'
IORWF PORTC,F
; BSF SEGMENT_1 ; зажжем этот разряд
BcF SEGMENT_1 ; зажжем этот разряд
RETURN
MCICLE2:
INCF cicle,F
MOVLW b'00000001'
ANDWF PORTC,F
MOVF DISPLAY_S2,W
ANDLW b'11111110'
IORWF PORTC,F
; BSF SEGMENT_2 ; зажжем этот разряд
BcF SEGMENT_2 ; зажжем этот разряд
RETURN
MCICLE3:
INCF cicle,F
MOVLW b'00000001'
ANDWF PORTC,F
MOVF DISPLAY_S3,W
ANDLW b'11111110'
IORWF PORTC,F
; BSF SEGMENT_3 ; зажжем этот разряд
BcF SEGMENT_3 ; зажжем этот разряд
RETURN
MCICLE4:
INCF cicle,F
MOVLW b'00000001'
ANDWF PORTC,F
MOVF DISPLAY_S4,W
ANDLW b'11111110'
IORWF PORTC,F
; BSF SEGMENT_4 ; зажжем этот разряд
BcF SEGMENT_4 ; зажжем этот разряд
RETURN
MCICLE5:
INCF cicle,F
MOVLW b'00000001'
ANDWF PORTC,F
MOVF DISPLAY_S5,W
ANDLW b'11111110'
IORWF PORTC,F
; BSF SEGMENT_5 ; зажжем этот разряд
BcF SEGMENT_5 ; зажжем этот разряд
RETURN
; *********************************************************************
;Примеры использования процедур I2C
; *********************************************************************
DSTIME_READ_BYTE
CALL i2c_start
MOVLW 0xD0
MOVWF _i2c_byte ; // control байт с битом WR
CALL i2c_write
MOVF EE_ADDR,W
MOVWF _i2c_byte ; младший байт адреса памяти
CALL i2c_write;
CALL i2c_start;
MOVLW 0xD1
MOVWF _i2c_byte ;// control байт с битом RD
CALL i2c_write
CALL i2c_read
CALL i2c_stop
MOVF _i2c_byte,W
MOVWF EE_DATA
RETURN
; *********************************************************************
DSTIME_SAVE_BYTE
CALL i2c_start
MOVLW 0xD0
MOVWF _i2c_byte; ; //control байт с битом WR
CALL i2c_write
MOVF EE_ADDR,W
MOVWF _i2c_byte ;// младший байт адреса памяти
CALL i2c_write
MOVF EE_DATA,W
MOVWF _i2c_byte ;// записываемые данные
CALL i2c_write
GOTO i2c_stop
; RETURN
;**********************************************************************
; *********************************************************************
;Подпрограммы для работы с шиной I2C . 100 kHz ДЛЯ 4 мГц ;
; *********************************************************************
;/*--------- начало примера-----------
; Требуется 2 байта ОЗУ - i2c_byte - в него помещается байт,
; который необходимо вывести на шину, в нем оказывается байт,
; считанный с шины; tmp - счетчик, используемый в цикле. */
; *********************************************************************
;char i2c_byte; /* рабочий регистр */
;char tmp; /* счетчик */
i2c_start
BANK1
bcf TRIS_SDA ; SDA - вывод
bcf TRIS_SCL ; SCL - вывод
BANK0
bsf SCL ; SCL - 1
NOP
NOP
bsf SDA ; SDA - 1
NOP
NOP
bcf SDA ; SDA - 0
NOP
NOP
bcf SCL ; SCL - 0
RETURN
; ***********
i2c_stop
BANK0
bcf SDA ; SDA - 0
NOP
NOP
bsf SCL ; SCL - 1
NOP
NOP
bsf SDA ; SDA - 1
RETURN
; ***********
i2c_write
movlw 0x08
movwf _tmp
BANK1
bcf TRIS_SDA ; SDA - вывод
bcf TRIS_SCL ; SCL - вывод
BANK0
bcf SCL ; SCL - 0
NOP
NOP
send_bit
bsf SDA ; SDA - 1 выводим 1 на SDA
NOP
NOP
btfss _i2c_byte, 7 ; бит данных - 1 ?
bcf SDA ; нет - выводим 0 на SDA
NOP
NOP
bsf SCL ; SCL - 1
NOP
NOP
rlf _i2c_byte, F ; сдвигаем влево байт данных
bcf SCL ; SCL - 0
NOP
NOP
decfsz _tmp, F ; конец цикла ?
goto send_bit ; нет - переход
bsf SDA ; осв. SDA SDA - 1
NOP
NOP
bsf SCL ; SCL - 1, получаем ACK-бит и игнорируем его (!)
NOP
NOP
bcf SCL ; SCL - 0
RETURN
; ***********
i2c_read
movlw 0x08
movwf _tmp
BANK1
bsf TRIS_SDA ; SDA - на ввод
bcf TRIS_SCL ; SCL - вывод
BANK0
bcf SCL ; SCL - на 0
NOP
NOP
read_bit
rlf _i2c_byte, F ; сдвигаем байт влево
bsf SCL ; SCL - 1
NOP
NOP
bsf _i2c_byte, 0 ; устанавливаем бит в 1 ; -NOP
NOP
NOP
btfss SDA ; SDA - 1?
bcf _i2c_byte, 0 ; нет - устанавливаем бит в 0
bcf SCL ; SCL - 0
NOP
NOP
decfsz _tmp, F ; конец цикла ?
goto read_bit ; нет - переход
BANK1
bcf TRIS_SDA ; SDA - вывод
BANK0
RETURN
; ***********
;**********************************************************************
INIT_TIMER
CLRF EE_DATA
CALL DSTIME_SAVE_BYTE ;0
INCF EE_ADDR,F
CALL DSTIME_SAVE_BYTE ;1
INCF EE_ADDR,F
CALL DSTIME_SAVE_BYTE ;2
INCF EE_ADDR,F
CALL DSTIME_SAVE_BYTE ;3
INCF EE_ADDR,F
CALL DSTIME_SAVE_BYTE ;4
INCF EE_ADDR,F
CALL DSTIME_SAVE_BYTE ;5
INCF EE_ADDR,F
CALL DSTIME_SAVE_BYTE ;6
INCF EE_ADDR,F
MOVLW b'10010000'
MOVWF EE_DATA
goto DSTIME_SAVE_BYTE ;7
;RETURN
;----------------------------------------------------------------------
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;@ Процедуры для работы с сетью MicroLAN со стороны ведущего. @
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;
;******** 4 MHZ *************
;******************** MicroLAN ***************************
; Команды сетевого уровня.
READ_ROM_CMD equ 033h ; Команда "Чтение ПЗУ"
READ_R1990_CMD equ 00Fh ; Для DS1990A этот код используется вместо 33h.
MATCH_ROM_CMD equ 055h ; Команда "Совпадение ПЗУ".
SKIP_ROM_CMD equ 0CCh ; Команда "Пропуск ПЗУ".
;*********************************************************
; W=0 - 772 мкс.
delay:
movwf fCOUNTER
D_Loop36:
decfsz fCOUNTER,1
goto D_Loop36
return
;-----------------------------------------------------------------------------
Reset_1Wire: ; Сбрасываем линию на около 500 мкс.
bcf _1WIRE
movlw .166
call delay ; 500 мкс.
bsf _1WIRE
CLRWDT ; СБРОС СТОРОЖЕВОГО ТАЙМЕРА
; Пропускаем импульс присутствия.
movlw .166
call delay ; 500 мкс.
CLRWDT ; СБРОС СТОРОЖЕВОГО ТАЙМЕРА
return
;-----------------------------------------------------------------------------
; Возвращает:
; Если ОК, то содержимое ПЗУ в регистрах fROM_ID0:fROM_ID7.
; Если ошибка CRC - флаг C (CARRY) в регистре STATUS установлен.
Get_TEMP:
clrf CRC
; Сбрасываем все приборы на линии.
; call Reset_1Wire
; Выдаем команду "Чтение ".
movlw 0xBE
call RW_Byte
; Читаем ПЗУ.
movlw 0xFF
call RW_Byte ; byte 0.
movwf fROM_ID0
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 1.
movwf fROM_ID1
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 2.
movwf fROM_ID2
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 3.
movwf fROM_ID3
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 4.
movwf fROM_ID4
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 5.
movwf fROM_ID5
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 6.
movwf fROM_ID6
call DO_CRC
; Читаем CRC.
movlw 0xFF
call RW_Byte ; byte 7 (CRC).
movwf fROM_ID7
subwf CRC,1
return
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; Возвращает:
; Если ОК, то содержимое ПЗУ в регистрах fROM_ID0:fROM_ID7.
; Если ошибка CRC - флаг C (CARRY) в регистре STATUS установлен.
Get_ROM_ID:
clrf CRC
; Сбрасываем все приборы на линии.
call Reset_1Wire
; Выдаем команду "Чтение ПЗУ".
movlw READ_ROM_CMD
call RW_Byte
; Читаем ПЗУ.
movlw 0xFF
call RW_Byte ; byte 0.
movwf fROM_ID0
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 1.
movwf fROM_ID1
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 2.
movwf fROM_ID2
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 3.
movwf fROM_ID3
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 4.
movwf fROM_ID4
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 5.
movwf fROM_ID5
call DO_CRC
movlw 0xFF
call RW_Byte ; byte 6.
movwf fROM_ID6
call DO_CRC
; Читаем CRC.
movlw 0xFF
call RW_Byte ; byte 7 (CRC).
movwf fROM_ID7
subwf CRC,1
return
;-----------------------------------------------------------------------------
; Ф-ция ввода/вывода на линию 1-Wire.
; Выводим из W и читаем в W.
RW_Byte:
movwf fTEMP
movlw d'8' ; 8 бит.
movwf fBIT_CNT
RBLoop:
bcf _1WIRE ; Обнуляем выход.
; Ждем 2 мкс.
CLRWDT ; СБРОС СТОРОЖЕВОГО ТАЙМЕРА
nop
btfsc fTEMP,0
bsf _1WIRE ; Устанавливаем выход.
rrf fTEMP,1
; Ждем ~12 мкс.
movlw 3
call delay
bcf fTEMP,7 ; Принимаем в тот же TEMP, из которого передаем.
btfsc _1WIRE
bsf fTEMP,7
; Далее даем время на освобождение линии ведомым.
movlw d'20'
call delay
; Отпускаем линию.
bsf _1WIRE
; Чуть-чуть даем отдохнуть (для медленных эмуляторов). Для Dallas не нужно.
movlw d'1' ; Впоследствии можно удалить при нормальной работе.
call delay
; Если 8 бит, то выходим.
decfsz fBIT_CNT,1
goto RBLoop
; Принятый байт в W.
movf fTEMP,0
return
;-----------------------------------------------------------------------------
; Процедура обновления CRC (циклическая контрольная сумма). Параметр в W.
DO_CRC: ; Размер CRC - 8 бит.
movwf CRC
movlw 0x08
movwf fBIT_CNT
movf CRC,0
DoCRC_Loop:
xorwf CRC,0
movwf fTEMP
rrf fTEMP,0
movf CRC,0
btfsc STATUS,0
xorlw 0x18
movwf fTEMP
rrf fTEMP,0
movwf CRC
bcf STATUS,0
rrf CRC,1
movf CRC,0
decfsz fBIT_CNT,1
goto DoCRC_Loop
return
;-----------------------------------------------------
;*****************************************************************************
;* ПРОЦЕДУРА ДЕЛЕНИЯ *
;*****************************************************************************
; Деление.
div_16_L ; R1:R0 = R3:R2 / R5:R4
; В R3:R2 остаток.
clrf R0
clrf R1
movf R4,w
btfss STATUS,Z
goto div16_Loop_L
movf R5,w
btfss STATUS,Z
goto div16_Loop_L
return
div16_Loop_L:
; Вычитаем RR5:RR4 из RR3:RR2.
movf R4,w
subwf R2,f ; F = F - W
btfss STATUS,C
decf R3,f ; Перенос.
btfsc R3,7
goto div16_exit_L
movf R5,w
subwf R3,f
btfss STATUS,C
goto div16_exit_L
; Увеличиваем частное на 1.
movlw 1
addwf R0,f
btfsc STATUS,C
incf R1,f
clrwdt
goto div16_Loop_L
; Выход.
div16_exit_L:
movf R4,w
addwf R2,f
; btfss STATUS,C
incf R3,f ; Перенос.
movf R5,w
addwf R3,f
return
; ;-----------------------------------------------------------------------------
;
;**********************************************************************
;*****************************************************************************
;* ПРОЦЕДУРА ДЕЛЕНИЯ *
;*****************************************************************************
; Деление.
div_16 ; R0 = R2 / R4
; В R2 остаток.
clrf R0
movf R4,w
btfss STATUS,Z
goto div16_Loop
return
div16_Loop:
; Вычитаем RR4 из RR2.
movf R4,w
subwf R2,f ; F = F - W
btfss STATUS,C
goto div16_exit
; Увеличиваем частное на 1.
INCF R0,f
clrwdt
goto div16_Loop
; Выход.
div16_exit:
movf R4,w
addwf R2,f
return
;-----------------------------------------------------------------------------
;**********************************************************************
;**********************************************************************
;********* КОНЕЦ 1 БЛОКА *********************************************
;**********************************************************************
;**********************************************************************
ORG 0x800
;**********************************************************************
NOP
NOP
NOP
;********* ПОДПРОГРАММЫ *********************************************
;**********************************************************************
; ПОДПРОГРАММЫ *
;**********************************************************************
;**********************************************************************
END ; directive 'end of program'
Прошивка процессора
:020000040000FA
:040000008A014F28FA
:08000800A00003088312A1000F
:100010000A08A20000308A008B1C16288B10D60F0D
:100020001228D70ADA0F3328DB0A33280B11810193
:1000300016308100DE0A14305E06031D2628DE011C
:100040005608D8005708D900D601D701DF0AC930B1
:100050005F06031D3328DF015A08DC005B08DD0062
:10006000DA01DB013328831222088A002108830089
:10007000A00E200E090000308A000F3982072034BC
:1000800076340C34143452349034803436340034A2
:100090001034FE34FE34FE348834E434C63428226E
:1000A000B0019222AF1B0A23C601FC30291DD100EA
:1000B00029190714291D07104F22AB0F6F28D10FE4
:1000C00062282911291C6828C60A0330C605291090
:1000D000A91C6E28C60A0730C605A910E021003009
:1000E00046060319F5210130460603194B2102305B
:1000F000460603198E21033046060319902004306A
:10010000460603192B210530460603190021063047
:1001100046060319CD20073046060319A9205528A5
:10012000AA0F0800FF30B800C730BB00F530BC0094
:100130005808C9000A30CB00CC01BB2349083D2038
:10014000B90047083D20BA000430470203182915BA
:100150000800C730BB007D30BC00AC0F08005C0855
:10016000C9005D08CA000A30CB00CC019C234908B5
:100170003D20B8004808CA004708C9000A30CB0033
:10018000CC019C2349083D20B90047083D20BA0016
:1001900004304702031829150800F521FF30B80084
:1001A000B9002B08031D0800291C08002910023083
:1001B000B00092222F080F39C7002F0E0F39C90047
:1001C000C70A0A3047060319F2284908023A031DF4
:1001D000ED284708043A0319FD28490E4704AF00EB
:1001E000A2220800C701C90A033049060319FD28E5
:1001F000490E4704AF00A2220800AF01A222080066
:10020000F521FF30BB00BA002B08031D0800291C94
:10021000080029100130B00092222F080F39C700C2
:100220002F0E0F39C900C70A0A30470603191D29C6
:10023000490E4704AF00A2220800C701C90A0630D0
:10024000490603192829490E4704AF00A2220800D5
:10025000AF01A2220800FF30BB00BC00E930BA00A9
:10026000DF30B90005304D02C700470C3D20B80013
:100270002B08031D0800291C08002910CD034D0878
:10028000053A19300319CD00CD034D08053A193050
:100290000319CD000800AA0F08001F109F111F129C
:1002A0009F121F14DD211F151F1954291E08D0008D
:1002B0001F1050080F39C900CB00C90DC90D490DD9
:1002C0004B074B07C9001030CB00BB2347083D202C
:1002D000B900500E0F39C9000A30CB00BB234708C4
:1002E0003D20BB0049083D20BA00FD30BC00E53090
:1002F000B8000530490603192915063049060319C7
:100300002915073049060319291500304706031936
:10031000291501304906031929150800CD30B80008
:10032000BC1E9A29DF30B900BA00BB00D40180306E
:10033000D5001922DD30BC00D40F0800D50F08000D
:100340008030D500212219223C153E0E0F390319A9
:10035000AC293C11BD09BE093D080F39D300BD0CC5
:10036000BD0CBD0CBD0CBD0CD20CBD0CD20CBD0C1B
:10037000D20CBD0CD20CBE0CD20CBE0CD20CBE0CDE
:10038000D20CBE0CD20C5208C9000A30CB00BB23E1
:1003900047083D20BB0049083D20BA005308C9006A
:1003A000C90DC90D490D53075307C9001030CB00C3
:1003B000BB2347083D20B900080003301C2B080070
:1003C0008618CE010619CF01861CCE0A061DCF0A5B
:1003D000CE19ED29CF19F12908002914CE012915CC
:1003E0000800A914CF012915080005304506031D92
:1003F0000800AA0F0800E630AA000230B0009222DE
:100400002F083D20BA002F0E3D20BB000130B00068
:1004100092222F083D20B8002F0E3D20B900003059
:10042000B0009222FF30BC002F1C0800BC103C1210
:1004300008008B132023CC307223443072238B1797
:1004400008008B132023CC30722329238B1708003C
:10045000031383121F108501860187018101831612
:1004600005309F002D308500073086000030870062
:1004700045308100981200308C0000308D0003134D
:10048000831205169813B0308B00A901B801B90189
:10049000BA01BB01BC010A30CD0007100800F830DA
:1004A00086044D0845060319C501450803196A2A43
:1004B000013045060319722A0230450603197A2ACB
:1004C000033045060319822A0430450603198A2A97
:1004D000C50A0800C50A013087053808FE398704B7
:1004E00006130800C50A013087053908FE3987045C
:1004F00086120800C50A013087053A08FE398704CC
:1005000006120800C50A013087053B08FE3987043A
:1005100086110800C50A013087053C08FE398704AA
:1005200086130800AD22D030AD00C8223008AD00DF
:10053000C822AD22D130AD00C822EB22BE222D0848
:10054000AF000800AD22D030AD00C8223008AD00A9
:10055000C8222F08AD00C822BE2A031383168512B5
:100560000511031383120515000000008516000015
:10057000000085120000000005110800031383121B
:100580008512000000000515000000008516080017
:100590000830AE000313831685120511031383126E
:1005A000051100000000851600000000AD1F851237
:1005B00000000000051500000000AD0D0511000051
:1005C0000000AE0BD32A85160000000005150000C0
:1005D0000000051108000830AE00031383168516CD
:1005E000051103138312051100000000AD0D051560
:1005F000000000002D1400000000851E2D100511C4
:1006000000000000AE0BF62A0313831685120313B5
:1006100083120800AF01A222B00AA222B00AA222CD
:10062000B00AA222B00AA222B00AA222B00AA222D2
:10063000B00A9030AF00A22AA300A30B1D2B080024
:100640000512A6301C2305166400A6301C23640086
:100650000800A801BE307223FF307223BD00892339
:10066000FF307223BE008923FF307223BF0089232D
:10067000FF307223C0008923FF307223C100892319
:10068000FF307223C2008923FF307223C300892305
:10069000FF307223C400A8020800A80120233330D1
:1006A0007223FF307223BD008923FF307223BE0006
:1006B0008923FF307223BF008923FF307223C000DB
:1006C0008923FF307223C1008923FF307223C200C7
:1006D0008923FF307223C3008923FF307223C400B3
:1006E000A8020800A7000830A50005126400000059
:1006F00027180516A70C03301C23A713051AA717E4
:1007000014301C23051601301C23A50B752B27085C
:100710000800A8000830A50028082806A700270C14
:1007200028080318183AA700270CA8000310A80CE3
:100730002808A50B8D2B0800C701C8014B08031D15
:10074000A52B4C08031DA52B08004B08C902031C50
:10075000CA03CA1BB52B4C08CA02031CB52B0130B7
:10076000C7070318C80A6400A52B4B08C907CA0AA3
:100770004C08CA070800C7014B08031DC02B08001E
:100780004B08C902031CC72BC70A6400C02B4B08C7
:04079000C90708008D
:06100000000000000000EA
:02400E00F23F7F
:00000001FF
Устройство размещается в стандартном пластмассовом корпусе размерами 60*80*15 мм.
Статья была взята с www.picping.narod.ru
Гармаш Генадий.