В данной статье будет рассмотрен вариант сканирования клавиатуры параллельно с разрядами
7-ми сегментных светодиодных индикаторов именно в среде компилятора "Bascom", а именно: динамическая индикация в 4-х разрядах + сканирование 4-х кнопок, попутно получились софтовые часики
Обратите внимание, 7-seg LED можно ставить любые (с соответствующей коррекцией программы и схемы, что-бы соблюдались условия автовыбора типа индикатора), ОА и ОК с высотой символа до 38мм (проверялось в железе), желательно подобрать резисторы в цепи сегментов индикатора, по току, согласно документации на индикаторы ).
Сопротивление в цепи разряда индикатора, на корпус, ~47к. Сопротивление в цепи клавиатуры 100к ±5к, подобранно эксперементально, в противном случае, не работает клавиатура при разных ( ОА, ОК ) индикаторах.
Исходник
'******************************************************************************* '* Revision : 1.0 * '* Controller : ATMEGA8A * '* Compiler : BASCOM-AVR 2.0.7.1 * '* Author : sasha_1973* '******************************************************************************************************* '------------------------------------------------------------------------------------------------------- $regfile = "m8def.dat" : $crystal = 1000000 : $hwstack = 40 : $swstack = 16 : $framesize = 32 : $baud = 4800 '1200 '2400 '4800 '9600 '19200 '38400 '57600 '115000 '------------------------------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- Sim: ' $sim '------------------------------------------------------------------------------- '******************************************************************************************************* '------------------------------------------------------------------------------- $lib "mcsbyte.lbx" $lib "mcsbyteint.lib" '------------------------------------------------------------------------------- '************************************************************************************************************************************************************************************************** '-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ' Config Adc = Single , Prescaler = Auto , Reference = Avcc ' Prescaler может быть 2,4,8,16,32,64 или Auto, в случае Auto компилятор выбирает подходящую частоту работы АЦП. ' Config Adc = Free , Prescaler = 32 , Reference = Avcc ' Источник опорного напряжения Reference может быть: Aref – внешний источник, Avcc – напряжение питания схемы и Internal – внутренний ' Режимы считывания: Single - единичное считывание, результаты заносятся в ADCL, ADCH; Free – постоянное считывание, результаты заносятся в ADCL, ADCH, но происходит всё автономно ' Enable Adc ' Разрешаем работу АЦП '--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- '*************************************************************************************************************************************************************************************************** '------------------------------------------------------------------------------- '------------ Конфигурация TIMER0 - обработка 7-seg индикатора ------------ '******************************************************************************* '************************* Конфигурация TIMER0 ************************* '******************************************************************************* '------------------------------------------------------------------------------- Config Timer0 = Timer , Prescale = 1024 , Clear Timer = 0 ' конфигурируем таймер индикации PRESCALE = 1|8|64|256|1024 '------------------------------------------------------------------------------- On Timer0 Обработка_прерывания_timer0 ' Nosave 'Подпрограмма обработка прерывания timer0 '------------------------------------------------------------------------------- Tcnt0 = 254 ' Делитель 1000/(1000000/1024/(256-251))= 1000/(976,5625/5)=1000/195,3125=5,12 5,12 ms '******************************************************************************* '************************* Конфигурация TIMER2 ************************* '******************************************************************************* '------------------------------------------------------------------------------- Config Timer2 = Timer , Async = On , Prescale = 64 ' Делитель 32768 / 64 / 256 = 0,5 сек (прерывание TIMER2 = 2 раза в секунду) '------------------------------------------------------- On Timer2 Обработка_прерывания_timer2 ' Nosave '------------------------------------------------------------------------------- ' Assr.3 = 1 : Wait 1 ' Включить НЧ-генератор AS2 и подождать стабилизации амплитуды ' При включении бита AS2 (3) в регистре ASSR (ASSR.3), становится возможным применение режима ' "Powersave" - разновидность спящего режима. Пробуждение от TIMER0, TIMER1 ' Mcucr = &B10000000 ' Разрешаем режим пониженного энергопотребления Power Idle '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '**************** ***************** '**************** Конфигурация семисегментных индикаторов ***************** '**************** ***************** '******************************************************************************* '------------------------------------------------------------------------------- '------- Назначаем переменные для сегментов (A, B, C, D, E, F, G, H) ------- '------------------------------------------------------------------------------- A Alias Portb.0 : B Alias Portb.1 : C Alias Portb.2 : D Alias Portb.3 : E Alias Portb.4 : F Alias Portb.5 : G Alias Portd.6 : H Alias Portd.7 'порты, к которым подключены сегменты индикаторов '------------------------------------------------------------------------------- '-- Назначаем переменные для разрядов (Разряд_1, Разряд_2, Разряд_3, Разряд_4) -- '------------------------------------------------------------------------------- Разряд_1 Alias Portc.0 : Разряд_2 Alias Portc.1 : Разряд_3 Alias Portc.2 : Разряд_4 Alias Portc.3 ' : Разряд_5 Alias Portd.6 : Разряд_6 Alias Portd.7 : Разряд_7 Alias Portd.6 : Разряд_8 Alias Portd.7 ' порты, к которым подключены общие выводы индикаторов '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '------------------- Определение индикаторов с ОА или ОК --------------------- '------------------------------------------------------------------------------- '-------------- Заводим переменные для определения, ОА или ОК -------------- '------------------------------------------------------------------------------- Dim Indicator_1 As Byte , Indicator_2 As Byte , Indicator_3 As Byte , Indicator_4 As Byte '------------------------------------------------------------------------------- '------------- Ручной выбор ОА или ОК, используется для отладки ------------ '------------------------------------------------------------------------------- Config Разряд_4 = Input : Config H = Output : Set H '------------------------------------------------------------------------------- '-- Автоматический выбор ОА или ОК, при наличии резистора ~47к, см.схему --- '------------------------------------------------------------------------------- Waitms 1 If Pinc.3 = 1 Then ' Смотрим уровень на Разряд_4 Indicator_1 = 1 ' Если Indicator_1 = 1, то ОК Indicator_2 = 1 ' Если Indicator_2 = 1, то ОК Else Indicator_1 = 0 ' Иначе Indicator_1 = 0, то ОА Indicator_2 = 0 ' Иначе Indicator_2 = 0, то ОА End If Waitms 1 '------------------------------------------------------------------------------- '------------- Ручной выбор ОА или ОК, используется для отладки ------------ '------------------------------------------------------------------------------- ' Indicator_1 = 1 : Indicator_2 = 1 : Indicator_3 = 1 ' Indicator_1 = 0 : Indicator_2 = 0 : Indicator_3 = 0 '------------------------------------------------------------------------------- '******************************************************************************* '************ Окончательная настройка портов для LED индикации *********** '******************************************************************************* '------------------------------------------------------------------------------- Ddrc = &B00001111 : Ddrd = &B11110010 : Ddrb = &B00111111 '------------------------------------------------------------------------------- Config Portd.4 = Output : Пищалка Alias Portd.4 Config Portd.5 = Output : Двоеточие_led Alias Portd.5 '------------------------------------------------------------------------------- '******************************************************************************* '********************* Конфигурация порта клавиатуры ********************* '******************************************************************************* '------------------------------------------------------------------------------- Config Pind.3 = Input
If Indicator_1 = 1 Then Set Portd.3 Else Reset Portd.3
Клавиатура Alias Pind.3 '------------------------------------------------------------------------------- '******************************************************************************* 'Настройка_часов: '----------------- Задействуем аппаратные часы контроллера ----------------- '------------------------------------------------------------------------------- ' Config Clock = Soft , Gosub = Sectic ' Секундное_прерывание: ' Config Date = Dmy , Separator = . ' ANSI-Format день. месяц. год ' Date$ = "11.06.13" ' Time$ = "21:02:00" '------------------------------------------------------------------------------- '******************************************************************************* '******************* ************************ '******************* Конфигурация USART ************************ '******************* ************************ '******************************************************************************* ' RXCIE, TXCIE и UDRIE – биты, разрешающие прерывания по приему байта, окончанию передачи байта и пустом регистре UDR соответственно. Установкой их в 1 разрешаем прерывания. ' RXEN, TXEN – как я уже сказал, биты, включающие приёмник и передатчик соответственно. Установкой в 1 включаем приёмник или передатчик. ' TXC, RXC и UDRE – флаги прерываний по окончанию передачи, приёма и по опустошению регистра данных. ' U2X – если записать в этот бит 1, то скорость UART удвоится. ' UPE – флаг ошибки чётности. При ошибке он выставится в 1.
' Теперь UCSRC. Тут нас интересуют лишь биты, задающие размер одного байта – UCSZ0 и UCSZ1. Для стандартной посылки 8 бит, нужно записать в них единицы.
' Name Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 ' UCSRA RXC TXC UDRE FE DOR PE U2X MPCM '------------------------------------------------------------------------------- ' Ucsra.1 = 1 '------------------------------------------------------------------------------- Config Pind.0 = Input '> Конфигурация вывода RxD, приёмник UART Config Pind.1 = Output '> Конфигурация вывода TxD, передатчик UART '----------------------------------------- ' On Udre Прерывание_буфер_uart_пуст ' Переход на подпрограмму обработки прерывания после опустошения буфера передачи данных по UART ' On Urxc Прерывание_прием_uart_закончен ' Переход на подпрограмму обработки прерывания после окончания приёма данных по UART ' On Utxc Прерыв_передача_uart_закончена ' Переход на подпрограмму обработки прерывания после окончания передачи данных по UART '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- ' Config Int0 = Low Level ' On Int0 Обработка_прерывания_int0 '---------------------------------------- ' Кнопка_прерывание_int0 Alias Pind.2 ' Config Кнопка_прерывание_int0 = Input ' Set Кнопка_прерывание_int0 '------------------------------------------------------------------------------- '******************************************************************************* '******************* Определение переменных и констант ******************* '******************************************************************************* '------------------------------------------------------------------------------- '-------------- Переменные для подпрограммы вывода на 7-seg LED ------------ '------------------------------------------------------------------------------- Dim Цикл_led As Byte ' переменная, для хранения количества выводимых разрядов (нужна для разбивки значения на разряды) Dim Цифра(4) As Byte ' значения разрядов для 4-х разрядов ' Dim Флаг_яркость As Bit ' флаг для регулировки яркости LED дисплея ' Dim Яркость_led As Byte ' переменная, для регулировки яркости LED дисплея Dim Копия_цифра As Byte ' переменная, для временного хранения выводимого разряда Dim Флаг_точка(4) As Byte ' флаги точек для 4-х разрядов Dim Флаг_гашение(4) As Byte ' флаги гашения нужного разряда для 4-х разрядов Dim Флаг_мигание(4) As Byte ' флаги мигания нужного разряда для 4-х разрядов Dim Счетчик_миганий As Word ' счетчик для обработки частоты и длительности мигания Dim Частота_мигания As Word ' переменная, для хранения значения частоты мигания при Флаг_мигание(n) = 1 Dim Счетчик_разрядов As Byte ' счетчик перебора разрядов Dim Выводимая_цифра_led As Byte ' переменная, для загрузки цифр в порт ' Dim Количество_разрядов As Byte ' переменная, для хранения значения количества используемых разрядов ' Dim Счетчик_яркость_led As Byte ' переменная, для изменения яркости Dim Выводимые_данные_led As Byte ' переменная, для хранения выводимых данных Dim Дополнительный_символ(4) As Byte ' переменная, для хранения значения дополнительного символа при Флаг_дополнительный_символ(n) = 1 Dim Копия_выводимые_данные_led As Byte ' переменная, для временного хранения выводимых данных (нужна для разбивки значения на разряды) Dim 1_канал_выводимые_данные_led As Byte ' переменная, для хранения выводимых данных Dim 2_канал_выводимые_данные_led As Byte ' переменная, для хранения выводимых данных ' Dim 3_канал_выводимые_данные_led As Byte Dim Флаг_дополнительный_символ(4) As Byte ' флаг сигнализирующий о выводе дополнительных символов ' Dim Скорость_изменения_яркости_led As Byte ' переменная, для хранения значения скорости изменения яркости LED дисплея Dim Длительность_горения_при_мигании As Word ' переменная, для хранения значения длительности горения знакоместа при Флаг_мигание(n) = 1 '------------------------------------------------------------------------------- '----- Переменные для подпрограммы расчета времени и обработки кнопок ------ '------------------------------------------------------------------------------- Dim Сон As Byte Dim Год As Word 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 Буфер_клавиатуры 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 Счетчик_времени_звонка As Byte Dim Флаг_произошло_нажатие As Byte Dim Флаг_обновить_индикатор As Byte Dim Время_горения_двоеточия As Byte Dim Счетчик_прерываний_int1 As Byte Dim Случайное_нажатие_кнопки As Byte Dim Счетчик_прерывания_timer0 As Byte Dim Счетчик_прерываний_timer0 As Byte Dim Счетчик_прерываний_timer2 As Byte Dim Флаг_есть_прерывание_timer0 As Byte Dim Флаг_есть_прерывание_timer2 As Byte Dim Флаг_обновить_данные_времени As Byte Dim Счет_времени_горения_двоеточия As Byte Dim Счетчик_времени_настройки_часов As Word 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 '------------------------------------------------------------------------------- '---------- Переменные для подпрограмм обработка аппаратного USART --------- '------------------------------------------------------------------------------- Dim B As Byte Dim Символ_из_буфера As Byte Dim Есть_данные_для_uart As Byte Dim Буфер_прием_uart As String * 20 Dim Флаг_есть_сообщение_uart As Byte Dim Флаг_прием_uart_закончен As Byte Dim Принятое_сообщение As String * 20 Dim Временный_буфер_uart As String * 1 Dim Буфер_передача_uart As String * 20 Dim Флаг_передача_uart_закончена As Byte '------------------------------------------------------------------------------- '******************************************************************************* '************************ Определение подпрограмм ************************ '******************************************************************************* '------------------------------------------------------------------------------- Declare Sub Bip_bip() Declare Sub Del_buffer() 'очистка буфера Declare Sub Передача_uart() Declare Sub Настройка_часов() Declare Sub Обновить_данные() Declare Sub Регулировка_яркости_led() Declare Sub Обработка_нажатия_клавиатуры() Declare Sub Определение_индикаторов_оа_&_ок() Declare Sub Getline(временный_буфер_uart As String) 'чтение данных из буфера '------------------------------------------------------------------------------- '******************************************************************************* '*********************** Первоначальные установки ************************ '******************************************************************************* '******************************************************************************* '------------------------------------------------------------------------------- Readeeprom Первое_включение , 1 : Waitms 10
If Первое_включение <> 50 Then rcall Начальные_настройки End If '------------------------------------------------------------------------------- Readeeprom Часы , 100 : Waitms 10 Readeeprom Минуты , 110 : Waitms 10 Readeeprom Секунды , 120 : Waitms 10 Readeeprom Число_месяца , 130 : Waitms 10 Readeeprom Месяц , 140 : Waitms 10 Readeeprom Год , 150 : Waitms 10 '------------------------------------------------------------------------------- Частота_мигания = 200 : Длительность_горения_при_мигании = 100 ' значение частоты мигания и длительности горения знакоместа на LED дисплее при Флаг_мигание(n) = 1 Длительность_пищалки = 30 '------------------------------------------------------------------------------- Print "Секунды - " ; Секунды Print "Минуты - " ; Минуты Print "Часы - " ; Часы Print "Число - " ; Число_месяца Print "Месяц - " ; Месяц Print "Год - 2013" Print "" '------------------------------------------------------------------------------- '******************************************************************************* '***************** ****************** '**************** Разрешаем работу прерываний - Atmega8A **************** '***************** ****************** '******************************************************************************* '------------------------------------------------------------------------------- ' Enable Adc ' Enable Aci ' Enable Urxc ' Разрешаем прерывание после окончания приёма данных по UART ' Enable Udre ' Разрешаем прерывание после опустошения буфера UART ' Enable Utxc ' Разрешаем прерывание после окончания передачи по UART ' Enable Oc1a ' Enable Oc1b ' Enable Int0 ' Enable Int1 Enable Timer0 ' Enable Timer1 Enable Timer2 ' Enable Compare2 ' Enable Compare1a ' Enable Compare1b '------------------------------------------------------------------------------- '-------------------- Разрешаем работу всех прерываний --------------------- '------------------------------------------------------------------------------- Enable Interrupts '------------------------------------------------------------------------------- '******************************************************************************* '*************************** Начало программы **************************** '******************************************************************************* '------------------------------------------------------------------------------- Do : Nop ' крутимся здесь, ожидая прерывание '------------------------------------- Главный_цикл:
If Буфер_клавиатуры <> 0 Then Rcall Обработка_нажатия
Print "" Print "Кнопка - " ; Кнопка Print ""
Буфер_клавиатуры = 0 End If
If Есть_данные_для_uart = 1 Then Call Передача_uart Есть_данные_для_uart = 0 End If
'-------------------- Спящий_режим: Power Idle '-------------------- Goto Главный_цикл '-------------------- Loop '------------------------------------------------------------------------------- '******************************************************************************* '***************** ****************************** '***************** ПОДПРОГРАММЫ ****************************** '***************** ****************************** '******************************************************************************* '------------------------------------------------------------------------------- Настройка_времени: '------------------------------------------------------------------------------- Настройка_часов:
Флаг_настраиваем_время = 1 Флаг_мигание(1) = 1 : Флаг_мигание(2) = 1 Минимальное_значение = 0 : Максимальное_значение = 23
Do
Что_настраиваем = Часы
If Буфер_клавиатуры <> 0 Then Rcall Обработка_нажатия Буфер_клавиатуры = 0 End If
Часы = Что_настраиваем
Loop Until Флаг_настраиваем_время = 0
Флаг_мигание(1) = 0 : Флаг_мигание(2) = 0
Writeeeprom Часы , 100 : Waitms 10
Goto Выход_настройка_времени
'--------------------------------------------------
Настройка_минут:
Флаг_настраиваем_время = 1 Флаг_мигание(3) = 1 : Флаг_мигание(4) = 1 Минимальное_значение = 0 : Максимальное_значение = 59
Do
Что_настраиваем = Минуты
If Буфер_клавиатуры <> 0 Then Rcall Обработка_нажатия Буфер_клавиатуры = 0 End If
Минуты = Что_настраиваем
Loop Until Флаг_настраиваем_время = 0
Флаг_мигание(3) = 0 : Флаг_мигание(4) = 0
Writeeeprom Минуты , 110 : Waitms 10
'------------------------------------------------------------------------------- Выход_настройка_времени: Goto Главный_цикл '------------------------------------------------------------------------------- Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- Сохранение_значений: '------------------------------------------------------------------------------- Disable Interrupts '------------------------------------------------------------------------------- '---------------------- Значения времени и даты -------------------------------- '------------------------------------------------------------------------------- Начальные_настройки: '-------------------------------------------------------------------------------
Первое_включение = 50 Секунды = 0 Минуты = 0 Часы = 12 Число_месяца = 1 Месяц = 1 Год = 2013
'---------------------------------------------------
Writeeeprom Первое_включение , 1 : Waitms 10 Writeeeprom Часы , 100 : Waitms 10 Writeeeprom Минуты , 110 : Waitms 10 Writeeeprom Секунды , 120 : Waitms 10 Writeeeprom Число_месяца , 130 : Waitms 10 Writeeeprom Месяц , 140 : Waitms 10 Writeeeprom Год , 150 : Waitms 10
'------------------------------------------------------------------------------- Set Пищалка : Waitms 500 : Reset Пищалка : Waitms 200 : Set Пищалка : Waitms 500 : Reset Пищалка : Waitms 200 : Set Пищалка : Waitms 500 : Reset Пищалка : Waitms 20 '------------------------------------------------------------------------------- Config Watchdog = 16 Start Watchdog Waitms 150 '------------------------- ' Goto Главный_цикл '------------------------- Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '***************** Подпрограмма обработки прерывания TIMER0 **************** '***************** происходит каждые 2,048 ms **************** '******************************************************************************* '------------------------------------------------------------------------------- Обработка_прерывания_timer0: '------------------------------------------------------------------------------- Rcall Индикация_7seg_led
Rcall Опрос_клавиатуры '------------------------------------------------------------------------------- ' Делитель TIMER0 = 1000/(1000000/1024/(256-254))=1000/(976,5625/2) = 2,048 ms '------------------------------------------------------------------------------- Tcnt0 = 254 '------------------------------------------------------------------------------- Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '******************** Подпрограмма опроса клавиатуры ********************* '******************************************************************************* '------------------------------------------------------------------------------- Опрос_клавиатуры: '-------------------------------------------------------------------------------
If Indicator_1 = 0 Then If Клавиатура <> 0 Then Флаг_произошло_нажатие = 1 Счетчик_нет_нажатия = 0 Буфер_клавиатуры = Счетчик_разрядов ' Goto Обработка_нажатия Else Incr Счетчик_нет_нажатия If Счетчик_нет_нажатия > 8 Then Счетчик_нет_нажатия = 0 Флаг_произошло_нажатие = 0 End If End If Else If Клавиатура = 0 Then Флаг_произошло_нажатие = 1 Счетчик_нет_нажатия = 0 Буфер_клавиатуры = Счетчик_разрядов ' Goto Обработка_нажатия Else Incr Счетчик_нет_нажатия If Счетчик_нет_нажатия > 8 Then Счетчик_нет_нажатия = 0 Флаг_произошло_нажатие = 0 End If End If End If
If Счетчик_нет_нажатия > 3 Then Буфер_клавиатуры = 0 Счетчик_нет_нажатия = 0 Счетчик_кнопка_нажата = 0 Флаг_произошло_нажатие = 0 End If
'------------------------------------------------------------------------------- Выход_опрос_клавиатуры: Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '******************** Подпрограмма обработки нажатия ********************* '******************** кнопки клавиатуры ********************* '******************************************************************************* '------------------------------------------------------------------------------- Обработка_нажатия: '-------------------------------------------------------------------------------
Incr Счетчик_кнопка_нажата
If Счетчик_кнопка_нажата > 250 Then Счетчик_кнопка_нажата = 250
'-------------------------------------------------------------------------------
Select Case Буфер_клавиатуры
Case 1: If Счетчик_кнопка_нажата = 1 Then Кнопка = 1 rcall Bip_Bip
If Флаг_настраиваем_время = 0 Then
If Флаг_показать_секунды = 0 Then Флаг_показать_секунды = 1 Else Флаг_показать_секунды = 0 End If
Else
End If
Else rcall Увеличение Waitms 100 End If
Case 2: If Счетчик_кнопка_нажата = 1 Then Кнопка = 2 rcall Bip_Bip
If Флаг_настраиваем_время = 0 Then Флаг_настраиваем_время = 1 rcall Настройка_минут Else Флаг_настраиваем_время = 0 End If
Else End If
Case 3: If Счетчик_кнопка_нажата = 1 Then Кнопка = 3 rcall Bip_Bip
If Флаг_настраиваем_время = 0 Then Флаг_настраиваем_время = 1 rcall Настройка_часов Else Флаг_настраиваем_время = 0 End If
Else End If
Case 4: If Счетчик_кнопка_нажата = 1 Then Кнопка = 4 rcall Bip_Bip
If Флаг_настраиваем_время = 0 Then
Секунды = 0
Else
End If
Else
rcall Уменьшение
Waitms 100
End If Case Else: End Select
'------------------------------------------------------------------------------- Выход_обработка_нажатия: Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* Увеличение: '------------------------------------------------------------------------------- Incr Что_настраиваем If Что_настраиваем > Максимальное_значение Then Что_настраиваем = Минимальное_значение Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* Уменьшение: '------------------------------------------------------------------------------- Decr Что_настраиваем If Что_настраиваем < Минимальное_значение Or Что_настраиваем = 255 Then Что_настраиваем = Максимальное_значение Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- Bip_bip: '------------------------------------------------------------------------------- Set Пищалка Waitms Длительность_пищалки Reset Пищалка '------------------------------------------------------------------------------- Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '**************** Подпрограмма обработки прерывания TIMER2 ***************** '**************** происходит 2 раза в секунду ***************** '******************************************************************************* '------------------------------------------------------------------------------- Обработка_прерывания_timer2: '------------------------------------------------------------------------------- Incr Счетчик_прерываний_timer2
If Счетчик_прерываний_timer2 > 1 Then Счетчик_прерываний_timer2 = 0 Флаг_обновить_данные_времени = 1 rcall Обновить_данные_времени End If '------------------------------------------------------------------------------- '---------------- Каждые 0,5 сек. зажигаем двоеточие ----------------------- '------------------------------------------------------------------------------- If Флаг_горит_двоеточие = 0 Then Флаг_горит_двоеточие = 1 Else Флаг_горит_двоеточие = 0 End If '------------------------------------------------------------------------------- Return '------------------------------------------------------------------------------- '******************************************************************************* '------------------------------------------------------------------------------- '******************************************************************************* '****************** Подпрограмма обработки вывода ****************** '**************** на 7-seg индикатор (вызывается по TIMER0) **************** '******************************************************************************* '------------------------------------------------------------------------------- Индикация_7seg_led: ' прерывание таймера Т2 (индикация) '------------------------------------------------------------------------------- ' Stop Timer0 '-------------------------------------------------------------------------------
If Флаг_показать_секунды = 1 Then 1_канал_выводимые_данные_led = Минуты 2_канал_выводимые_данные_led = Секунды Else 1_канал_выводимые_данные_led = Часы 2_канал_выводимые_данные_led = Минуты End If
If Флаг_горит_двоеточие = 1 Then Set Двоеточие_led Флаг_точка(2) = 1 Else Reset Двоеточие_led Флаг_точка(2) = 0 End If
'-------------------------------------------------------------------------------
Выводимые_данные_led = 1_канал_выводимые_данные_led '
Копия_выводимые_данные_led = Выводимые_данные_led For Цикл_led = 2 To 1 Step -1 ' цикл в котором разбивается переменная на 4 числа Выводимые_данные_led = Копия_выводимые_данные_led Mod 10 Цифра(цикл_led) = Выводимые_данные_led ' Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10 ' Next
Выводимые_данные_led = 2_канал_выводимые_данные_led '
Копия_выводимые_данные_led = Выводимые_данные_led For Цикл_led = 4 To 3 Step -1 ' цикл в котором разбивается переменная на 4 числа Выводимые_данные_led = Копия_выводимые_данные_led Mod 10 Цифра(цикл_led) = Выводимые_данные_led ' Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10 ' Next '------------------------------------------------------------------------------- '---------------------- гасим все разряды индикатора ----------------------- '------------------------------------------------------------------------------- Call Регулировка_яркости_led ' в принципе, гашение тут без надобности, индикатор и так выключается в прерывании Регулировка_яркости_led. Если же индикация работает БЕЗ регулировки яркости, то гашение ОБЯЗАТЕЛЬНО. '------------------------------------------------------------------------------- '---- перебираем разряды, в каждом прерывании выводим следующий разряд ----- '------------------------------------------------------------------------------- Incr Счетчик_разрядов : If Счетчик_разрядов > 4 Then Счетчик_разрядов = 1 ' выбираем разряд для загрузки в обработчик вывода на 7-seg LED '------------------------------------------------------------------------------------ 'участок кода отвечающий за мигание, тушение разрядов и выводит точку в нужном месте '------------------------------------------------------------------------------------ Incr Счетчик_миганий : If Счетчик_миганий > Частота_мигания Then Счетчик_миганий = 1 ' длительность мигания
If Флаг_мигание(счетчик_разрядов) = 1 And Счетчик_миганий > Длительность_горения_при_мигании Or Флаг_гашение(счетчик_разрядов) = 1 Then ' если флаг мигания этого разряда выставлен и счетчик > 200 Select Case Счетчик_разрядов Case 1 To 2 If Indicator_1 = 1 Then Выводимая_цифра_led = Lookup(11 , Цифры_ok) ' выводим пустое место Else Выводимая_цифра_led = Lookup(11 , Цифры_oa) ' выводим пустое место End If Case 3 To 4 If Indicator_2 = 1 Then Выводимая_цифра_led = Lookup(11 , Цифры_ok) ' выводим пустое место Else Выводимая_цифра_led = Lookup(11 , Цифры_oa) ' выводим пустое место End If End Select Else ' иначе (флаг не выставлен, либо счетчик < 200) If Флаг_дополнительный_символ(счетчик_разрядов) = 1 Then Select Case Счетчик_разрядов Case 1 To 2 If Indicator_1 = 1 Then Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok) ' выводим дополнительный_символ Else Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa) ' выводим дополнительный_символ End If Case 3 To 4 If Indicator_2 = 1 Then Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok) ' выводим дополнительный_символ Else Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa) ' выводим дополнительный_символ End If End Select Else Выводимая_цифра_led = Цифра(счетчик_разрядов) Select Case Счетчик_разрядов Case 1 To 2 If Indicator_1 = 1 Then Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok) Else Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa) End If Case 3 To 4 If Indicator_2 = 1 Then Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok) Else Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa) End If End Select End If
'------------------------------------------------------------------------------- '--------------------- Если необходимо, добавляем точку -------------------- '-------------------------------------------------------------------------------
If Флаг_точка(счетчик_разрядов) = 1 Then Выводимая_цифра_led = Выводимая_цифра_led Xor &H80 '&H7F ' или &B10000000 добавляем к выводимой цифре точку Цифры_OA End If '------------------------------------------------------------------------------- End If '------------------------------------------------------------------------------- '--------------------- загружаем в порт код цифры ---------------------- '------------------------------------------------------------------------------- A = Выводимая_цифра_led.0 ' Сегмент "А" B = Выводимая_цифра_led.1 ' Сегмент "B" C = Выводимая_цифра_led.2 ' Сегмент "C" D = Выводимая_цифра_led.3 ' Сегмент "D" E = Выводимая_цифра_led.4 ' Сегмент "E" F = Выводимая_цифра_led.5 ' Сегмент "F" G = Выводимая_цифра_led.6 ' Сегмент "G" H = Выводимая_цифра_led.7 ' Сегмент "Точка" '------------------------------------------------------------------------------- '---------------- Включаем соответствующий разряд индикатора --------------- '------------------------------------------------------------------------------- Select Case Счетчик_разрядов Case 1 : If Indicator_1 = 1 Then Reset Разряд_1 Else Set Разряд_1 Case 2 : If Indicator_1 = 1 Then Reset Разряд_2 Else Set Разряд_2 Case 3 : If Indicator_1 = 1 Then Reset Разряд_3 Else Set Разряд_3 Case 4 : If Indicator_1 = 1 Then Reset Разряд_4 Else Set Разряд_4 End Select '------------------------------------------------------------------------------- ' Start Timer0 '------------------------------------------------------------------------------- '-------------------- Выход из обработчика прерывания ---------------------- '------------------------------------------------------------------------------- Return '******************************************************************************* '=============================================================================== '=========== Таблицы выводимых символов для индикаторов с ОК и ОА ========== '=============================================================================== Цифры_ok: ' цифры '----------- Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F '0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Data &H40 , &H00 , &H63 , &H39 , &H78 , &H5C , &H38 , &H74 , &H5E , &H77 '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A" Data &H58 , &H31 , &H76 , &H79 , &H50 , &H71 , &H1C , &H73 , &H37 , &H80 '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П". "." Data &H54 ', &H , &H , &H , &H , &H , &H , &H , &H , &H '"n", "", "", "", "", "", "", "", "", "". "" '------------------------------------------------------------------------------- Цифры_oa: '----------- Data &HC0 , &HF9 , &HA4 , &HB0 , &H99 , &H92 , &H82 , &HF8 , &H80 , &H90 '0,1,2,3,4,5,6,7,8,9 Data &HBF , &HFF , &H9C , &HC6 , &H87 , &HA3 , &HC7 , &H8B , &HA1 , &H88 '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A" Data &HA7 , &HCE , &H89 , &H86 , &HAF , &H8E , &HE3 , &H8C , &HC8 , &H7F '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П", "." Data &HAB ', &H , &H , &H , &H , &H , &H , &H , &H , &H '"n", "", "", "", "", "", "", "", "", "". "" '=============================================================================== Регулировка_яркости_led: ' прерывание таймера Timer2 (регулировка яркости) '-------------------------- If Indicator_1 = 1 Then Set Разряд_1 : Set Разряд_2 ': Set Разряд_3 : Set Разряд_4 ': Set Разряд_5 : Set Разряд_6 : Set Разряд_7 : Set Разряд_8 ' гасим индикаторы ОК Else Reset Разряд_1 : Reset Разряд_2 ': Reset Разряд_3 : Reset Разряд_4 ': Reset Разряд_5 : Reset Разряд_6 : Reset Разряд_7 : Reset Разряд_8 ' гасим индикаторы ОА End If '-------------------------- If Indicator_2 = 1 Then Set Разряд_3 : Set Разряд_4 ': Set Разряд_7 : Set Разряд_8 Else Reset Разряд_3 : Reset Разряд_4 ': Reset Разряд_7 : Reset Разряд_8 ' гасим индикаторы ОА End If '-------------------------- Return ' выход из обработчика прерывания '------------------------------------------------------------------------------- '*******************************************************************************
'******************************************************************************* '******************** Подпрограмма расчета времени ********************** '******************** часов, минут и секунд ********************** '******************************************************************************* '------------------------------------------------------------------------------- Обновить_данные_времени: '------------------------------------------------------------------------------- Incr Секунды 'плюс секунда
If Секунды > 59 Then 'при необходимости Секунды = 0 : Goto Обновить_минуты 'скорректировать счетчик секунд End If
Goto Обновить_индикатор '====================================== Обновить_минуты: '====================================== Incr Минуты 'плюс минута
If Минуты > 59 Then 'при необходимости Минуты = 0 : Goto Обновить_часы 'скорректировать счетчик минут End If
Goto Обновить_индикатор '====================================== Обновить_часы: '====================================== Incr Часы 'плюс час
If Часы > 23 Then 'при необходимости Часы = 0 : Goto Обновить_число_месяца 'скорректировать счетчик часов End If '====================================== Обновить_число_месяца: '====================================== Incr Число_месяца 'плюс час
If Число_месяца > 30 Then 'при необходимости Число_месяца = 1 : Goto Обновить_месяц 'скорректировать счетчик часов End If '====================================== Обновить_месяц: '====================================== Incr Месяц 'плюс час
If Месяц > 12 Then 'при необходимости Месяц = 1 : Goto Обновить_год 'скорректировать счетчик часов End If '====================================== Обновить_год: '====================================== Incr Год 'плюс час
If Год > 2020 Then 'при необходимости Год = 2013 'скорректировать счетчик часов End If
'====================================== Обновить_индикатор: '====================================== Флаг_обновить_данные_времени = 0 Есть_данные_для_uart = 1 ' Флаг_обновить_индикатор = 1 ' поставить признак обновления индикации '------------------------------------------------------------------------------- Выход_обновить_данные_времени: '------------------------------------------------------------------------------- Return '------------------------------------------------------------------------------- '*******************************************************************************
'******************************************************************************* '****************** Подпрограмма обработки вывода ****************** '****************** на компьютер (аппаратный USART) ****************** '******************************************************************************* '------------------------------------------------------------------------------- Передача_uart: '------------------------------------------------------------------------------- If Indicator_1 = 1 Then Print "Индикаторы с ОК" Else Print "Индикаторы с ОА" End If
Print "Текущее время - " ;
Print Часы ; ":" ; If Минуты < 10 Then Print "0" ; Print Минуты ; ":"; If Секунды < 10 Then Print "0" ; Print Секунды
Print "Текущая дата - " ; Print "Пятница " ; Print "28 июня 2013 года" Print "" '------------------------------------------------------------------------------- Return '-------------------------------------------------------------------------------
'*******************************************************************************
Эмуляция в "Протеус", исходник
Видео работы в "Протеус" - выложу чуть позже
Видео работы в железе -
выложу чуть позже
|