Цифровые часы
Выбор и обоснование технических требований к цифровым часам с будильником. Разработка структурной схемы. Разработка алгоритма управляющей программы. Характеристики, специальные особенности микроконтроллеров PIC16F62X. Характеристика периферийных модулей.
Рубрика | Коммуникации, связь, цифровые приборы и радиоэлектроника |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 08.02.2017 |
Размер файла | 1,6 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
ВВЕДЕНИЕ
В последнее время цифровые устройства стали развиваться приличными темпами. Цифровые приборы во многих отраслях науки и техники стали вытеснять аналоговые. Особое место в цифровой технике заняли микроконтроллеры.
Микроконтроллер -- микросхема, предназначенная для управления электронными устройствами. По сути, это однокристальный компьютер, способный выполнять простые задачи. Использование одной микросхемы, вместо целого набора, как в случае обычных процессоров, применяемых в персональных компьютерах, значительно снижает размеры, энергопотребление и стоимость устройств, построенных на базе микроконтроллеров.
Микроконтроллеры являются основой для построения встраиваемых систем, их можно встретить во многих современных приборах, таких, как телефоны, стиральные машины и т. п. Большая часть выпускаемых в мире процессоров -- микроконтроллеры.
При проектировании микроконтроллеров приходится соблюдать баланс между размерами и стоимостью с одной стороны и гибкостью и производительностью с другой. Для разных приложений оптимальное соотношение этих и других параметров может различаться очень сильно. Поэтому существует огромное количество типов микроконтроллеров, отличающихся архитектурой процессорного модуля, размером и типом встроенной памяти, набором периферийных устройств, типом корпуса и т. д.
В данной курсовой работе предлагается реализовать цифровые часы с будильником с семисегментным индикатором на базе микроконтроллера PIC16F628.
1. выбор и обоснование технических требований к устройству
В соответствии с заданием в данной курсовой работе необходимо разработать цифровые часы с будильником. Рассмотрим принцип работы данного устройства и сформулируем основные технические требования к нему.
Основным элементом устройства является микроконтроллер PIC16F628.
Техническими требованиями к данному проекту являются:
- напряжение питания 5В;
- вывод значения на семисегментный индикатор;
18-выводный FLASH микроконтроллер PIC16F628 входит в состав распространенного семейства PICmicroPIC16CXX. Микроконтроллер этого семейства имеет 8-разрядную, высокопроизводительную и полностью статическую RISC архитектуру.
PIC16F628 имеет 8-уровневый аппаратный стек и большое количество внутренних и внешних прерываний. В гарвардской архитектуре RISC ядра микроконтроллера разделены 14-разрядная память программ и 8-разрядная память данных. Такой подход позволяет выполнять все инструкции за один машинный цикл, кроме команд ветвления, которые выполняются за два машинных цикла. Ядро микроконтроллера поддерживает 35 простых в изучении, но очень эффективных инструкций. Дополнительные регистры управления и архитектурные новшества позволяют создавать высокоэффективные устройства.
Специальные особенности микроконтроллеров PIC16F62X позволяют сократить число внешних компонентов, что в свою очередь снижает стоимость конечного устройства, повышает надежность системы и уменьшает энергопотребление. Дополнительную гибкость в разработках дает широкий выбор режимов работы тактового генератора: ER генератор, наиболее дешевое решение; LP генератор, минимизирует потребляемый ток; XT генератор, для подключения стандартного резонатора; INTRC внутренний RC генератор; HS генератор, для высокоскоростных режимов работы.
Энергосберегающий режим SLEEP, позволяет эффективно использовать микроконтроллеры в устройствах с питанием от батареек или аккумуляторов. Выход из режима SLEEP происходит при возникновении внешних, некоторых внутренних прерываниях и сбросе микроконтроллера. Высоконадежный сторожевой таймер WDT с собственным внутренним RC генератором предотвращает «зависание» программы.
Микроконтроллер PIC16F628 удовлетворяет ряду параметров для его использования от зарядных устройств до удаленных датчиков с малым потреблением электроэнергии. FLASH технология и большое количество периферийных модулей, совместимых с микроконтроллером, позволяет быстро и удобно разрабатывать программное обеспечение. Высокая производительность, малая стоимость, легкость в использовании и гибкость портов ввода/вывода - делают PIC16F628 универсальным микроконтроллером.
В таблице 1.1 представлены основные характеристики микроконтроллера PIC16F628.
Таблица 1.1 -- Основные характеристики микроконтроллера PIC16F628
Быстродействие |
Максимальная тактовая частота (МГц) |
20 |
|
Память |
Flash память программ (слов) |
2048 |
|
Память данных (байт) |
224 |
||
EEPROM память данных (байт) |
128 |
||
Периферия |
Таймеры |
TMR0, TMR1, TMR2 |
|
Компараторов |
2 |
||
Модулей CCP |
1 |
||
Последовательный интерфейс |
USART |
||
Программируемый источник опорного напряжения |
Есть |
||
Дополнительные характеристики |
Число источников прерываний |
10 |
|
Число портов ввода/вывода |
16 |
цифровой часы микроконтроллер алгоритм
Характеристика высокопроизводительного RISC ядра: 35 инструкций; Все команды выполняются за один цикл (200нс), кроме инструкций переходов, выполняющихся за два цикла; Тактовая частота: DC - 20МГц, тактовый сигнал. DC - 200нс, один машинный цикл; Система прерываний; 16 специальных аппаратных регистров; 8-уровневый аппаратный стек; Прямой, косвенный и относительный режим адресации
Характеристика периферийных модулей: 15 независимых портов ввода/вывода; Повышенная нагрузочная способность портов ввода/вывода;
Таймер 0: 8-разрядный таймер/счетчик с 8-разрядным программируемым предделителем; Таймер 1: 16-разрядный таймер/счетчик с возможностью подключения внешнего пьезоэлектрического резонатора; Таймер 2: 8-разрядный таймер/счетчик с 8-разрядным программируемым предделителем и выходным делителем; Последовательный синхронно-асинхронный приемопередатчик USART;16 байт памяти данных, доступных из всех банков.
Специальные функции микроконтроллера: Сброс по включению питания (POR); Таймер сброса (PWRT) и таймер ожидания запуска генератора (OST) после включения питания; Детектор пониженного напряжения (BOD); Сторожевой таймер WDT с собственным RC генератором; Мультиплицируемый вывод -MCLR; Программируемые подтягивающие резисторы на входах PORTB; Программируемая защита памяти программ; Низковольтный режим программирования; Режим энергосбережения SLEEP; Программирование в готовом устройстве (используется два вывода микроконтроллера); Программируемые пользователем биты ID;
Выбор параметров тактового генератора:
- FLASH биты выбора параметров тактового генератора
- ER генератор 4.3067 0 T(внешний резистор)
- Уменьшение числа внешних компонентов
- Двухскоростной внутренний RC генератор
- Работа в режиме малого потребления
- EC внешний тактовый сигнал
- XT режим генератора
- HS режим генератора
- LP режим генератора
CMOS технология: Высокоскоростная, энергосберегающая CMOS FLASH технология (0.7 микрон); Полностью статическая архитектура; Широкий диапазон напряжений питания: от 3.0 до 5.5В; Коммерческий, индустриальный и расширенный температурные диапазоны; Малое энергопотребление;
В состав микроконтроллера входит: сброс по включению питания PWRT, сторожевой таймер WDT, программируемая защита кода программы и высокая нагрузочная способность портов ввода/вывода.
Микроконтроллер PIC16F628 программируется в последовательном режиме с использованием двух выводов RB6 и RB7.
На рисунке 1.1 представлено расположение выводов микроконтроллера PIC16F628 в PDIP корпусе, а на рисунке 1.2 схема микроконтроллера.
Рисунок 1.1 - Расположение выводов микроконтроллера PIC16F628
Рисунок 1.2 - Схема микроконтроллера PIC16F628
2. разработка структурной схемы УСТРОЙСТВА
В данной работе необходимо разработать цифровые часы с будильником на семисегментном индикаторе. Структурная схема проекта состоит из четырех функциональных блоков (рисунок 2.1): клавиатура, микроконтроллер (МК), дисплей, динамик.
Рисунок 2.1 - Структурная схема цифровых часов с будильником на семисегментном индикаторе
Функции блоков:
-Клавиатура - для цифровой установки режима работы;
-Микроконтроллер (основной узел) - формирует сигнал;
-Дисплей - для отображения времени часов и будильника;
-Динамик - для звуковой индикации.
Основой проектируемого устройства является микроконтроллер (МК). На него возлагаются такие задачи как управление семисегментным индикатором и подача сигнала будильника на динамик. микроконтроллер выполняет обработку полученной информации и выполняет действия согласно заданной программе. Основой блока МК является микроконтроллер PIC16F628.
Стабилизированное и фильтрованное питание поступает с источника питания на блок МК, дисплей и динамик. Блок семисегментного дисплея отображает взаимодействие проектируемого устройства с пользователем посредством визуального отображения информации. Для проектируемого устройства был выбран семисигментный индикаторный дисплей REC-S5461AG-G.
3. РАЗРАБОТКА ПРИНЦИПИАЛЬНОЙ СХЕМЫ УСТРОЙСТВА
Принципиальная схема разработана в соответствии со структурной схемой. Как видно из схемы часов (рисунок 3.1), микроконтроллер PIC16F628 является единственной микросхемой, используемой в данном устройстве.
Для задания тактовой частоты к выводам 15 и 16 подключен внешний кварцевый резонатор QR1 на 4 МГц.
Керамические конденсаторы С2 и С3 по 33 пФ введены для обеспечения уверенного запуска кварцевого резонатора. К выводам 1, 2, 3, 11, 12, 13, 17, 18 подключен семисегментный дисплей HL1 (REC-S5461AG-G) с общим анодом, аноды которого подключены к выводам 6 - 9 микроконтроллера. Для обеспечения ограничения тока на индикатор на выводы 1, 2, 3, 11, 12, 13, 17, 18 подключены токоограничивающие резисторы R1 - R8 по 1 кОм.
Для управления индикацией времени к выводам 6 - 9 присоединены кнопки SA1 - SA4 без фиксации.
В качестве выхода для сигнала будильника используется вывод 10, к которому присоединен динамик BA1, а в качестве усилителя - каскад на транзисторах VT1, VT2.
Рабочее напряжение питания схемы 5В.
В таблице 3.1 приведена перечень элементов, используемых в схеме.
Рисунок 3.1 - Принципиальная схема цифровых часов с будильником.
Таблица 3.1 - Перечень элементов принципиальной схемы
Поз. Обо-значение |
Наименование |
Кол. |
Примечание |
|
Конденсаторы |
||||
С1 |
Электролитический конденсатор, 100 мкФ |
1 |
||
С2, С3 |
Конденсатор кепамический 33 пФ |
2 |
||
С4 |
Электролитический конденсатор 0,1 мкФ |
1 |
||
Кварцевые резонаторы |
||||
QR1 |
Кварцевый резонатор 4 МГц |
1 |
||
Транзисторы |
||||
VT1 |
Кремниевый биполярный транзистор КТ315 |
1 |
||
VT2 |
Кремниевый биполярный транзистор КТ361 |
1 |
||
Резисторы |
||||
R1-R8 |
Резистор 1 кОм |
8 |
||
R9, R12-R15 |
Резистор 2,2 мОм |
5 |
||
R10, R11 |
Резистор 10 кОм |
2 |
||
Микросхемы |
||||
DD1 |
Микроконтроллер PIC16F628 |
1 |
||
Дисплей |
||||
HL1 |
Семисегментный индикатор REC-S5461AG-G |
1 |
||
Кнопки |
||||
SA1-SA4 |
Кнопки тактовые 0613HIM-130G-G |
4 |
||
Динамик |
||||
BA1 |
Динамик 3 Ом 3 Вт |
1 |
4. разработка алгоритма управляющей программы
Для обеспечения работы проектируемого устройства в соответствии с заданными техническими требованиями необходимо запрограммировать микроконтроллер на определённую обработку и выдачу данных. Для составления программы необходимо сначала составить алгоритм работы устройства, т.е. конечный набор правил для выполнения некоторых процедур. Условно алгоритм работы можно разделить на составные части: инициализация переменных и констант, главный цикл программы, цикл коррекции и будильник.
На рисунке 4.1 представлена общая блок-схема программы.
gl_cikl - главный цикл программы.
Рисунок 4.1 - общая блок-схема программы
На рисунке 4.2 представлена блок-схема подпрограммы цикла коррекции.
Рисунок 4.2 - подпрограмма Cikl_kor
На рисунке 4.3 представлена блок-схема подпрограммы Cikl_kors0, которая отвечает за настройку секунд.
Sec_nol - подпрограмма инкремента секунд.
Рисунок 4.3 - блок-схема подпрограммы Cikl_kors0
На рисунке 4.4 представлена блок-схема подпрограммы Ci_kormin, которая отвечает за коррекцию минут.
Inc_min - подпрограмма инкремента минут.
Рисунок 4.4 - блок-схема подпрограммы Ci_kormin
На рисунке 4.5 представлена блок-схема подпрограммы Ci_korhas, которая отвечает за настройку часов.
Inc_has - подпрограмма инкремента часов.
Рисунок 4.5 - блок-схема подпрограммы Ci_korhas
На рисунке 4.6 представлена блок-схема подпрограммы Budkormin, которая отвечает за настройку минут будильника.
Incminbud - подпрограмма инкремента минут будильника.
Рисунок 4.6 - блок-схема подпрограммы budkormin
На рисунке 4.7 представлена блок-схема подпрограммы budkorhas, которая отвечает за настройку часов будильника.
Inchasbud - инкремент часов будильника.
Cikl_bud0 - начало цикла будильника.
Рисунок 4.7 - блок-схема подпрограммы budkorhas
5. РАЗРАБОТКА УПРАВЛЯЮЩЕЙ ПРОГРАММЫ
Для написания программы микроконтроллера для разрабатываемого устройства был выбран язык Assembler.
Написание программы, её отладка и компиляция осуществляется с помощью интегрированной среды разработки MPLAB IDE v7.20 для PIC.
Листинг программы с подробным описанием в комментариях:
; Программа ЧАСЫ на PIC16F628 (Тактовая частота 4 Мгц)
;
; Декремент счётчика ct256 происходит 256 раз в секунду
; в программе прерывания по переполнению таймера TMR1.
; ===================================================
list p=16f628 ;задали тип контроллера
include <p16F628.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
;-------------------------------
; конец основных циклов
;-------------------------------
;=================================
; преобразование числа в двоично-десятичный формат
; в аккомуляторе преобразуемое число 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 ; возврат из подпрограммы преобразования
;-------------------------------
; опрос кнопок в прерывании
;======================================================
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
;-------------------------------
; динамическая индикация в прерывании
;==================================================
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
;-------------------------------
;чтение из EEPROM
;=========================================
ee_rd bsf STATUS,RP0 ; банк 1
movwf EEA...
Подобные документы
В работе на базе PIC-контроллера реализуется цифровой секундомер. Выбор технических требований к устройству, к питанию. Разработка структурной схемы, принципиальной электрической схемы, алгоритма работы управляющей программы, управляющей программы.
курсовая работа [427,1 K], добавлен 20.06.2008Выбор и обоснование основных технических решений микроконтроллера. Разработка алгоритма рабочей программы. Расчет потребляемой мощности и определение требований к источникам питания. Описание модулей программы и ее отдельных функциональных модулей.
курсовая работа [210,3 K], добавлен 25.11.2013Характеристика микропроцессора Z80, его достоинства и система команд. Проектирование интерфейса, структурной схемы и алгоритма работы управляющей микро-ЭВМ. Разработка модулей памяти, генератора тактового импульса, контроллера, ввода/вывода и индикатора.
курсовая работа [1,7 M], добавлен 17.02.2014Основные типы микроконтроллеров. Разработка структурной схемы прибора. Работа матричного индикатора HCMS-2000. Разработка принципиальной схемы. Расчет режимов элементов. Разработка алгоритма программы. Последовательный интерфейс обмена данными.
курсовая работа [650,6 K], добавлен 12.01.2016Разработка структурной и принципиальной схемы устройства. Микроконтроллер PIC16F886, температурные и электрические характеристики. Четырехразрядный семисегментный светодиодный индикатор. Разработка алгоритма управляющей программы, общий алгоритм.
курсовая работа [497,4 K], добавлен 31.01.2013Однокристальные микро-ЭВМ, предназначенные для использования в бытовой радиоэлектронной аппаратуре. Обоснование технических требований к устройству. Разработка структурной и принципиальной электрической схем устройства. Алгоритм управляющей программы.
курсовая работа [159,9 K], добавлен 19.06.2010Особенности проектирования микропроцессорного устройства "Цифровой осциллограф". Выбор микроконтроллера, описание периферийных устройств. Разработка принципиальной схемы устройства и программы для микроконтроллера, осуществляющей все функции устройства.
курсовая работа [923,5 K], добавлен 24.12.2012Разработка блока управления, управляющей программы, структурной и электрической схем высокомоментного линейного привода с цифровым программным управлением на базе современных компьютерных технологий. Математический расчет его динамических характеристик.
дипломная работа [2,4 M], добавлен 22.10.2010Разработка и обоснование структурной схемы цифрового корректирующего фильтра. Обоснование общего алгоритма его функционирования. Оценка быстродействияустройства. Отладка разработанной программы. Составление принципиальной схемы устройства и ее описание.
курсовая работа [774,7 K], добавлен 03.12.2010Описание алгоритма работы и разработка структурной схемы микропроцессорной системы управления. Разработка принципиальной схемы. Подключение микроконтроллера, ввод цифровых и аналоговых сигналов. Разработка блок-схемы алгоритма главной программы.
курсовая работа [3,3 M], добавлен 26.06.2016Разработка структурной и принципиальной схем микропроцессорного тахометра. Микроконтроллер PIC16F886 и устройство индикации тахометра. Основные температурные и электрические характеристики микроконтроллера. Разработка алгоритма управляющей программы.
курсовая работа [527,0 K], добавлен 07.07.2013Разработка структурной схемы устройства. Принцип работы его блоков: источника напряжения, цифрового программируемого устройства, семисегментного дисплея, датчиков давления и температуры. Разработка алгоритма работы управляющей программы, ее блок-схема.
курсовая работа [2,5 M], добавлен 23.06.2015Разработка и обоснование общего алгоритма функционирования устройства. Выбор однокристального микропроцессора повышенной производительности. Написание управляющей программы на языке микропроцессора. Расчет амплитудно-частотной характеристики фильтра.
курсовая работа [113,8 K], добавлен 04.12.2010Техническое обоснование структурной схемы и разработка универсального источника бесперебойного питания с цифровым управлением. Электрический расчет силовых элементов и структурной схемы Line-interractive устройства. Расчет себестоимости блока питания.
дипломная работа [883,1 K], добавлен 09.07.2013Параметры, характеристики, схемы и назначение выводов микроконтроллера. Разработка программы, реализующей взаимодействие со сторонними устройствами, вместе образующих устройство часов с функцией будильника. Электрическая схема разрабатываемого устройства.
курсовая работа [406,5 K], добавлен 12.09.2012Разработка структурной схемы системы и ее описание. Матричная клавиатура AK1604A-WWB. Жидкокристаллический индикатор, часы реального времени. Интерфейс процессора с памятью. Разработка программы для микроконтроллера. Резидентный загрузчик НЕХ202.
курсовая работа [1,0 M], добавлен 01.02.2014Семейство однокристальных микроконтроллеров HCS12. Внутренняя или неявная адресация INH. Команды загрузки и пересылки данных, битовых операций, вызова подпрограмм и перехода в режимы пониженного энергопотребления. Основная блок-схема алгоритма, листинг.
курсовая работа [453,4 K], добавлен 04.06.2014Разработка цифровых часов, отображающих время посредством светодиодной индикации. Выбор и обоснование структурной схемы и электрорадиоэлементов: резисторов, светодиодов. Определение средней наработки на отказ. Процесс программирования PIC-контроллера.
дипломная работа [1,1 M], добавлен 12.05.2016Обзор и сравнительный анализ методов измерения уровня жидкости. Основные виды уровнемеров. Выбор структурной схемы, разработка и расчет ее узлов. Разработка алгоритма программы для микроконтроллера. Расчет технико-экономических показателей проекта.
дипломная работа [1,1 M], добавлен 12.05.2013Этапы разработки микропроцессорной системы на основе микроконтроллера. Общая характеристика солнечных часов. Разработка схемы, программного обеспечения и алгоритма управления солнечных часов. Технико-экономическое обоснование разработки и охрана труда.
дипломная работа [5,9 M], добавлен 16.07.2010