Олег Хай Опубликовано 12 августа, 2012 Поделиться Опубликовано 12 августа, 2012 Здрасте, хочу сделать часы с индексацией на табло минут с интервалом каждые 5 минут. Есть схема исходник только не знаю что там надо подправить чтобы интервал был 5 минут а не каждую 1 минуту. -1 Ссылка на комментарий Поделиться на другие сайты Поделиться
forbidden11 Опубликовано 12 августа, 2012 Поделиться Опубликовано 12 августа, 2012 Да, там нужно кое-что подправить. Для более развернутого ответа нужно побольше информации 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
Dmitron Опубликовано 13 августа, 2012 Поделиться Опубликовано 13 августа, 2012 надо текст программы поправить 2 Решаю любые проблемы кроме своих. скайп sidatel uselect-el(dot)ucoz.com Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
wws63 Опубликовано 13 августа, 2012 Поделиться Опубликовано 13 августа, 2012 Для начала выложите исходник программы 0 Опыт - это то, что получаешь, не получив того, что хотел Ссылка на комментарий Поделиться на другие сайты Поделиться
Олег Хай Опубликовано 13 августа, 2012 Автор Поделиться Опубликовано 13 августа, 2012 (изменено) ; Программа ЧАСЫ на 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 Изменено 13 августа, 2012 пользователем Alex код 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
wws63 Опубликовано 13 августа, 2012 Поделиться Опубликовано 13 августа, 2012 А с использованием тега code можно? 0 Опыт - это то, что получаешь, не получив того, что хотел Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 13 августа, 2012 Поделиться Опубликовано 13 августа, 2012 Олег Хай, можно было бы и в виде файла прикрепить, смотрится некрасиво... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Олег Хай Опубликовано 13 августа, 2012 Автор Поделиться Опубликовано 13 августа, 2012 Олег Хай, можно было бы и в виде файла прикрепить, смотрится некрасиво... ну как вышло) 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
korsaj Опубликовано 14 августа, 2012 Поделиться Опубликовано 14 августа, 2012 В тексте программы замени этот участок программы: ; -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 ; возврат из подпрограммы ;------------------------------- И да будет тебе счастье! )) ЗЫ. Автор выложил исходник с небольшой заковыркой - подсвечивание сегментов на соседних индикаторах. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Олег Хай Опубликовано 14 августа, 2012 Автор Поделиться Опубликовано 14 августа, 2012 а что надо сделать чтобы соседние сегменты не подсвечивались? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
korsaj Опубликовано 14 августа, 2012 Поделиться Опубликовано 14 августа, 2012 (изменено) Надо задержку между переключением разряда сделать. ) В этом фрагменте меняется значение портА затем значение портБ, а нужно вначале обнулить портБ , изменить значения потрА, изменить значение портБ и включить. ; -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 ;------------------------------- ЗЫ. А нет схемы поразборчевее чем в первом посте? Изменено 14 августа, 2012 пользователем korsaj 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
korsaj Опубликовано 14 августа, 2012 Поделиться Опубликовано 14 августа, 2012 (изменено) Вот кусок с испрвлениями: Начало: ; -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 ЗЫ. С кнопками тоже фигня какая-то. Изменено 14 августа, 2012 пользователем korsaj 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Олег Хай Опубликовано 14 августа, 2012 Автор Поделиться Опубликовано 14 августа, 2012 а че с кнопками по разборчивей ничего нету( 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
korsaj Опубликовано 14 августа, 2012 Поделиться Опубликовано 14 августа, 2012 Соберешь узнаешь. Както криво работают или может так задумано (тогда криво задумано). 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Adusik Опубликовано 11 сентября, 2012 Поделиться Опубликовано 11 сентября, 2012 (изменено) Это сырой проект, не доведённый до ума, бросьте его. Автор живёт здесь: http://www.kaligraf.narod.ru/index.html Здесь есть всё, доведённый до ума проект со схемой без дешифратора. Изменено 11 сентября, 2012 пользователем Adusik 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
lc433 Опубликовано 11 декабря, 2012 Поделиться Опубликовано 11 декабря, 2012 Что там за константа коррекции в этих часах? Это как-то связано с перепонением таймера? 0 Слава антисионистам Владимиру Путину и Владимиру Квачкову! Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.