'===============================================================================
'*
'* Автор: Sasha_1973
'* Дата: 14.01.2014 г.
'*
'* МК: ATmega8А
'* Тактовая частота МК: 1 MГц
'*
'* Скорость передачи USART: 9600 бод
'*
'* Компилятор: BASCOM-AVR 2.0.7.1
'* Используемый шрифт в Bascom: Consolas; размер = 14
'*
'* Программа симулятор: Proteus 7.10 SR0
'*
'* Описание:
'* Реализация программных часов на TIMER2, кварц 32768 кГц на выводах XTAL1(PB6) и XTAL2(PB7)
'*
'===============================================================================
'------------------- Настройка контроллера -----------------------------------
$map ' Получаем карту распределения памяти компилятором Bascom
$regfile = "m8def.dat" ' Используемый контроллер
$crystal = 1000000 ' 2000000 ' 4000000 ' 8000000
$framesize = 32
$hwstack = 40
$swstack = 16
'-------------------------- Настройка USART ----------------------------------
$baud = 4800 '1200 '2400 '4800 '9600 '19200 '38400 '57600 '115000
Ucsra.1 = 1 ' Двойная скорость работы USART, скорость трансляции = $baud * 2
'--- Настройка прерывания TIMER2, для работы часов (раскомментировать нужное)
' Config Timer2 = Timer , Async = On , Prescale = 64 ' Делитель 32768 / 64 / 256 = 0,5 сек (прерывание TIMER2 = 2 раза в секунду)
' Const Количество_срабатываний_timer2 = 2
'---------------------------------------------------------------
Config Timer2 = Timer , Async = On , Prescale = 128 ' Делитель 32768 / 128 / 256 = 1 сек (прерывание TIMER2 = 1 раз в секунду)
Const Количество_срабатываний_timer2 = 1 ' Значение константы используется в подпрограмме "Обработка_прерывания_timer2"
' Ссылка на подпрограмму обработчика прерывания TIMER2, для работы часов
On Timer2 Обработка_прерывания_timer2 Nosave ' Ссылка на подпрограмму обработчика прерывания TIMER2
'--------------- Настройка пониженного энергопотребления МК ------------------
Assr.3 = 1 : Waitms 100 ' Включить НЧ-генератор AS2 и подождать стабилизации амплитуды генератора
' При включении бита AS2 (3) в регистре ASSR (ASSR.3), становится возможным применение режима
' "Powersave" - разновидность спящего режима. Пробуждение МК от TIMER2
' Mcucr = &B10000000 ' Разрешаем режим пониженного энергопотребления Power Idle
Mcucr = &B10110000 ' Разрешаем режим пониженного энергопотребления Power Save
'----------------------- Используемые переменные -----------------------------
Dim Часы As Byte
Dim Минуты As Byte
Dim Секунды As Byte
Dim Время_работы_часы As Byte
Dim Время_работы_минуты As Byte
Dim Время_работы_секунды As Byte
Dim Флаг_работа_окончена As Byte
Dim Осталось_работать_часы As Byte
Dim Осталось_работать_минуты As Byte
Dim Осталось_работать_секунды As Byte
Dim Счетчик_прерываний_timer2 As Byte
Dim Флаг_обновить_данные_времени As Byte
Dim Флаг_данные_для_передачи_usart As Byte
'------------------------ Предварительные настройки --------------------------
Часы = 20
Минуты = 50
Секунды = 0
Осталось_работать_часы = 1
Осталось_работать_минуты = 0
Осталось_работать_секунды = 0
'------------------- Передайм настройки времени в USART ----------------------
Print "Настройки времени"
Print Часы ; ":" ; Минуты ; ":" ; Секунды : Print
Wait 1
'-------------- Разрешаем работу необходимых прерываний ----------------------
Enable Timer2
'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================
' Г Л А В Н Ы Й Ц И К Л
'===============================================================================
Главный_цикл:
If Флаг_обновить_данные_времени = 1 Then
Gosub Расчет_времени_работы
Gosub Обновить_данные_времени
Gosub Расчет_осталось_работать
Флаг_обновить_данные_времени = 0
Флаг_данные_для_передачи_usart = 1
Goto Главный_цикл
End If
If Флаг_данные_для_передачи_usart = 1 Then
Gosub Передача_uart
Флаг_данные_для_передачи_usart = 0
Goto Главный_цикл
End If
'-----------------------
Спящий_режим:
sleep ' или так Power Powersave
Goto Главный_цикл
End
'===============================================================================
' И С П О Л Ь З У Е М Ы Е П О Д П Р О Г Р А М М Ы
'===============================================================================
'===============================================================================
' Подпрограмма обработки прерывания TIMER2, происходит 1 или 2 раза в секунду, в зависимости от настроек TIMER2
'===============================================================================
Обработка_прерывания_timer2:
'-------------------------------------------------------------------------------
'---- Сохраняем регистры, которые используем в обработке прерывания
!Push R31 ' Сохраняем регистры, которые используем в обработке прерывания
!In R31 , Sreg
!Push R31
'------------------ Считаем количество прерываний TIMER2 ---------------------
!Lds R31 , {счетчик_прерываний_timer2} ' Считываем значение переменной "Счетчик_прерываний_timer2" в регистр "R31", для последующих операций
!Inc R31 ' Увеличиваем значение переменной в регистре "R31"
!sts {счетчик_прерываний_timer2} , R31 ' Пишем значение из регистра "R31" в переменную "Счетчик_прерываний_timer2"
'------------------
!Andi R31 , количество_срабатываний_timer2 ' Сравниваем полученное значение с значением "Const количество_срабатываний_timer2"
'------------------
!Breq Выход_прерывание_timer2 ' Если полученное значение меньше значениея "Const количество_срабатываний_timer2", уходим на метку "Выход_прерывание_timer2" -- иначе
!clr R31 ' Если полученное значение равно значениию "Const количество_срабатываний_timer2", пишем "0" в регистр "R31
!sts {счетчик_прерываний_timer2} , R31 ' Заносим значение из регистра "R31" в переменную "Счетчик_прерываний_timer2" и переходим к подпрограмме расчета времени
'-------- Подпрограммы обрабатываемые по 2 срабатыванию TIMER2 ---------------
!ldi R31 , 1
!sts {Флаг_обновить_данные_времени} , R31 ' Поднимаем флажок, что надо обновить время
'--------------- Восстанавливаем ранее сохраненные регистры ------------------
Выход_прерывание_timer2:
!Pop R31
!Out Sreg , R31 ' Восстанавливаем регистры
!Pop R31
'-------------------------------------------------------------------------------
Return
'===============================================================================
'===============================================================================
'----------- Подпрограмма расчета времени: часов, минут и секунд ---------
'===============================================================================
Обновить_данные_времени:
'-------------------------------------------------------------------------------
Incr Секунды ' Плюс секунда
If Секунды > 59 Then ' При необходимости
Секунды = 0 : Goto Обновить_минуты ' корректируем счетчик секунд и обновляем счетчик минут
End If
Goto Выход_обновить_данные_времени
'----------------------------------------------------
Обновить_минуты:
'----------------------------------------------------
Incr Минуты ' Плюс минута
If Минуты > 59 Then ' При необходимости
Минуты = 0 : Goto Обновить_часы ' корректируем счетчик минут и обновляем счетчик часов
End If
Goto Выход_обновить_данные_времени
'----------------------------------------------------
Обновить_часы:
'----------------------------------------------------
Incr Часы ' Плюс час
If Часы > 23 Then ' При необходимости
Часы = 0 ' корректируем счетчик часов
End If
'-------------------------------------------------------------------------------
Выход_обновить_данные_времени:
'-------------------------------------------------------------------------------
Return
'===============================================================================
'===============================================================================
Расчет_времени_работы:
'-------------------------------------------------------------------------------
nop
Incr Время_работы_секунды ' Плюс секунда
If Время_работы_секунды > 59 Then ' При необходимости
Время_работы_секунды = 0 : Goto Обновить_время_работы_минуты ' корректируем счетчик секунд и обновляем счетчик минут
End If
Goto Выход_расчет_времени_работы
'----------------------------------------------------
Обновить_время_работы_минуты:
'----------------------------------------------------
Incr Время_работы_минуты ' Плюс минута
If Время_работы_минуты > 59 Then ' При необходимости
Время_работы_минуты = 0 : Goto Обновить_время_работы_часы ' корректируем счетчик минут и обновляем счетчик часов
End If
Goto Выход_расчет_времени_работы
'----------------------------------------------------
Обновить_время_работы_часы:
'----------------------------------------------------
Incr Время_работы_часы ' Плюс час
If Время_работы_часы > 23 Then ' При необходимости
Время_работы_часы = 0 ' корректируем счетчик часов
End If
Выход_расчет_времени_работы:
nop
'-------------------------------------------------------------------------------
Return
'===============================================================================
'===============================================================================
Расчет_осталось_работать:
'-------------------------------------------------------------------------------
nop
If Осталось_работать_секунды = 0 Then ' При необходимости
Осталось_работать_секунды = 59 : Goto Обновить_осталось_работать_мин ' корректируем счетчик секунд и обновляем счетчик минут
End If
Decr Осталось_работать_секунды ' Минус секунда
Goto Выход_расчет_осталось_работать
'----------------------------------------------------
Обновить_осталось_работать_мин:
'----------------------------------------------------
If Осталось_работать_минуты = 0 Then ' При необходимости
Осталось_работать_минуты = 59 : Goto Обновить_осталось_работать_часы ' корректируем счетчик минут и обновляем счетчик часов
End If
Decr Осталось_работать_минуты ' Минус минута
Goto Расчет_осталось_работать
'----------------------------------------------------
Обновить_осталось_работать_часы:
'----------------------------------------------------
If Осталось_работать_часы = 0 And Осталось_работать_минуты = 0 And Осталось_работать_секунды = 0 Then ' При необходимости
Флаг_работа_окончена = 1
' Осталось_работать_часы = 0 ' корректируем счетчик часов
End If
Decr Осталось_работать_часы ' Минус час
Выход_расчет_осталось_работать:
nop
'-------------------------------------------------------------------------------
Return
'===============================================================================
'===============================================================================
'--- Подпрограмма обработки вывода на компьютер (аппаратный USART)
'===============================================================================
Передача_uart:
'-------------------------------------------------------------------------------
Print
Print "Время работы - " ;
Print Время_работы_часы ; ":" ;
If Время_работы_минуты < 10 Then Print "0" ;
Print Время_работы_минуты ; ":";
If Время_работы_секунды < 10 Then Print "0" ;
Print Время_работы_секунды
Print "Текущее время - " ;
Print Часы ; ":" ;
If Минуты < 10 Then Print "0" ;
Print Минуты ; ":";
If Секунды < 10 Then Print "0" ;
Print Секунды
Print "Осталось работать - " ; Осталось_работать_часы ; ":" ; Осталось_работать_минуты ; ":" ; Осталось_работать_секунды
Print
'-------------------------------------------------------------------------------
Return
'===============================================================================