Олег Хай

Часы С Индикацией Времени Каждые 5 Минут

16 сообщений в этой теме

Здрасте, хочу сделать часы с индексацией на табло минут с интервалом каждые 5 минут. Есть схема исходник только не знаю что там надо подправить чтобы интервал был 5 минут а не каждую 1 минуту.

post-150966-0-09747000-1344802752_thumb.gif

  • Не одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
forbidden11    75

Да, там нужно кое-что подправить.

Для более развернутого ответа нужно побольше информации :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
wws63    82

Для начала выложите исходник программы :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
UTSource

Найдите миллионы труднодоступных

электронных компонентов

; Программа ЧАСЫ на PIC16F628A (Тактовая частота 4 Мгц)
;
; Декремент счётчика ct256 происходит 256 раз в секунду
; в программе прерывания по переполнению таймера TMR1.
; ==========================================================
list	p=16f628a	;задали тип контроллера
include	<p16F628a.inc>;подключили файл опций
; =====Конфигурация=========

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF
;===============================================
; Переменные и флаги, используемые в программе
;===============================================
RBPU	equ	07h; бит включения подтягивающих резисторов

ct256	equ	20h; счётчик 256 Гц

flagi	equ	21h
; назначение битов	
zv_of	equ	0;бит 0 - нажатие кнопки - выключение звука будильника
bu_sr	equ	1;бит 1 - будильник сработал
mctn	equ	2;бит 2 - малый счётчик ct256zvuk =0
rind	equ	3;бит 3 - режим индикации 0=часы-минуты, 1=минуты-секунды
bu_vkl	equ	4;бит 4 - будильник включен
bctn	equ	5;бит 5 - большой счётчик seczvuk =0
bit_ap	equ	6;бит 6 - бит автоповтора(устанавливается подпрограммой pause_ap)
kon_bit	equ	7;бит 7 - контрольный бит для автоповтора(flagi)

sec	equ	22h; значение секунд в виде 60-(количество секунд)
min	equ	23h; значение минут в виде 60-(количество минут)
has	equ	24h; значение часов в виде 24-(количество часов)

d_rez	equ	25h; результат деления на 10(десятки после
	   ; преобразования
e_rez	equ	26h; единицы после преобразования

ct256zvuk	equ	27h; дополнительный счётчик для генерации звука
time_temp	equ	28h; ячейка для подпрограммы пауза
temp1	equ	29h; временная ячейка для работы в прерывании

nom_kn	equ	2Ah; номер опрашиваемой кнопки
temp_kn	equ	2Bh; временная ячейка для работы с кнопками
temp1_kn	equ	2Ch; временная ячейка для работы с кнопками

seczvuk	equ	2Dh; секундный счётчик для генерации звука
ctblkn	equ	2Eh; секундный счётчик для блокировки кнопок

flagi1	equ	2Fh; флаги
; назначение битов
u_on	equ	00h; бит состояния портов 0-порты заблокированы напряжения нет
	   ;		  1-порты в обычном режиме напряжение есть
blkn	equ	01h; флаг блокировки кнопок 1-кнопки заблокированы


ct_kn_kor	equ	33h; счётчик от дребезга кнопки "коррекция"
fl_kor	equ	34h; флаги нажатия кнопки "коррекция"

ct_kn_bud	equ	35h; счётчик от дребезга кнопки "будильник"
fl_bud	equ	36h; флаги нажатия кнопки "будильник"

ct_kn_inc	equ	37h; счётчик от дребезга кнопки "инкремент"
fl_inc	equ	38h; флаги нажатия кнопки "инкремент"

fl_kn	equ	00h; флаг включения кнопки
fl_ap	equ	01h; флаг автоповтора (кнопка нажата дольше секунды)

n_ind	equ	39h ; номер индикатора, выводимого на индикацию
	    ; в прерывании

ind_0	equ	3Ah; четыре текущих индицируемых разряда
ind_1	equ	3Bh
ind_2	equ	3Ch
ind_3	equ	3Dh

fl_ind	equ	3Eh; флаги мигания разрядов
		; бит 0 - мигание разряда ind_0
		; бит 1 - мигание разряда ind_1
		; бит 2 - мигание разряда ind_2
		; бит 3 - мигание разряда ind_3
		; бит 4 - включение мигающей точки
temp_ind	equ	3Fh; временная ячейка

mask_b	equ	41h; маска порта B

kor_l	equ	0x42; (EEPROM 0x01)корректирующее значение, прибавляется
kor_h	equ	0x43; (EEPROM 0x02)к константе в TMR1 один раз в секунду
; по адресу 0x03 EEPROM записывается значение 0x55 (контрольный байт), которое
; проверяется при включении питания



LED0	equ	49h	; Регистр хранения результатов преобразований
		; 1-го двоично-десятичного разряда.
LED1	equ	4Ah	; ------- 2-го -------------------------
LED2	equ	4Bh	; ------- 3-го -------------------------
LED3	equ	4Ch	; ------- 4-го -------------------------

Count	equ	4Dh	; Счетчик проходов.
Mem	equ	4Eh	; Регистр оперативной памяти.

TimerL	equ	4Fh	; Регистр младшего разряда 2-байтного двоичного числа.
TimerM	equ	50h	; Регистр старшего разряда 2-байтного двоичного числа.
; ячейки, отображаемые во всех банках
tempkor_l	equ	70h	; буфер, чтобы хранить корректирующее значение
tempkor_h	equ	71h	; во время его коррекции 

w_temp	equ	72h	; ячейка хранения аккомулятора во время прерывания
status_temp	equ	73h	; для хранения регистра STATUS во время прерывания
temp_fsr	equ	74h	; ячейка для хранения регистра FSR во время прерывания

bud_min	equ	75h	; уставка минут будильника (EEPROM 0x04)
bud_has	equ	76h	; уставка часов будильника (EEPROM 0x05)
	   	; по адресу 0x06 EEPROM записан контрольный байт 0x55 
	   	; проверяемый при включении питания


;==========================
; Точка старта
;==========================
ORG	0
	GOTO	START
;======================
; программа прерывания
;======================
ORG	0004
movwf	w_temp; сохранили аккомулятор во временную ячейку
swapf	STATUS,W; загрузили регистр STATUS в аккомулятор, со сменой полубайтов
movwf	status_temp; сохранили во временную ячейку
movf	FSR,W	; загрузили регистр FSR в аккомулятор
movwf	temp_fsr	; сохранили во временной ячейке
bcf	STATUS,RP0
bcf	STATUS,RP1	; выбрали 0-й банк
;=============================================
; загрузка константы в регистры TMR1L и TMR1H
;=============================================
bcf	T1CON,TMR1ON; выключили таймер TMR1
movlw	0F0h;   загрузили в аккомулятор старший полубайт константы
movwf	TMR1H; переправили в регистр старшего байта таймера

; уход в прерывание происходит либо за 2 либо за 3 цикла контроллера, поэтому необходима
; коррекция младшего байта константы в зависимости от числа импульсов, оставшихся в
; счётчике TMR1L на момент остановки счёта

movlw	0C6h;   загрузили в аккомулятор младший полубайт константы
addwf	TMR1L,F; суммировали с остатком в TMR1

; так как число импульсов не круглое, каждое четвёртое прерывание
; необходимо уменишить константу на 1
; вычитание происходит только когда включены 0-й и первый биты счётчика ct256

movlw	2; загружаем в аккомулятор 2
andwf	ct256,W; выделяем 2-й бит счётчика
bcf	STATUS,C ;обнуляем флаг переноса
movwf	temp1; поместили во временную ячейку
rrf	temp1,W; сдвинули бит вправо, оставив в аккомуляторе
andwf	ct256,W; логическое И с первым битом в счётчике
subwf	TMR1L,F; вычли результат из младшего полубайта константы

bsf	T1CON,TMR1ON; включили таймер TMR1
;=============================================
; константа загружена
;=============================================

;сброс флага прерывания
bcf	PIR1,TMR1IF; сбросили флаг прерывания TMR1

; малый счётчик
decfsz	ct256zvuk,F	; декремент звукового счётчика
goto	clock01
bsf	flagi,mctn	; установили флаг малый счётчик =0
goto	clock00
clock01	bcf	flagi,mctn	; сбросили флаг малый счётчик =0
clock00	decfsz	ct256,F
goto	clock_ret; возврат из прерывания по уменьшению счётчика
	         ; 256 Гц на один импульс

; обработка одной секунды
;=====================
; коррекция константы
;=====================
bcf	T1CON,TMR1ON; выключили таймер TMR1
movf	kor_h,W	; загрузили в аккомулятор старший полубайт коррекции
addwf	TMR1H,F	; суммировали со старшим полубайтом константы
movf	kor_l,W	; загрузили в аккомулятор младший полубайт коррекции
addwf	TMR1L,F	; суммировали с младшим полубайтом константы
movf	STATUS,W	; загрузили в аккомулятор регистр STATUS
andlw	B'00000001'	; выделяем бит переноса
addwf	TMR1H,F	; суммировали со старшим полубайтом константы
bsf	T1CON,TMR1ON; включили таймер TMR1

; счётчик блокировки кнопок
decfsz	ctblkn,F	; декремент счётчика блокировки кнопок
goto	metka00	; счётчик не равен 0
; счётчик =0
bcf	flagi1,blkn	; сброс флага блокировки кнопок

; большой счётчик
metka00	decfsz	seczvuk,F	; декремент секундного звукового счётчика
goto	next_1
bsf	flagi,zv_of	; выставили флаг конец звука (выключить звук будильника)
bsf	flagi,bctn	; установили флаг большой счётчик=0
goto	next_0
next_1	bcf	flagi,bctn	; сбросили флаг обнуления большого счётчика

next_0	decfsz	sec,F
goto	clock_ret; возврат из прерывания
; обработка одной минуты
movlw	3Ch; загрузка в счётчик секунд числа 60(3C hex)
movwf	sec
decfsz	min,F
goto	clock_ret0; возврат из прерывания
; обработка одного часа
movlw	3Ch ;загрузка в счётчик минут числа 60(3C hex)
movwf	min
decfsz	has,F
goto	clock_ret0; возврат из прерывания
; переход в следующие сутки
movlw	18h; загрузка в счётчик часов числа 24(18 hex)
movwf	has
; возврат из прерывания
clock_ret0	call	bud_prov	; вызвали подпрограмму проверки будильника
clock_ret	call	u_re	; проверка напряжения и переключение портов
btfss	flagi1,u_on	; проверка напряжения
goto	clock_ret1	; напряжения нет, пропускаем опрос кнопок и 
		; динамическую индикацию
call	ind_pre	; динамическая индикация
btfsc	flagi1,blkn	; проверка блокировки кнопок
goto	clock_ret1	; кнопки блокированы, пропускаем опрос кнопок
; опрос кнопок
clrf	nom_kn	; задали номер кнопки 0 "коррекция"
call	knopki	; вызвали подпрограмму опроса кнопок
incf	nom_kn,F	; задали номер кнопки 1 "будильник"
call	knopki	; вызвали подпрограмму опроса кнопок
incf	nom_kn,F	; задали номер кнопки 2 "инкремент"
call	knopki	; вызвали подпрограмму опроса кнопок

clock_ret1	movf	temp_fsr,W	; загрузили в аккомулятор регистр FSR
movwf	FSR	; восстановили регистр FSR
swapf	status_temp,W; загрузили регистр STATUS в аккомулятор,
		 ; со сменой полубайтов
movwf	STATUS; восстановили регистр STATUS
swapf	w_temp,F
swapf	w_temp,W; восстановили аккомулятор
retfie	; возврат из прерывания	

;==========================
; Начало основной программы
; инициализация контроллера
;==========================
START	clrw		;обнуление аккомулятора
bcf	STATUS,RP0	;переход в 0-й
bcf	STATUS,RP1	;банк
movwf	INTCON	;запрет всех прерываний
movwf	PIR1	;сброс всех флагов прерываний
bsf	STATUS,RP0	;1-й банк
movwf	PIE1	;запрет прерываний от переферийных модулей
bcf	STATUS,RP0	;0-й банк
;=======================================================	
;далее выключаем неиспользуемые модули микроконтроллера
;=======================================================
;отключение модуля компараторов
movlw	07h	;загрузили в аккомулятор число "00000111"
movwf	CMCON	;включили биты CM0...CM2 регистра CMCON, что
		;соответствует отключению модуля компараторов
;отключение модуля USART
clrf	RCSTA	;обнулили регистр RCSTA, выключив бит SPEN(7-й)
		;что соответствует отключеннию USART
;отключение модуля TMR2
clrf	T2CON	;обнулили регистр T2CON, выключив бит TMR2ON(2-й)
		;что соответствует отключению TMR2
;отключение модуля CCP
clrf	CCP1CON	;обнулили регистр CCP1CON, выключив биты
		;CCP1M0...CCP1M3
		;(0-й...3-й), что соответствует отключению модуля CCP
;отключение источника опорного напряжения
bsf	STATUS,RP0	;1-й банк
clrf	VRCON	;обнулили регистр VRCON(в 1-м банке), выключив
		;бит VREN(7-й),что соответствует отключению ИОН

;отключение TMR0
bcf	OPTION_REG,T0CS	;обнуляем бит T0CS, что соответствует  
			;тактированию TMR0 от внутреннего сигнала
bcf	STATUS,RP0	;0-й банк	
;========================================================
;закончили отключение неиспользуемых модулей
;========================================================

clrf	T1CON; отключили TMR1, и инициализировали, обнулив все биты
	     ; регистра T1CON

; обнуляем все регистры нулевого банка
nolreg	movlw	20h	; адрес первого регистра
movwf	FSR	; загрузили в FSR
nolreg0	clrf	INDF	; обнулили регистр
movf	FSR,W	; загрузили FSR  в аккомулятор
incf	FSR,F	; увеличили FSR на 1
xorlw	7Fh	; сравниваем FSR  с адресом последней ячейки
btfss	STATUS,Z	; проверка равенства
; флаг нуля сброшен, адреса НЕ равны
goto	nolreg0	; продолжить обнуление
; закончили обнуление

;загрузка константы в TMR1
movlw	0F0h;   загрузили в аккомулятор старший полубайт константы
movwf	TMR1H; переправили в регистр старшего байта таймера
movlw	0C6h;   загрузили в аккомулятор младший полубайт константы
movwf	TMR1L; переправили в регистр младшего байта таймера
;загружаем счётчики секунд, минут и часов
movlw	3Ch; загрузили в аккомулятор число 60(3Ch)
movwf	sec; переправили в счётчик секунд
movwf	min; переправили в счётчик минут
movlw	18h; загрузили в аккомулятор число 24(18h)
movwf	has; переправили в счётчик часов

;загрузка корректирующей константы
movlw	03h ; загрузили в аккомулятор адрес контрольного байта в EEPROM
call	ee_rd ; вызов подпрограммы чтения из EEPROM
xorlw	55h ; сравниваем прочитанное с контрольным значением
btfsc	STATUS,Z ;проверка флага нуля
; флаг нуля установлен (контрольное значение есть в EEPROM)
goto	kk_ee ; переход к чтению константы из EEPROM
; флаг нуля сброшен (в EEPROM константа не записана)
movlw	04h ;загрузили в аккомулятор старший полубайт коррекции(.1032)
movwf	kor_h ; переправили в ячейку старшего полубайта
movlw	08h  ; загрузили в аккомулятор младший полубайт коррекции
movwf	kor_l ; переправили в ячейку младшего полубайта
goto	port_inic ; переход к инициализации портов
; чтение корректирующей константы из EEPROM
kk_ee	movlw	01h ; в аккомулятор- адрес младшего полубайта константы
call	ee_rd ; читаем из EEPROM
movwf	kor_l ; переправили на место младший полубайт
movlw	02h ; в аккомулятор адрес старшего полубайта
call	ee_rd ; читаем из EEPROM
movwf	kor_h ; корректируещее значение загружено

; инициализация портов
port_inic	clrf	PORTA
clrf	PORTB
bsf	STATUS,RP0	;1-й банк
movlw	B'11100000'	; загрузили в ак-р число для TRISA
		; RA0-RA4 - выходы
		; RA5-RA7 - входы
movwf	TRISA	; переправили в TRISA
movlw	B'11100000'	; загрузили в ак-р число для TRISB
		; RB0-RB4 - выходы
		; RB5-RB7 - входы
movwf	TRISB	; переправили в TRISB
bcf	OPTION_REG,RBPU ; ВКЛЮЧИЛИ ПОДТЯГИВАЮЩИЕ РЕЗИСТОРЫ
bcf	STATUS,RP0	; 0-й банк

; загрузка значения будильника
movlw	06h	; загрузили в аккомулятор адрес контрольного байта
call	ee_rd	; вызов подпрограммы чтения из EEPROM
xorlw	55h	; сравниваем прочитанное с контрольным значением
btfss	STATUS,Z	;проверка флага нуля
; флаг нуля сброшен (контрольного значения НЕТ в EEPROM)
goto	inic_ok	; к окончанию инициализации
; флаг нуля установлен (контрольное значение есть в EEPROM)
; читаем уставку будильника из EEPROM
movlw	04h	; адрес минут будильника
call	ee_rd	; вызов подпрограммы чтения из EEPROM
movwf	bud_min	; загрузили минуты будильника
movlw	05h	; адрес часов будильника
call	ee_rd	; вызов подпрограммы чтения из EEPROM
movwf	bud_has	; загрузили часы будильника
;включаем прерывания
inic_ok	bsf	STATUS,RP0; 1-й банк
bsf	PIE1,TMR1IE; прерыванине по переполнению TMR1 разрешено
bcf	STATUS,RP0; 0-й банк
bsf	INTCON,PEIE; разрешаем прерывания от переферийных модулей	
bsf	INTCON,GIE; глобальное разрешение прерываний

; включаем таймер/счётчик TMR1
bsf	T1CON,TMR1ON; таймер TMR1 включен

;==================================
; Начало главного цикла программы
;==================================

; Главный цикл программы
;===========================
gl_cikl	call	hasmin_ind	; вывод на индикатор часов-минут
movf	fl_ind,W	; загрузили в аккомулятор флаги мигания индикаторов
andlw	B'11110000'	; обнулили флаги мигания индикаторов
xorwf	flagi,W
andlw	B'11101111'
xorwf	flagi,W
movwf	fl_ind ; заменили бит мигающей точки на бит включения будильника
; проверяем сработал ли будильник
btfsc	flagi,bu_sr
; будильник сработал
goto	budilnik ; переход к циклу будильник сработал
; проверяем нажата ли кнопка коррекция
btfsc	fl_kor,fl_kn
; бит включен, кнопка нажата
goto	cikl_kor; переход к циклу коррекции
; проверяем нажата ли кнопка будильник
btfsc	fl_bud,fl_kn
; бит включен, кнопка нажата
goto	cikl_bud; переход к циклу будильника
; проверяем нажата ли кнопка инкремент
btfsc	fl_inc,fl_kn
; бит включен, кнопка нажата
goto	smrin; смена режима индикации
goto	gl_cikl; переход к началу главного цикла
;-------------------------------

; смена режима индикации
;==========================
smrin	movlw	B'00001000' ; загрузили маску для 3-го бита
xorwf	flagi,F	; инвертировали бит режима индикации
bcf	fl_inc,fl_kn ; сброс флага кнопки инкремент
goto	gl_cikl	; возврат в главный цикл
;-------------------------------

; цикл коррекции
;=================
cikl_kor	bcf	fl_kor,fl_kn ; обнулили флаг кнопки коррекция
bsf	flagi,rind	; режим индикации минуты-секунды
bcf	fl_ind,04h ; выключили мигающую точку
; включаем мигание 2-х младших разрядов (секунд)
bsf	fl_ind,00h
bsf	fl_ind,01h
; цикл коррекции секунд
;=========================
cikl_kors0	call	hasmin_ind	; вызов подпрограммы индикации
; проверяем флаг выхода из цикла
btfsc	flagi,bctn	; проверка на 0 большого счётчика
goto	gl_cikl	; если флаг установлен - воврат в главный цикл
; проверяем нажата ли кнопка коррекция
btfsc	fl_kor,fl_kn
; бит включен, кнопка нажата
goto	ci_kormin; переход к циклу коррекции минут
; проверяем автоповтор кнопки коррекция
btfsc	fl_kor,fl_ap
; автоповтор включен
goto	ci_korkonst ; переход к коррекции константы
; проверяем нажата ли кнопка инкремент
btfss	fl_inc,fl_kn
; кнопка НЕ нажата
goto	cikl_kors0 ; переход к началу цикла коррекции секунд
; кнопка инкремент нажата - обнулить секунды (обнуляется счётчик секунд-sec=.60-, ct256,
; перезагружается константа в TMR1 )
call	sec_nol ; вызываем подпрограмму обнуления секунд
bcf	fl_inc,fl_kn ; сбрасываем бит кнопки инкремент
goto	cikl_kors0 ; переход к началу цикла коррекции секунд
;-------------------------------

; цикл коррекции минут
;======================
ci_kormin	bcf	fl_kor,fl_kn ; обнулили флаг кнопки коррекция
bcf	flagi,rind	; режим индикации часы-минуты
ci_kormin0	call	hasmin_ind ; выводим на индикатор часы-минуты
; проверяем флаг выхода из цикла
btfsc	flagi,bctn
goto	gl_cikl	; если флаг установлен - воврат в главный цикл
; проверяем нажата ли кнопка коррекция
btfsc	fl_kor,fl_kn
; кнопка коррекция нажата
goto	ci_korhas ; переход к циклу коррекции часов	
; проверяем нажата ли кнопка инкремент
btfss	fl_inc,fl_kn
; кнопка инкремент НЕ нажата
goto	ci_kormin1 ; переход к проверке автоповтора кнопки инкремент
; кнопка инкремент нажата
bcf	fl_inc,fl_kn ; сбрасываем флаг кнопки инкремент
call	inc_min ; вызываем подпрограмму инкремента минут
goto	ci_kormin0 ; к началу цикла коррекции минут
; проверяем автоповтор кнопки инкремент
ci_kormin1	btfss	fl_inc,fl_ap
; автоповтора нет
goto	ci_kormin0 ; переход к началу цикла коррекции минут

; автоповтор включен - увеличиваем счётчик минут с частотой 4 Гц
cikm_ap	call	pause_ap ; вызываем подпрограмму паузы автоповтора
btfss	flagi,bit_ap ; проверяем бит автоповтора
; бит ВЫключен
goto	cikm_ap1
; бит включен
bcf	flagi,bit_ap ; обнулили бит автоповтора
call	inc_min ; вызвали подпрограмму инкремента минут
; индикация и проверка автоповтора кнопки инкремент
cikm_ap1	call	hasmin_ind
goto	ci_kormin1 ; переход к началу цикла автоповтора
;-------------------------------

; цикл коррекции часов
;=======================
ci_korhas	bcf	fl_kor,fl_kn ; обнулили флаг кнопки коррекция
movlw	B'00001100'
movwf	fl_ind ; включаем мигание часов
ci_korhas0	call	hasmin_ind ; выводим на индикатор часы-минуты
; проверяем флаг выхода из цикла
btfsc	flagi,bctn
goto	gl_cikl	; если флаг установлен - воврат в главный цикл
; проверяем нажата ли кнопка коррекция
btfsc	fl_kor,fl_kn
; кнопка коррекция нажата
goto	ingl_cikl	; возврат в главный цикл
; проверяем нажата ли кнопка инкремент
btfss	fl_inc,fl_kn
; кнопка инкремент НЕ нажата
goto	cikh_ap ; переход к проверке автоповтора кнопки инкремент
; кнопка инкремент нажата
bcf	fl_inc,fl_kn ; сбросили флаг кнопки инкремент
call	inc_has ; вызвали подпрограмму инкремента часов
goto	ci_korhas0 ; к началу цикла коррекции часов

cikh_ap	btfss	fl_inc,fl_ap ; проверяем включен ли автоповтор
; автоповтор кнопки инкремент выключен
goto	ci_korhas0 ; к началу цикла коррекции часов

; автоповтор включен - увеличиваем счётчик часов с частотой 4 Гц
call	pause_ap ; вызываем подпрограмму паузы автоповтора
btfss	flagi,bit_ap ; проверяем бит автоповтора
; бит ВЫключен
goto	cikh_ap1
; бит включен
bcf	flagi,bit_ap ; обнулили бит автоповтора
call	inc_has ; вызвали подпрограмму инкремента часов
; индикация и проверка автоповтора кнопки инкремент
cikh_ap1	call	hasmin_ind ; выводим на индикатор часы-минуты
goto	cikh_ap ; переход к началу цикла автоповтора
; возврат в главный цикл
ingl_cikl	clrf	fl_kor
clrf	fl_bud
clrf	fl_inc	; сброс флагов кнопок
clrf	ct_kn_kor
clrf	ct_kn_bud
clrf	ct_kn_inc	; сброс счётчиков дребезга
bcf	flagi,rind	; включаем режим индикации часы-минуты
; блокировка кнопок на 3 секунды
movlw	.3	; загрузили в аккомулятор число 3
movwf	ctblkn	; переправили в счётчик блокировки кнопок
bsf	flagi1,blkn	; установили флаг блокировки кнопок
goto	gl_cikl
;-------------------------------

; цикл коррекции константы
;==========================
ci_korkonst	bcf	fl_kor,fl_ap ; обнулили флаг автоповтора кнопки коррекция
bcf	fl_kor,fl_kn ; сброс флага кнопки коррекция
; включаем мигание 2-х старших разрядов индикатора
bsf	fl_ind,02h
bsf	fl_ind,03h
movf	kor_l,W
movwf	tempkor_l ; загрузили в буфер младший полубайт корректирующей константы
movf	kor_h,W
movwf	tempkor_h ; загрузили в буфер старший полубайт корректирующей константы
ci_korcon0	movf	tempkor_l,W
movwf	TimerL ; загрузили иладший полубайт в ячейки для преобразования
movf	tempkor_h,W
movwf	TimerM ; загрузили старший полубайт в ячейки для преобразования
call	bin2_10 ; вызвали подпрограмму преобразования в дес. код
movf	LED0,W
movwf	ind_0
movf	LED1,W
movwf	ind_1
movf	LED2,W
movwf	ind_2
movf	LED3,W
movwf	ind_3 ; переправили десятичное значение на индикатор
; проверяем флаг выхода из цикла
btfsc	flagi,bctn
goto	gl_cikl	; если флаг установлен - воврат в главный цикл
; проверяем автоповтор кнопки инкремент (+)
btfsc	fl_inc,fl_ap
; автоповтор есть
goto	konsinc_ap ; переход к автоповтору инкремента
; автоповтора нет
; проверяем автоповтор кнопки будильник (-)
btfsc	fl_bud,fl_ap
; автоповтор есть
goto	konsdec_ap ; переход к автоповтору декремента
; автоповтора нет
; проверяем нажата ли кнопка инкремент (+)
btfsc	fl_inc,fl_kn
; кнопка нажата
call	konst_inc ; вызываем подпрограмму инкремента константы
; кнопка НЕ нажата

; проверяем нажата ли кнопка будильник (-)
btfsc	fl_bud,fl_kn
; кнопка нажата
call	konst_dec ; вызываем подпрограмму декремента константы
; кнопка НЕ нажата

btfss	fl_kor,fl_kn ; проверяем нажата ли кнопка коррекция
; кнопка коррекция НЕ нажата
goto	ci_korcon0 ; возврат к началу цикла коррекции константы
; кнопка коррекция нажата дольше секунды
; запись откорректированной константы во все отведённые для неё ячейки
bcf	fl_kor,fl_kn
bcf	fl_kor,fl_ap ; сброс флагов кнопки коррекция
clrf	ct_kn_kor	 ; обнуление счётчика дребезга кнопки коррекция
; запрет прерываний
bcf	INTCON,GIE
; запись в рабочую ячейку
movf	tempkor_l,W
movwf	kor_l
movf	tempkor_h,W
movwf	kor_h
bsf	INTCON,GIE	; разрешение прерываний
; запись в EEPROM
bsf	STATUS,RP0	; банк1
movlw	01h	; поместили в аккомулятор адрес kor_l в EEPROM
movwf	EEADR	; переслали в EEADR
movf	tempkor_l,W	; поместили в аккомулятор новое значение kor_l
call	ee_wr	; вызвали подпрограмму записи в EEPROM
movlw	02h	; поместили в аккомулятор адрес kor_h в EEPROM
movwf	EEADR	; переслали в EEADR
movf	tempkor_h,W	; поместили в аккомулятор новое значение kor_h
call	ee_wr	; вызвали подпрограмму записи в EEPROM
movlw	03h	; поместили в аккомулятор адрес контрольного бита
movwf	EEADR	; переслали в EEADR
movlw	55h	; загрузили в аккомулятор контрольный байт
call	ee_wr	; вызвали подпрограмму записи в EEPROM
; возврат в главный цикл
bcf	STATUS,RP0	; 0-й банк
goto	ingl_cikl
;-------------------------------

; автоповтор инкремента константы
;=================================
konsinc_ap	call	pause_ap ; вызываем подпрограмму паузы автоповтора
btfss	flagi,bit_ap ; проверяем бит автоповтора
; бит ВЫключен
goto	ci_korcon0	; возврат в цикл коррекции константы
; бит включен
bcf	flagi,bit_ap ; обнулили бит автоповтора
call	konst_inc ; вызвали подпрограмму инкремента константы
goto	ci_korcon0	; возврат в цикл коррекции константы
;-------------------------------

; автоповтор декремента константы
;================================
konsdec_ap	call	pause_ap ; вызываем подпрограмму паузы автоповтора
btfss	flagi,bit_ap ; проверяем бит автоповтора
; бит ВЫключен
goto	ci_korcon0	; возврат в цикл коррекции константы
; бит включен
bcf	flagi,bit_ap ; обнулили бит автоповтора
call	konst_dec ; вызвали подпрограмму декремента константы
goto	ci_korcon0	; возврат в цикл коррекции константы
;-------------------------------

; цикл будильника
;======================
cikl_bud	bcf	fl_bud,fl_kn ; сброс флага кнопки будильник
cikl_bud0	call	budind	; индикация часов-минут будильника
; проверяем флаг выхода из цикла
btfsc	flagi,bctn
goto	gl_cikl	; если флаг установлен - воврат в главный цикл
; опрос кнопок
btfsc	fl_bud,fl_kn ; проверяем нажата ли кнопка будильник
goto	bud_end	 ; на завершение цикла будильника
btfsc	fl_kor,fl_kn ; нажата ли кнопка коррекция
goto	budkormin	; к коррекции минут будильника
btfss	fl_inc,fl_kn ; проверяем нажата ли кнопка инкремент
; кнопка инкремент не нажата
goto	cikl_bud0	; переход к началу цикла
; кнопка инкремент нажата
bcf	fl_inc,fl_kn ; сброс флага кнопки инкремент
;-------------------------------

;будильник включить/выключить
;============================
; инвертируем бит включения будильника
movlw	B'00010000'	; загрузили в аккомулятор маску для 4-го бита
xorwf	flagi,F	; инвертируем 4-й бит
movf	fl_ind,W	; загрузили в аккомулятор флаги мигания индикаторов
xorwf	flagi,W
andlw	B'11101111'
xorwf	flagi,W
movwf	fl_ind	; заменили бит мигающей точки на бит включения будильника
btfsc	flagi,bu_vkl ; проверяем включен ли будильник
; будильник включен
call	zvuk1sek	; вызов звукового сигнала, длительностью 1 секунда
; будильник выключен
goto	cikl_bud0	; переход к началу цикла
;-------------------------------

; выход из цикла будильника
;===========================

; запись в EEPROM уставки будильника
bud_end	bsf	STATUS,RP0	; банк1
movlw	04h	; адрес минут будильника в EEPROM
movwf	EEADR	; загрузили в ячейку адреса EEPROM
movf	bud_min,W	; загрузили в аккомулятор минуты будильника
call	ee_wr	; вызвали подпрограмму записи в EEPROM
movlw	05h	; адрес часов будильника в EEPROM
movwf	EEADR	; загрузили в ячейку адреса EEPROM
movf	bud_has,W	; загрузили в аккомулятор часы будильника
call	ee_wr	; вызвали подпрограмму записи в EEPROM
movlw	06h	; адрес контрольного бита будильника в EEPROM
movwf	EEADR	; загрузили в ячейку адреса EEPROM
movlw	55h	; загрузили в аккомулятор контрольный байт
call	ee_wr	; вызвали подпрограмму записи в EEPROM
bcf	STATUS,RP0	; банк0
goto	ingl_cikl	; возврат в главный цикл
;-------------------------------

; цикл коррекции минут будильника
;================================
budkormin	bcf	fl_kor,fl_kn ; сброс флага кнопки коррекция
bsf	fl_ind,0h	;
bsf	fl_ind,01h	; включили мигание двух младших разрядов индикатора
budkormin0	call	budind	; индикация часов-минут будильника
; проверяем флаг выхода из цикла
btfsc	flagi,bctn
goto	gl_cikl	; если флаг установлен - воврат в главный цикл

btfsc	fl_kor,fl_kn ; проверяем нажата ли кнопка коррекция
; кнопка коррекция нажата
goto	budkorhas	; переход к циклу коррекции часов будильника
; кнопка коррекция НЕ нажата
btfss	fl_inc,fl_kn ; проверяем нажата ли кнопка инкремент
; кнопка инкремент НЕ нажата
goto	budkormin1	; переход к проверке автоповтора
; кнопка инкремент нажата
bcf	fl_inc,fl_kn ; сброс флага кнопки инкремент
call	incminbud	; вызов подпрограммы инкремента минут будильника
goto	budkormin0	; переход к началу цикла коррекции минут будильника
;-------------------------------

; цикл автоповтора инкремента минут будильника
;=============================================
budkormin1	btfss	fl_inc,fl_ap ; проверяем автоповтор кнопки инкремент
; автоповтора нет
goto	budkormin0	; переход к началу цикла коррекции минут будильника
; автоповтор есть
call	pause_ap	; вызываем подпрограмму паузы автоповтора
btfss	flagi,bit_ap ; проверяем бит автоповтора
; бит автоповтора выключен
goto	budkormin2
; бит автоповтора включен
bcf	flagi,bit_ap ; сброс бита автоповтора
call	incminbud	; вызов подпрограммы инкремента минут будильника
budkormin2	call	budind	; индикация часов-минут будильника
goto	budkormin1	; переход к началу цикла автоповтора
;-------------------------------

; цикл коррекции часов будильника
;====================================
budkorhas	bcf	fl_kor,fl_kn ; сброс флага кнопки коррекция
bcf	fl_ind,00h
bcf	fl_ind,01h	; выключили мигание 2-х младших разрядов индикатора
bsf	fl_ind,02h
bsf	fl_ind,03h	; включили мигание двух старших разрядов индикатора
budkorhas0	call	budind	; индикация часов-минут будильника
; проверяем флаг выхода из цикла
btfsc	flagi,bctn
goto	gl_cikl	; если флаг установлен - воврат в главный цикл
btfss	fl_kor,fl_kn ; проверка нажатия кнопки коррекция
; кнопка коррекция НЕ нажата
goto	budkorhas1	; переход к проверке кнопки инкремент
; кнопка коррекция нажата	
bcf	fl_ind,02h
bcf	fl_ind,03h	; выключили мигание 2-х старших разрядов
bcf	fl_kor,fl_kn ; сбросили флаг кнопки коррекция
goto	cikl_bud0	; переход к началу цикла будильника
budkorhas1	btfss	fl_inc,fl_kn ; проверка нажатия кнопки инкремент
; кнопка инкремент НЕ нажата
goto	budkorhas2	; переход к проверке автоповтора инкремента
; кнопка инкремент нажата
bcf	fl_inc,fl_kn ; сброс флага кнопки инкремент
call	inchasbud	; вызов подпрограммы инкремента часов будильника
goto	budkorhas0	; к началу цикла коррекции часов
;-------------------------------

; цикл автоповтора инкремента часов будильника
;==============================================
budkorhas2	btfss	fl_inc,fl_ap ; проверка автоповтора кнопки инкремент
; автоповтор выключен
goto	budkorhas0	; к началу цикла коррекции часов
; автоповтор включен
call	pause_ap	; вызываем подпрограмму паузы автоповтора
btfss	flagi,bit_ap ; проверяем бит автоповтора
; бит автоповтора выключен
goto	budkorhas3
; бит автоповтора включен
bcf	flagi,bit_ap ; сброс бита автоповтора
call	inchasbud	; вызов подпрограммы инкремента часов будильника
budkorhas3	call	budind	; индикация часов-минут будильника
goto	budkorhas2	; переход к началу цикла автоповтора
;-------------------------------


; будильник сработал
;======================
; генерация звука 0,5 сек 1 кГц 0,5 сек 500 Гц в течении трёх секунд
; затем секундная пауза и повтор последовательности
; генерация длится 255 секунд затем возврат в главный цикл
; возврат в главный цикл по нажатию любой кнопки
budilnik	movlw	0FFh
movwf	seczvuk
bcf	flagi,zv_of	; сброс бита окончания звука
bcf	flagi,bu_sr	; сброс флага "будильник сработал"
bcf	flagi,bu_vkl ; сброс флага "будильник включен"
budil_a	movlw	3	; загрузили в аккомулятор счётчик повтора
movwf	Mem	; переправили в регистр счётчика
; звук 1 кГц в течении 0,5 сек
budil0	movlw	.128
movwf	ct256zvuk
bcf	flagi,mctn	; сброс флага ct256zvuk=0
budil1	movlw	B'00010000'	; загрузили в аккомулятор маску для 4-го бита
xorwf	PORTB,F	; инвертировали 4-й бит порта B
call	time0.5ms	; вызвали подпрограмму задержки
btfsc	flagi,zv_of	; проверка флага конец звука
goto	budilend	; флаг установлен - выйти из цикла генерации звука
btfss	flagi,mctn	; проверка на 0 дополнительного счётчика
goto	budil1	; счётчик НЕ равен 0 - переход к началу цикла 1 кГц

; звук 500 Гц в течении 0,5 сек
movlw	.128
movwf	ct256zvuk
bcf	flagi,mctn	; сброс флага ct256zvuk=0
budil2	movlw	B'00010000'	; загрузили в аккомулятор маску для 4-го бита
xorwf	PORTB,F	; инвертировали 4-й бит порта B
call	time1.0ms	; вызвали подпрограмму задержки
btfsc	flagi,zv_of	; проверка флага конец звука
goto	budilend	; флаг установлен - выйти из цикла генерации звука
btfss	flagi,mctn	; проверка на 0 дополнительного счётчика
goto	budil2	; счётчик НЕ равен 0 - переход к началу цикла 500 Гц
decfsz	Mem,F	; декремент счётчика повторов
goto	budil0	; счётчик НЕ =0 - повтор сочетания двух звуков

; секундная пауза
movlw	0FFh
movwf	ct256zvuk
bcf	flagi,mctn	; сброс флага ct256zvuk=0
budil3	btfsc	flagi,zv_of	; проверка флага конец звука
goto	budilend	; флаг установлен - выйти из цикла генерации звука
btfss	flagi,mctn	; проверка на 0 дополнительного счётчика
goto	budil3	; счётчик НЕ равен 0 - переход к началу цикла паузы
goto	budil_a	; повтор всей последовательности

budilend	bcf	flagi,0	; обнуление флага конец звука
goto	ingl_cikl
;-------------------------------
; конец основных циклов
;-------------------------------

;=================================
; Далее расположены подпрограммы
;=================================
; -1-
; Подпрограмма преобразования числа в двоично-десятичный формат
; в аккомуляторе преобразуемое число 0...99
;===============================================================
dd_preo   	movwf	e_rez; загружаем число в ячейку единиц
; разделить число на 10 - получим десятки
d_10	clrf	d_rez; очистка регистра десятков
movlw	0Ah; загрузка в аккомулятор числа 10
bcf	STATUS,C; обнуление флага переноса
d_10_cikl	subwf	e_rez,F; вычитаем из преобразуемого числа 10
btfss	STATUS,C; проверка флага переноса
goto	dd_ed; перенос есть(результат отрицательный), прекращаем вычитание
; пререноса нет
incf	d_rez,F; увеличиваем на 1 регистр десятков
goto	d_10_cikl; продолжаем вычитание	

dd_ed	addwf	e_rez,F; прибавив 10 получим единицы
return	; возврат из подпрограммы преобразования
;-------------------------------
; -2-
; Подпрограмма опроса кнопок в прерывании
;=========================================================
knopki	movlw	ct_kn_kor	; загрузили в аккомулятор адрес 0-го счётчика
movwf	FSR	; переправили в FSR
movf	nom_kn,W	; переправили в аккомулятор номер опрашиваемой кнопки
movwf	temp_kn	; загрузили во временную ячейку
addwf	temp_kn,W	; удвоили номер кнопки так как на кнопку отведено 2 ячейки
addwf	FSR,F	; суммировали номер кнопки с адресом FSR
; адрес счётчика дребезга в FSR установлен

; сдвигаем бит проверяемой кнопки в 5-ю(RB5- кнопка коррекция) позицию
lb_kn_0	movf	PORTB,W	; загрузили PORTB в аккомулятор
movwf	temp1_kn	; переправили во временную ячейку

lb1_kn	movf	temp_kn,F	; команда выставляет флаг Z если регистр =0
btfsc	STATUS,Z	; проверяем номер кнопки на равенство нулю
; номер кнопки =0
goto	lb2_kn	; бит в 5-й позиции ячейки temp1_kn
; номер кнопки >0
rrf	temp1_kn,F	; сдвигаем биты вправо
decf	temp_kn,F	; уменьшаем номер кнопки на 1
goto	lb1_kn	; переход к началу цикла
; бит в 5-й позиции ячейки temp1_kn
; проверяем нажата ли кнопка
lb2_kn	btfss	temp1_kn,5
; кнопка нажата
goto	kn_vkl	; преход к обработке ситуации "кнопка нажата"

; кнопка НЕ нажата
; Сброс флага автоповтора
incf	FSR,F
bcf	INDF,fl_ap
decf	FSR,F
; проверяем счётчик дребезга данной кнопки на заполнение
movlw	019h	; загружаем в аккомулятор число 25 (019 hex)
subwf	INDF,W	; вычитаем из счётчика число 25
btfsc	STATUS,C	; проверяем флаг переноса
; флаг включен - кнопка отпущена после нажатия счётчик >25
clrf	INDF	; обнуляем счётчик дребезга
; флаг выключен(результат отрицательный), счётчик не заполнен
; проверка счётчика дребезга на 0
movf	INDF,F	; выставляем флаг Z при равенстве счётчика 0
btfss	STATUS,Z	; проверяем флаг Z
; счётчик дребезга >0
decf	INDF,F	; уменьшили счётчик на 1
return

; кнопка НАжата
kn_vkl	movlw	.180	; счётчик секунд после последнего нажатия кнопки
movwf	seczvuk	; загружаем в дополнительный счётчик секунд
bcf	flagi,5	; сброс флага выхода из цикла
bsf	flagi,zv_of	; выставляем флаг нажатия кнопки (для выключения будильника)
movlw	019h	; загружаем в аккомулятор число 25 (019 hex)
subwf	INDF,W	; вычитаем из счётчика число 25
btfss	STATUS,Z	; проверяем флаг нуля
; флаг выключен , счётчик не равен 25
goto	lb3_kn	; переход к проверке на автоповтор
; флаг включен, счётчик =25
incf	FSR,F	; установили в FSR адрес ячейки с флагами кнопки
bsf	INDF,fl_kn	; включили флаг "кнопка нажата"
decf	FSR,F	; в FSR адрес счётчика дребезга
; проверка на автоповтор
lb3_kn	movlw	.250	; загружаем в аккомулятор число 250
subwf	INDF,W	; вычитаем из счётчика число 250
btfss	STATUS,C	; проверяем флаг переноса
; флаг выключен(результат отрицательный), счётчик не заполнен
goto	lb4_kn	; переход к инкременту счётчика
; счётчик >250 автоповтор есть
incf	FSR,F	; в FSR адрес ячейки с флагами кнопки
bsf	INDF,fl_ap	; включили флаг автоповтора
return
; инкремент счётчика дребезга
lb4_kn	incf	INDF,F	; увеличили счётчик дребезга на 1
return
;-------------------------------

; -3-
; подпрограмма динамической индикации в прерывании
;==================================================
ind_pre	movlw	ind_0; загрузили в аккомулятор адрес младшего разряда
movwf	FSR  ; переправили в FSR

movf	ct256,W	; загрузили в аккомулятор счётчик прерываний
andlw	B'00000011'	; выключили все биты кроме двух последних
		; в аккомуляторе номер индицируемого разряда
movwf	n_ind	; переправили в ячейку номера индикатора
; вывод цифры в порт A
;***********************
incf	n_ind,F	; увеличили номер индикатора на 1
decf	FSR,F	; уменьшили FSR на 1
clrf	temp_ind	; обнулили временную ячейку
bsf	STATUS,C	; включили флаг переноса
ind_pre00	rlf	temp_ind,F	; сдвигаем бит влево во временной ячейке
incf	FSR,F	; увеличение FSR на 1
decfsz	n_ind,F	; уменьшаем номер индикатора на 1 с проверкой на 0
; номер индикатора > 0
goto	ind_pre00	; возврат на цикл
; номер индикатора = 0 в FSR адрес нужной цифры
; в temp_ind на месте индицируемого бита  1
movf	PORTA,W	; загрузили в аккомулятор значение PORTA
xorwf	INDF,W
andlw	B'11110000' ;
xorwf	INDF,W	; заменили 4 младших бита в аккомуляторе на 
		; цифру индикатора
; в аккомуляторе значение, готовое к выводу в PORTA
movwf	PORTA	; выводим полученный байт в порт A
; включение мигающей точки
bsf	PORTA,4	; выключили мигающую точку
btfss	fl_ind,4	; проверили бит точки
goto	ind_pre_a	; точка выключена
btfsc	ct256,7	; проверяем 1 Гц бит счётчика
bcf	PORTA,4	; сбросили 4-й бит(включили точку) если 1 Гц бит включён

; вывод в порт B
;***********************
; если бит мигания включен, то индикатор мигает с частотой 2 Гц

ind_pre_a	movf	ct256,W	; загрузили в аккомулятор счётчик прерываний
andlw	B'00000011'	; выключили все биты кроме двух последних
		; в аккомуляторе номер индицируемого разряда
movwf	n_ind	; переправили в ячейку номера индикатора
incf	n_ind,F	; увеличили номер индикатора на 1
movf	ct256,W	; загрузили счётчик в аккомулятор
clrf	mask_b	; обнулили маску
movwf	temp1	; загрузили счётчик во временную ячейку
rlf	temp1,F
rlf	temp1,F	; на месте флага переноса - бит 2 Гц	
ind_pre01	rlf	mask_b,F	; сдвигаем бит 2 Гц влево в маске
decfsz	n_ind,F	; уменьшаем номер индикатора с проверкой на 0
; номер индикатора >0
goto	ind_pre01	; уход на цикл
; номер индикатора = 0, в mask_b на месте индицируемого бита - бит 2 Гц
movf	mask_b,W	; загрузили в аккомулятор бит 2 Гц
andwf	fl_ind,W	; логическое И с флагом мигания
xorwf	temp_ind,W	; исключающщее ИЛИ с битом включения разряда
xorlw	B'00001111'	; исключающщее ИЛИ с маскирующим значением
movwf	mask_b	; в mask_b - значение порта B 
		; - индицируемый разряд обнулён(если бит мигания выключен)

movf	PORTB,W
xorwf	mask_b,W
andlw	B'11110000'
xorwf	mask_b,W
movwf	PORTB	; заменили 4 младших бита порта B на результат из маски
return
;-------------------------------

; -4-
; подпрограмма чтения из EEPROM
;=========================================
ee_rd	bsf	STATUS,RP0	; банк 1
movwf	EEADR	; загрузили из аккомулятора адрес для чтения
bsf	EECON1,RD	; читаем EEPROM
ee_rd00	btfsc	EECON1,RD	; проверяем закончено ли чтение
; RD=1 чтение НЕ закончено
goto	ee_rd00	; повтор проверки
; чтение закончено
movf	EEDATA,W	; переписываем данные в аккомулятор
bcf	STATUS,RP0	; банк 0
return		; возврат из подпрограммы
;-------------------------------

; -5-
; подпрограмма записи в EEPROM
;=========================================
ee_wr	bcf	INTCON,GIE	; запрет всех прерываний
bsf	EECON1,WREN	; разрешение записи
movwf	EEDATA	; загрузили записываемое значение из аккомклятора
		; в EEDATA
movlw	0x55	; загрузили в аккомулятор 55h
movwf	EECON2	; переправили в EECON2
movlw	0AAh	; записываем в аккомулятор 0AAh
movwf	EECON2	; переправили в EECON2
bsf	EECON1,WR	; старт записи данных

ee_wr00	btfsc	EECON1,WR	; проверяем закончена ли запись
; WR=1 запись не закончена
goto	ee_wr00	; повтор проверки
; WR=0 запись завершена
bcf	EECON1,WREN	; запрет записи
bcf	EECON1,EEIF	; сброс флага прерывания по окончанию записи
bsf	INTCON,GIE	; разрешение прерываний
return		; возврат из подпрограммы
;-------------------------------

; -6-
; подпрограмма обнуления секунд
;===============================
sec_nol	bcf	INTCON,GIE	; запрет всех прерываний
bcf	T1CON,TMR1ON; выключили таймер TMR1
clrf	ct256	; обнулили счётчик прерываний
movlw	.60	; загрузили в аккомулятор число 60 dec
movwf	sec	; переправили в счётчик секунд
movlw	0F0h	; загрузили в аккомулятор старший полубайт константы
movwf	TMR1H	; переправили в регистр старшего байта таймера		
movlw	0C6h	; загрузили в аккомулятор младший полубайт константы
movwf	TMR1L	; переправили в регистр младшего полубайта таймера
bsf	T1CON,TMR1ON ; включили таймер
bsf	INTCON,GIE	; разрешили прерывания
return		; возврат из подпрограммы
;-------------------------------

; -7-
; подпрограмма паузы автоповтора
;===============================
pause_ap	btfsc	ct256,5	; проверяем бит 4 Гц
; бит 4 Гц включен
goto	pause_ap0	; переход к проверке контрольного бита
; бит 4 Гц ВЫключен
bsf	flagi,kon_bit ; включаем контрольный бит
return		; возврат из подпрограммы
pause_ap0	btfss	flagi,kon_bit ; проверяем контрольный бит
; контрольный бит ВЫключен
return		; возврат из подпрограммы
; контрольный бит включен
bsf	flagi,bit_ap ; установили бит автоповтора
bcf	flagi,kon_bit; сбросили контрольный бит
return		; возврат из подпрограммы
;-------------------------------

; -8-
; ПОДПРОГРАММА ПРЕОБРАЗОВАНИЯ 2-БАЙТНЫХ ДВОИЧНЫХ ЧИСЕЛ В 4-РАЗРЯДНЫЕ ДЕСЯТИЧНЫЕ ЧИСЛА.
;=====================================================================================
bin2_10	bcf	STATUS,C	; Сброс флага переноса-заема.
movlw	.16	; Зпись в регистр Count числа проходов преобразования,
movwf	Count	; равного суммарному количеству битов многоразрядного
		; регистра TimerL/TimerM (8*2=16).

clrf	LED0	; Сброс в 0 содержимого регистра LED0.
clrf	LED1	; -------"------ LED1.
clrf	LED2	; -------"------ LED2.
clrf	LED3	; -------"------ LED3.
Loop16	rlf	TimerL,F	; Циклический сдвиг влево 2-байтного двоичного числа,
rlf	TimerM,F	; записанного в группе регистров TimerL/TimerM

rlf	LED0,F	; Циклический сдвиг влево 2-байтного двоичного числа,
rlf	LED1,F	; записанного в группе регистров LED0/LED1
		; на одну позицию через бит С регистра STATUS.
decfsz	Count,F	; Декремент (-1) содержимого регистра Count с сохранением
		; результата в нем же.
goto	adjDEC	; Если результат не=0, то переход в ПП adjDEC
		; Если  результат =0, то программа исполняется далее.
; Поразрядное распределение содержимого регистров LED0...1 (обоих
; полубайтов) по младшим полубайтам регистров LED0...3.
swapf	LED1,W	; Запись старшего полубайта LED1
andlw	0Fh	; в младший полубайт LED3.
movwf	LED3	; --------------------------------

movfw	LED1	; Запись младшего полубайта LED1
andlw	0Fh	; в младший полубайт LED2.
movwf	LED2	; --------------------------------

swapf	LED0,W	; Запись старшего полубайта LED0
andlw	0Fh	; в младший полубайт LED1.
movwf	LED1	; --------------------------------

movfw	LED0	; Запись младшего полубайта LED0
andlw	0Fh	; в младший полубайт LED0.
movwf	LED0	; --------------------------------
return		; возврат из подпрограммы преобразования
; Запись в регистр FSR адресов регистров LED0...1 для дальнейшей косвенной адресации
; к ним в ПП adjBCD.
adjDEC	movlw	LED0	; Запись в регистр FSR, через регистр W, адреса регистра LED0
movwf	FSR	; с дальнейшим переходом в ПП adjBCD
call	adjBCD	; (адрес следующей команды закладывается в стек).

movlw	LED1	; -----------------------------
movwf	FSR	; То же самое для регистра LED1.
call	adjBCD	; -----------------------------
goto	Loop16	; Проход всех LED (с LED0 по LED1). Переход в ПП Loop16,
		; то есть на следующее кольцо числовых преобразований.
; Основные операции преобразования двоичных чисел в двоично-десятичные:
; операции сложения LED0...3 и констант 03h,30h с условиями по 3-му и 7-му битам.
adjBCD	movlw	3h	; Сложить содержимое текущего LED (LED0...3) с числом 03h,  
addwf	INDF,W	; c записью результата операции, через регистр W,
movwf	Mem	; в регистр Mem.

btfsc	Mem,3	; Анализ состояния 3-го бита регистра Mem.
movwf	INDF	; Если бит № 3 =1, то содержимое регистра Mem 
		; копируется в текущий LED.

movlw	30h	; Если бит №3 =0, то содержимое текущего LED складывается
addwf	INDF,W	; с константой 30h, с последующей записью результата операции,  
movwf	Mem	; через регистр W, в регистр Mem.

btfsc	Mem,7	; Анализ состояния 7-го бита регистра Mem.
movwf	INDF	; Если бит №7 =1, то содержимое регистра Mem 
		; копируется в текущий LED.

retlw	0	; Если бит №7 =0, то регистр W очищается и происходит
		; возврат по стеку в ПП adjDEC.
;-------------------------------

; -9-
; инкремент корректирующей константы
;====================================
konst_inc	bcf	fl_inc,fl_kn; сбросили флаг нажатия кнопки инкремент
movlw	01h	; загрузили в аккомулятор 1
addwf	tempkor_l,F	; инкремент младшего полубайта
movf	STATUS,W
andlw	B'00000001' ; выделяем бит переноса
movwf	Mem	; сохраняем во временной ячейке
movf	tempkor_h,W	; загружаем в аккомулятор старший полубайт константы
sublw	07h	; вычитаем из 7
btfsc	STATUS,Z	; старший полубайт равен 7 ?
; старший полубайт равен 7
goto	kons_max
; НЕ равен
movf	Mem,W	; загружаем бит переноса из Mem
addwf	tempkor_h,F	; суммируем со старшим полубайтом
return
kons_max	btfsc	Mem,0	; проверяем сохранённый бит переноса
decf	tempkor_l,F	; если перенос был- декремент младшего полубайта
return
;-------------------------------

; -10-
; декремент корректирующей константы
;====================================
konst_dec	bcf	fl_bud,fl_kn; сбросили флаг нажатия кнопки будильник (-)
movf	tempkor_l,W	; проверка на 0
iorwf	tempkor_h,W
btfsc	STATUS,Z ; константа =0 ?
; да константа =0
return ; возврат из подпрограммы без декремента
; константа НЕ =0
movlw	01h
subwf	tempkor_l,F	; декремент младшего полубайта
movf	STATUS,W
andlw	B'00000001'	; выделяем бит переноса
xorlw	B'00000001'	; инвертируем бит переноса
subwf	tempkor_h,F	; вычитаем бит переноса из старшего полубайта
return		; возврат из подпрограммы
;-------------------------------

; -11-
; инкремент минут будильника
;============================
incminbud	movlw	.59
subwf	bud_min,W
btfsc	STATUS,Z
goto	incminbud0
incf	bud_min,F
return
incminbud0	clrf	bud_min
return
;-------------------------------

; -12-
; инкремент часов будильника
;=============================
inchasbud	movlw	.23
subwf	bud_has,W
btfsc	STATUS,Z
goto	inchasbud0
incf	bud_has,F
return
inchasbud0	clrf	bud_has
return
;-------------------------------

; -13-
; вывод в младшие разряды индикатора
;====================================
; в аккомуляторе - выводимое однобайтное число
indout_ml	call	dd_preo	; преобразуем число в дес. формат
movf	e_rez,W	; загрузили единицы в аккомулятор
movwf	ind_0	; переправили единицы на индикацию
movf	d_rez,W	; загрузили десятки в аккомулятор
movwf	ind_1	; переправили десятки на индикацию
return		; возврат из подпрограммы
;-------------------------------

; -14-
; вывод в старшие разряды индикатора
;====================================
; в аккомуляторе - выводимое однобайтное число
indout_st	call	dd_preo	; преобразуем число в дес. формат
movf	e_rez,W	; загрузили единицы в аккомулятор
movwf	ind_2	; переправили единицы на индикацию
movf	d_rez,W	; загрузили десятки в аккомулятор
movwf	ind_3	; переправили десятки на индикацию
return		; возврат из подпрограммы
;-------------------------------

; -15-
; вывод на индикатор часов - минут или минут-секунд
;==================================================
hasmin_ind	btfss	flagi,rind ; проверка режима индикации
goto	hmin00
; минуты-секунды
movf	sec,W
sublw	.60
call	indout_ml
movf	min,W
sublw	.60
call	indout_st
return
; часы-минуты
hmin00	movf	min,W
sublw	.60
call	indout_ml	; вывод на индикатор минут
movf	has,W
sublw	.24
call	indout_st	; вывод на индикатор часов
return
;-------------------------------

; -16-
; инкремент минут
;=================
inc_min	decfsz	min,F
return
movlw	.60
movwf	min
return
;-------------------------------

; -17-
; инкремент часов
;=================
inc_has	decfsz	has,F
return
movlw	.24
movwf	has
return
;-------------------------------

; -18-
; индикация часов - минут будильника
;===================================
budind	movf	bud_min,W
call	indout_ml	; вывод минут будильника на индикатор
movf	bud_has,W
call	indout_st	; вывод часов будильника на индикатор
return	
;-------------------------------

; -19-
; подпрограмма проверки срабатывания будильника вызывается из прерывания
;========================================================================
bud_prov	btfss	flagi,bu_vkl ; проверяем включен ли будильник
return		; будильник ВЫключен - возврат
movf	has,W	; загрузили (24-часы) в аккомулятор
sublw	.24	; вычли из 24-х - в аккомуляторе часы
subwf	bud_has,W	; вычли из часов будильника
btfss	STATUS,Z	; проверка результата на 0
return		; результат НЕ нулевой - возврат
movf	min,W	; загрузили (60-минуты) в аккомулятор
sublw	.60	; вычли из 60-ти - в аккомуляторе минуты
subwf	bud_min,W	; вычли из минут будильника
btfsc	STATUS,Z	; проверка результата на 0
bsf	flagi,bu_sr	; результат = 0, установили флаг "будильник сработал"
return		; результат НЕ нулевой - возврат
;-------------------------------

; -20-
; подпрограмма пауза
;=====================
time0.25	movlw	.80
goto	time_load	
time0.5ms	movlw	0xA4
nop
goto	time_load
time1.0ms	movlw	0xff
call	time_load
nop
movlw	0x4a
goto	time_load
time_load	movwf	time_temp
time3f4	decfsz	time_temp,F
goto	time3f4
return
;-------------------------------

; -21-
; подпрограмма вызова звукового сигнала частотой 1 кГц, длительность 1 секунда
;=============================================================================
zvuk1sek	clrf	ct256zvuk
decf	ct256zvuk,F ; установили в счётчик число 255
zvuk1sec0	movlw	B'00010000'	; загрузили в аккомулятор маску для 4-го бита
xorwf	PORTB,F	; инвертировали 4-й бит порта B
; задержка
movlw	.100
movwf	time_temp
zv_cik00	decfsz	time_temp,F
goto	zv_cik00

btfss	flagi,mctn	; проверка на 0 дополнительного счётчика
goto	zvuk1sec0	; счётчик НЕ равен 0 - переход к началу цикла
return
;-------------------------------

; -22-
; Подпрограмма переключения режимов энергопотребления
;====================================================

u_re	btfss	PORTA,5	; проверка напряжения
; напряжения нет RA5=0
goto	u_re00	; переход к проверке флага u_on при RA5=0
; напряжение есть RA5=1
btfsc	flagi1,u_on	; проверка флага u_on
; флаг u_on=1
return		; возврат
; флаг u_on=0 переключаем порты в обычный режим
bsf	STATUS,RP0	; 1-й банк
movlw	B'11100000'	; загрузили в ак-р число для TRISA
		; RA0-RA4 - выходы
		; RA5-RA7 - входы
movwf	TRISA	; переправили в TRISA
movlw	B'11100000'	; загрузили в ак-р число для TRISB
		; RB0-RB4 - выходы
		; RB5-RB7 - входы
movwf	TRISB	; переправили в TRISB
bcf	STATUS,RP0	; 0-й банк	
bsf	flagi1,u_on	; выставляем флаг u_on
return		; возврат
; напряжения нет RA5=0
u_re00	btfss	flagi1,u_on	;проверка флага u_on
; флаг u_on=0 
return		; возврат
; флаг u_on=1 блокируем порты
bsf	STATUS,RP0	; 1-й банк
movlw	B'11111111'	; загрузили в ак-р число для TRISA
		; RA0-RA7 - входы
movwf	TRISA	; переправили в TRISA
movlw	B'11111111'	; загрузили в ак-р число для TRISB
		; RB0-RB7 - входы
movwf	TRISB	; переправили в TRISB
bcf	STATUS,RP0	; 0-й банк	
bcf	flagi1,u_on	; сбрасываем флаг u_on
return		; возврат	
;-------------------------------

end

Изменено пользователем Alex
код

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alex    555

Олег Хай, можно было бы и в виде файла прикрепить, смотрится некрасиво...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Олег Хай, можно было бы и в виде файла прикрепить, смотрится некрасиво...

ну как вышло)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
korsaj    34

В тексте программы замени этот участок программы:

; -13-
; вывод в младшие разряды индикатора
;====================================
; в аккомуляторе - выводимое однобайтное число
indout_ml       call    dd_preo ; преобразуем число в дес. формат
       movf    e_rez,W ; загрузили единицы в аккомулятор
       movwf   ind_0   ; переправили единицы на индикацию
       movf    d_rez,W ; загрузили десятки в аккомулятор
       movwf   ind_1   ; переправили десятки на индикацию
       return          ; возврат из подпрограммы
;-------------------------------

На вот этот:

; -13-
; вывод в младшие разряды индикатора
;====================================
; в аккомуляторе - выводимое однобайтное число
indout_ml
       call    dd_preo ; преобразуем число в дес. формат
       movf    e_rez,W ; загрузили единицы в аккомулятор
btfsc	STATUS,Z
movwf   ind_0   ; переправили единицы на индикацию
bcf	STATUS,Z
xorlw	0x05
btfss	STATUS,Z
goto	next	
       movf    e_rez,W ; загрузили единицы в аккомулятор	
       movwf   ind_0   ; переправили единицы на индикацию
next
       movf    d_rez,W ; загрузили десятки в аккомулятор
       movwf   ind_1   ; переправили десятки на индикацию
       return          ; возврат из подпрограммы
;-------------------------------

И да будет тебе счастье! ))

ЗЫ. Автор выложил исходник с небольшой заковыркой - подсвечивание сегментов на соседних индикаторах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
korsaj    34

Надо задержку между переключением разряда сделать. )

В этом фрагменте меняется значение портА затем значение портБ,

а нужно вначале обнулить портБ , изменить значения потрА, изменить значение портБ и включить.

; -3-
; подпрограмма динамической индикации в прерывании
;==================================================
ind_pre movlw   ind_0; загрузили в аккомулятор адрес младшего разряда

       -              -             -

; вывод цифры в порт A
;***********************
       movf    PORTA,W ; загрузили в аккомулятор значение PORTA
       xorwf   INDF,W
       andlw   B'11110000' ;
       xorwf   INDF,W  ; заменили 4 младших бита в аккомуляторе на 
                       ; цифру индикатора
; в аккомуляторе значение, готовое к выводу в PORTA
       movwf   PORTA   ; выводим полученный байт в порт A

       -           -             -

; вывод в порт B
;***********************
; если бит мигания включен, то индикатор мигает с частотой 2 Гц

       -         -           -

       movf    PORTB,W
       xorwf   mask_b,W
       andlw   B'11110000'
       xorwf   mask_b,W
       movwf   PORTB   ; заменили 4 младших бита порта B на результат из маски
       return
;-------------------------------

ЗЫ. А нет схемы поразборчевее чем в первом посте?

Изменено пользователем korsaj

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
korsaj    34

Вот кусок с испрвлениями:

Начало:

; -3-
; подпрограмма динамической индикации в прерывании
;==================================================
ind_pre 

       movf    PORTB,W
       movwf   TempPortB
movlw	b'11111111'
btfsc	TempPortB,4
	movwf	PORTB
movlw	b'11101111'
btfss	TempPortB,4
movwf	PORTB

movlw   ind_0; загрузили в аккомулятор адрес младшего разряда
       movwf   FSR  ; переправили в FSR

             -          -          -

Конец:

             _          _          _


       movf    TempPortB,W
;        movf    PORTB,W
       xorwf   mask_b,W
       andlw   B'11110000'
       xorwf   mask_b,W
       movwf   PORTB   ; заменили 4 младших бита порта B на результат из маски
       return
;-------------------------------

; -4-
; подпрограмма чтения из EEPROM

ЗЫ. С кнопками тоже фигня какая-то.

Изменено пользователем korsaj

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
korsaj    34

Соберешь узнаешь. Както криво работают или может так задумано (тогда криво задумано).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Adusik    1

Это сырой проект, не доведённый до ума, бросьте его.

Автор живёт здесь: http://www.kaligraf.narod.ru/index.html

Здесь есть всё, доведённый до ума проект со схемой без дешифратора.

Изменено пользователем Adusik

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
lc433    33

Что там за константа коррекции в этих часах? Это как-то связано с перепонением таймера?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: qwer qwer
      Требуется разработать блок управления сплит-системой с функцией обучения по ИК каналу через RS-485 интерфейс на базе МК STM32. Есть ТЗ и список команд управления. Разработка в 2 этапа: 1-разработка принципиальной электрической схемы с указанием элементов на основе структурной из ТЗ (можно в карандаше), 2-написание ПО для МК STM32 в соответствии с ТЗ и списком команд. Оплата поэтапно. Кому интересно - уточняйте детали и оценивайте стоимость работы.
      Блок управления по ИК каналу Описание.docx
      Команды MODBUS.xlsx
    • Автор: Splav
      Речь пойдет о таймере цикличного включения вентиляции гаража.
      Стояла задача обеспечить принудительную вентиляцию гаража.
      Оставлять включенным вентилятор круглые сутки - неоправданно.
      Включать его периодически вручную... Неудобно и лишено смысла.
      Поэтому было решено включать его на определенное время через разные интервалы времени, в зависимости от субъективного восприятия наличия сырости в гараже.
      Вменяемых вариантов в продаже я не нашел.
      Можно, конечно, приобрести на Али программируемый суточный таймер или что-то подобное...
      Да, можно, но мне кажется, что собрать из подручных деталей тоже можно, ну и мозги потренировать.
      За основу был выбран PIC12F675, потому что он у меня был.
      По уму здесь должен стоять PIC12F629, он дешевле, в нем нет АЦП, который в конструкции не используется и отключен.
      Итак.
      Время работы выбрано фиксированным и неизменным - 1 час.
      Время простоя - в зависимости от режима.
      1 час - 2 часа - 3 часа.
      (Изначально я планировал другие задержки: 2-3-5 часов. На практике в моих гаражных условиях эти интервалы оказались слишком большими)
      Индикация осуществляется всего 1 светодиодом.
      Переключение режимов и управление - всего 1 кнопкой.
      Схема:

      Коротко о работе:
      Кнопка.
      Опрос кнопки 10 раз в секунду. Антидребезг и подавление помех 0,3с - 3 опроса подряд кнопка нажата.
      Короткое нажатие на кнопку(от 0,3 до 2 с) - переключение режимов по кругу. 1 - 2 - 3 - OFF - 1 - 2 -  ....
      Длинное нажатие на кнопку (дольше 2 с) - смена состояния реле.
      Если оно было включено - выключается.
      Если было выключено - включается. Интервалы работы реле при этом соответствуют режиму.
      В режиме OFF длинное нажатие ничего не меняет.
      Переключение режима или смена состояния реле происходят при отпускании кнопки.
      Светодиод.
      Индикация режимов светодиодом:
      1 - 1 раз в 2 секунды загорается, если реле не включено. Проблеск света.
            1 раз в 2 секунды гаснет, если реле включено. Проблеск тени.
      2 - 1 раз в секунду загорается, если реле не включено.
            1 раз в секунду гаснет, если реле включено.
      3 - 2 раза в секунду загорается, если реле не включено.
            2 раза в секунду гаснет, если реле включено.
      OFF - загорается раз в 5 секунд. Контроль того, что МК не завис.
      Режимы работы.
      Время работы циклического таймера по режимам:
      1 - 1 час работы / 3 часов отдых. 6/24
      2 - 1 час работы / 2 часа отдых.  8/24
      3 - 1 час работы / 1 часа отдых.  12/24
      Работа.
      При отключении питания, пока не разрядились конденсаторы фильтра, МК отключает все выходы, сохраняет текущие данные в память, ждет 15 сек в таком состоянии и возобновляет работу, если отключение было кратковременным и емкостей фильтра питания хватило.
      Если отключение питания было длительным то, при возобновлении питания, загружает сохраненные данные из памяти и продолжает работу.
      При первом включении, после программирования МК, устройство работает в 1-ом режиме.
      Программа писалась в MPLab X IDE v4.05.
      Прошивка:fan_cycle_timer.hex

      Плата для устройства не разрабатывалась. Все было собрано на макетке.
      В блоке питания использован стандартный трансформатор для монтажа на плату ТПК 2х9V с 2-мя вторичными обмотками на 9В.
      Использовал только одну из них. Вторая - не подключена, в "воздухе"
      Реле - HLS-14F1D-DC12V-C. С обмотка на 12В, и одной группой переключающих контактов на 10А/240VAC.
      Устройство собрано в корпусе щитка для автоматов на 8 модулей. Производитель VIKO.
      Закреплена плата на щиток через резьбовые дистанционные втулки с резьбой М3.
      В качестве вентилятора - вытяжной вентилятор диаметром 125мм ВЕНТС 125С
      Устройство на данный момент отработало в гараже все лето, температура воздуха в тени доходила до 32 градусов.
      Перегревов элементов и зависаний контроллера пока не было.
       
      Несколько фото для общего представления о конструкции.

    • Гость Keil
      Автор: Гость Keil
      Добрый день, ситуация такая - попались мне под руку куча рассыпухи в числе которых достаточное количетво тинек и прочей лабуды - пытась хеловродить, попробовал взять готовый пример работы тиньки и лсдишника здесь также имею ардуинку как  Айсипи и чудесно мигаю светодиодом на мк прошитом ею же  так вот при попытке залить код который по ссылке чуда не произошло.
      курение мануалов лсдишника дало понять лиш одно что старший и младший биты одинаковы с лсдишником со статьи - лсдишник рабочий (игрался контрастом одной строки через V0  и потенциометр ) - как в прочем и мк, было задумано ковырнуть все это в протеусе и атмельстудии, но результатом не увенчалось. Пожалуйста тыкните носом что да где не так.
      fail.zip
    • Автор: В гостях у Михалыча
      Приветики. На днях купил колонку сгоревшую под ремонт. При нажатии на кнопку включения сразу же нагревается микросхема (B6THM1016 1516arz) В интернете вообще нет ничего о ней. Как я понял, это контроллер сенсорных кнопок и питания (даже если включить зарядку, то микруха не греется, пока не нажмешь на кнопку), ибо есть еще две микросхемы, одна из них усилитель, а вторая-блютуз. Может ее получится как-то заменить или выкинуть вообще?