' * * * заводим переменные * * * Dim A As Byte Dim W As Word Dim B As Word Dim C As Word Dim D As Byte Dim F As Bit Dim K As Byte Dim S As Byte
Dim N1 As Byte Dim N2 As Byte Dim N3 As Byte
Dim M1 As Integer Dim M2 As Integer Dim M3 As Integer
Declare Sub Led() Declare Sub Knopka() Declare Sub Seg_1() Declare Sub Seg_2() Declare Sub Seg_3()
' включаем прерывания Config Timer1 = Timer , Prescale = 256 On Timer0 Led Enable Timer0
Config Timer1 = Timer , Prescale = 1024 Enable Timer1 B = Timer1 C = Timer1 Enable Interrupts
Reset A W = 0 ' * * * Основной цикл программы * * * Do
M1 = W ' вот это число будем отображать M2 = M1 M3 = M1
M1 = M1 / 100 'обработка первого числа N1 = Abs(m1)
M2 = M2 Mod 100 'обработка второго числа M2 = M2 / 10 N2 = Abs(m2)
M3 = M3 Mod 10 ' обработка четвертого числа N3 = Abs(m3)
rcall Knopka Loop
Schet:
If Pinc.0 = 0 Then Waitms 5 Incr A End If If Pinc.1 = 0 Then Waitms 5 Decr A End If 'коэффициент пересчёта If A = 2 Then Incr W A = 0 End If
If A = -2 Then Decr W A = 0 End If
Return
'* * * подпрограма обработки индикации * * *
Led: Incr S
If S = 1 Then
Portd = &B01000000 'зажигаем первое число If N1 = 0 Then 'гашение не значащих нулей Portd = &B00000000 End If
Select Case N1 Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 End Select End If
If S = 2 Then Portd = &B00100000 'зажигаем второе число вместе с точкой If N2 = 0 And N1 = 0 Then 'гашение не значащих нулей Portd = &B00000000 End If
Select Case N2 Case 0 : Portb = &B01000000 Case 1 : Portb = &B01111001 Case 2 : Portb = &B00100100 Case 3 : Portb = &B00110000 Case 4 : Portb = &B00011001 Case 5 : Portb = &B00010010 Case 6 : Portb = &B00000010 Case 7 : Portb = &B01111000 Case 8 : Portb = &B00000000 Case 9 : Portb = &B00010000 End Select End If If S = 3 Then Portd = &B00010000 'зажигаем третье число
Select Case N3 Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 End Select End If
Upd: работать напрямую с переменной Eram Byte таким образом не получилось, хотя Баском ошибок не давал, все нормально скомпилировалось. . Пришлось создавать переменную Byte и при старте программы сначала считать в нее переменную Eram Byte, а в конце, при сохранении данных, сохранить в Byte, а потом записать в Eram Byte. В остальном все работает как нужно ! Откорректировал код выше.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
работать напрямую с переменной Eram Byte таким образом не получилось, хотя Баском ошибок не давал, все нормально скомпилировалось. . Пришлось создавать переменную Byte и при старте программы сначала считать в нее переменную Eram Byte, а в конце, при сохранении данных, сохранить в Byte, а потом записать в Eram Byte.
Разумеется. Переменная содержит адрес, по которому уже находятся Ваши данные. Потому и необходимо их по этому адресу забрать, и делать уже что угодно. Обратно точно так же.
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Всем здравствуйте! Мурррр! Подскажите пожалуйста новичку, идея такая: организовать ТРИ отдельных десятичных счётчика. Каждый считает свой разряд трёхразрядного 7-сегм. индикатора от 0 до 9. При достижении 10-ти первого счётчика, он обнуляется и инкременируется второй счётчик. Т.е. в результате имеем неа индикаторе готовое число посчитаных импульсов. Без всяких преобразований. Типа как на 3-х К176ИЕ4. Скажите: так делать впринципе нельзя, или я где то допустил ошибку? вот что у меня получается:[code Dim Коэффициент_пересчёта As Byte Dim Результат_счёта_1 As Byte Dim Результат_счёта_2 As Byte Dim Результат_счёта_3 As Byte Dim Счетчик_разрядов As Byte
Incr Счетчик_разрядов Stop Timer0 If Счетчик_разрядов > 3 Then Счетчик_разрядов = 1 ' выбираем разряд для загрузки в обработчик вывода на 7-seg LED End If
If Счетчик_разрядов = 1 Then
Portd = &B01000000 'зажигаем первое число
Select Case Результат_счёта_1
Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 End Select
End If Start Timer0 If Счетчик_разрядов = 2 Then
Portd = &B00100000
Select Case Результат_счёта_2
Case 0 : Portb = &B01000000 Case 1 : Portb = &B01111001 Case 2 : Portb = &B00100100 Case 3 : Portb = &B00110000 Case 4 : Portb = &B00011001 Case 5 : Portb = &B00010010 Case 6 : Portb = &B00000010 Case 7 : Portb = &B01111000 Case 8 : Portb = &B00000000 Case 9 : Portb = &B00010000 End Select
End If Start Timer0 If Счетчик_разрядов = 3 Then Stop Timer0 Portd = &B00010000
Select Case Результат_счёта_3
Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 End Select End If
Во первых, у переменной типа "байт" нет отрицательных значений. После нуля, при вычитании -1 будет 255. Как бы "по кругу" ходят значения. Во вторых,
LazarevSergey писал(а):
If Результат_счёта_2 = 0 Then Decr Результат_счёта_3 End If Return
Decr Результат_счёта_3 возможно только если Результат_счёта_3 больше нуля, иначе будет 255. Ну и при уменьшении третьего разряда, второй разряд нужно ставить в девятку. То есть при изменении старшего/младшего разряда нужно контролировать оба крайних значений разряда.
И главное, зачем это делать. Ведь для простейшей проверки числа придется обратно собирать из сотен, десятков и единиц. Та же кастрюля, только сбоку.
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Ind: Data &B11000000 ' 0 Data &B11111001 ' 1 Data &B10100100 ' 2 Data &B10110000 ' 3 Data &B10011001 ' 4 Data &B10010010 ' 5 Data &B10000010 ' 6 Data &B11111000 ' 7 Data &B10000000 ' 8 Data &B10010000 ' 9 Data &B10111111 ' - Data &B11111111 ' Пусто
О том и речь. И полноценная переменная для работы. Ведь на деле-то ее нужно разбивать на разряды обычно только для индикации. Хотя, может тут хитрая затея какая-нибудь.
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
О том и речь. И полноценная переменная для работы. Ведь на деле-то ее нужно разбивать на разряды обычно только для индикации. Хотя, может тут хитрая затея какая-нибудь.
Здравствуйте! Спасибо за проявленый интерес! Да. Затея, хитрая, как раз есть. А затея такая: реализовать установку начала отсчёта (счётчик, в основном, будет считать от настраеваемого числа к нулю. Но с корректировкой в плюс. ) И цифра в каждом разряде устанавливалась бы отдельно от остальных разрядов. Навроде как в реле времени DH48S-S и аналогичных, только не электромеханическим переключателем, а програмно, с выводом начала отсчёта на индикатор.
Добавлено after 15 minutes 28 seconds:
Мурик писал(а):
Не проще сделать так?Спойлер
Код:
$regfile = "m8def.dat" ' Выбор типа контроллера. $crystal = 1000000 ' Частота генератора, Гц. $hwstack = 50 ' Размер аппаратного. $swstack = 30 ' и программных стеков. $framesize = 40
Config Portd = Output Config Portc = Output
Dim Dinamindex As Byte Dim Temp As Byte Dim Dinaminfo(4) As Byte Dim Count As Word Dim Tmp As Word Dim I As Byte
Count = 0
Config Timer0 = Timer , Prescale = 8 ' Конфигурация таймера Timer1. On Timer0 Dinam ' Назначение подпрограммы прерываний от Timer1 Enable Timer0 ' Разрешение прерываний от Timer1
Enable Interrupts
Do Count = Count + 1 If Count > 999 Then Count = 0
Tmp = Count
For I = 1 To 3 Dinaminfo(i) = Tmp Mod 10 Tmp = Tmp / 10 Next I
Waitms 100 Loop End
Dinam: Dinamindex = Dinamindex + 1 If Dinamindex > 8 Then Dinamindex = 1
Ind: Data &B11000000 ' 0 Data &B11111001 ' 1 Data &B10100100 ' 2 Data &B10110000 ' 3 Data &B10011001 ' 4 Data &B10010010 ' 5 Data &B10000010 ' 6 Data &B11111000 ' 7 Data &B10000000 ' 8 Data &B10010000 ' 9 Data &B10111111 ' - Data &B11111111 ' Пусто
Затеи - это очень хорошо. Только видите ли, какое дело, нужно все же определить, что первично. Допустим, имеется у нас таймер, который считает себе от заданного числа и до 0. Считает каждый день, и несколько раз в день. И есть кнопка, которая этот таймер настраивает. Кнопка одна, и конечно удобнее настраивать поразрядно.
И можно сделать как? Три переменных, которые настраивает кнопка, и все как у Вас. Но нужно понимать, что каждую секунду работы таймера, будет проверяться куча условий: перевалили ли единицы через 0, если да то после декремента десятков дошагали ли они до своего конца, и так далее каждый раз... А можно завести одну переменную для секунд. И уменьшать / увеличивать ее одной командой, и сравнивать ее с чем угодно, и вообще творить кучу всяких дел. Но! Тогда придется при настройке таймера точно так же увеличивая / уменьшая единицы следить за десятками и прочее... Вот и стоит подумать что происходит чаще: работа таймера, или его настройка.
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Всем МЯУ!!! Три счётчика в одном, я, всё же победил! Когда код будет доведён до ума, обязательно отчитаюсь! Теперь возник следующий вопрос: как отследить короткое или длинное нажатие произошло? У меня получается (А точнее, НЕ получается) такой вот код. Целиком приводить пока не буду, дабы не захламлять форум. Пока только кусок, который должен бы, как я думаю, отвечать за распознования длины нажатия. МК на нажатия не реагирует вообще В чём я делаю ощибку?
Код:
Config Timer0 = Timer , Prescale = 8 ' Конфигурация таймера Timer1. On Timer0 Индикация ' Назначение подпрограммы прерываний от Timer1 Enable Timer0 ' Разрешение прерываний от Timer1
Config Int0 = Falling On Int0 Счёт Enable Int0
Config Int1 = Falling ‘превывание ( PIND.3=0) по низсходящему фронту On Int1 Кнопка Enable Int1
Enable Interrupts
. . . . .
Индикация:
Incr Счетчик_разрядов If Счетчик_разрядов > 3 Then Счетчик_разрядов = 1 End If
Incr Счётчик_времени_нажатия ' эта переменная инкременируется, как и счётчик_разрядов, по прерыванию таймера
. . . . .
Return
Кнопка:
Счётчик_времени_нажатия = 0 ' правильно ли я полагаю, что ‘ по НИЗСХОДЯЩЕМУ ФРОНТУ переменная обнуляется и далее начинает инкременироваться (а так как индикация не сбивается, я полагаю, что так и происходит) ‘ не зависимо от того отпущена кнопка или продолжает удерживаться If Pind.3 = 1 And Счётчик_времени_нажатия >= 10 Then ‘ когда отпускаем кнопку, смотрим чему там стала равна переменная и принимаем решение ‘ о характере нажатия Incr Счётчик_длиных_нажатий Set Flag_длиное_нажатие End If
If Pind.3 = 1 And Счётчик_времени_нажатия < 10 Then Incr Счётчик_коротких_нажатий Set Flag_короткое_нажатие Toggle Portd.4 End If
Кто как делает. У меня работает немного по другому.
Счётчик_времени_нажатия = 0 While pind.3 <> 1 Ждем отпускания кнопки wend If Счётчик_времени_нажатия >= 10 Then смотрим чему там стала равна переменная и принимаем решение Incr Счётчик_длиных_нажатий Set Flag_длиное_нажатие End If
Только не забыть дребезг погасить. Может в этом проблема?
Пробывал я примерно так...Через операторы While-Wend...Индикация сбивается. Как и через For-Next, как в этом примереhttp://bascomavr.3bb.ru/viewtopic.php?id=915#p9584. Пока нажата кнопка и идёт цикл- наблюдается сбой индикации.
Всем МЯУ!!! ... как отследить короткое или длинное нажатие произошло?
И вам тоже МЯУ! Я загнал 3 функции в одну кнопку: короткое, долгое и двойное нажатие. В железе работает! Если что-то не устраивает, измените тайминги (пометил как "Ахтунг! ...").
Blue Alias Portb.0 'СИНИЙ LED Green Alias Portb.1 'ЗЕЛЕНЫЙ LED Red Alias Portb.2 'КРАСНЫЙ LED Btn Alias Pind.2 'КНОПКА
'//СБРОС ПОРТОВ Reset Blue Reset Green Reset Red
'================== ПЕРЕМЕННЫЕ ================= Dim Count As Byte 'счетчик двойного нажатия
'================== ПРОГРАММА =================
Do 'основной цикл
Debounce Btn , 0 , Button , Sub 'опрос кнопки
Loop
'================= ОБРАБОТЧИК =================
Button: 'обработка нажатия кнопки
'//ОБРАБОТКА ДОЛГОГО НАЖАТИЯ Label1: 'ждем когда кнопка отпустится While Btn = 0 'до тех пор пока кнопка удерживается Incr Count 'увеличиваем счетчик Waitms 50 'задержка If Count => 40 Then '50*40 = 2000 мсек. - 2 секунды ---> Ахтунг! Долгое нажатие должно быть в теч. этого промежутка времени Toggle Green 'меняем состояние ЗЕЛЕНОГО светодиода Waitms 50 'задержка Count = 0 'обнуляем счетчик Goto Ext 'уходим End If 'конец условия Wend
'//ОБРАБОТКА ДВОЙНОГО НАЖАТИЯ Waitms 10 If Btn = 0 Then Goto Label1 For Count = 0 To 100 'увеличиваем count Waitms 10 '10*100 = 1000 мсек = 1 секунда ---> Ахтунг! Двойное нажатие должно быть в теч. этого промежутка времени If Btn = 0 Then 'если в это время нажать кнопку Toggle Red 'меняем состояние КРАСНОГО светодиода Goto Ext 'выходим из цикла End If 'конец условия Next Count 'Reset Red 'если не нажали второй раз КРАСНЫЙ светодиод погашен
'//ЕСЛИ КНОПКА УДЕРЖИВАЛАСЬ МЕНЕЕ СЕКУНДЫ Toggle Blue 'меняем состояние ГОЛУБОГО светодиода Count = 0 'обнуляем счетчик Ext: 'метка Return 'возврат в основной цикл
Вложение:
Комментарий к файлу: Прилагаю исходник и шпротеус 1btn 3 mode.rar [15.21 KiB]
Скачиваний: 218
Пока нажата кнопка и идёт цикл- наблюдается сбой индикации.
Пока Вы сидите в прерывании кнопки, все остальные прерывания (и индикации в том числе) глобально запрещены. Прерывание должно быть максимально коротким, оно же не даром называется так...
Код:
правильно ли я полагаю, что по НИЗСХОДЯЩЕМУ ФРОНТУ переменная обнуляется и далее начинает инкременироваться (а так как индикация не сбивается, я полагаю, что так и происходит)
Нет, так не происходит. Инкремент Вашей переменной выполняется в другом прерывании, а туда Вы попадете только когда покинете текущее (обработчик кнопки).
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Пока нажата кнопка и идёт цикл- наблюдается сбой индикации.
Пока Вы сидите в прерывании кнопки, все остальные прерывания (и индикации в том числе) глобально запрещены. Прерывание должно быть максимально коротким, оно же не даром называется так...
Код:
правильно ли я полагаю, что по НИЗСХОДЯЩЕМУ ФРОНТУ переменная обнуляется и далее начинает инкременироваться (а так как индикация не сбивается, я полагаю, что так и происходит)
Нет, так не происходит. Инкремент Вашей переменной выполняется в другом прерывании, а туда Вы попадете только когда покинете текущее (обработчик кнопки).
Но, прерывание же сконфигурировано "по низсходящему фронту". Не на всё время, пока нажата кнопка, а только на момент изменения уровня с высокого на низкий. И если в обработчике нет никаких ЗАНИМАЮЩИХ ВРЕМЯ циклов, а только сброс переменной (с последующим сравнением её "натиканого", после сброса значения) я думаю, что должно всё работать. Или я не догоняю каких то нюансов?
Добавлено after 6 minutes 41 second:
KOTик писал(а):
LazarevSergey писал(а):
Всем МЯУ!!! ... как отследить короткое или длинное нажатие произошло?
И вам тоже МЯУ! Я загнал 3 функции в одну кнопку: короткое, долгое и двойное нажатие. В железе работает! Если что-то не устраивает, измените тайминги (пометил как "Ахтунг! ...").
Blue Alias Portb.0 'СИНИЙ LED Green Alias Portb.1 'ЗЕЛЕНЫЙ LED Red Alias Portb.2 'КРАСНЫЙ LED Btn Alias Pind.2 'КНОПКА
'//СБРОС ПОРТОВ Reset Blue Reset Green Reset Red
'================== ПЕРЕМЕННЫЕ ================= Dim Count As Byte 'счетчик двойного нажатия
'================== ПРОГРАММА =================
Do 'основной цикл
Debounce Btn , 0 , Button , Sub 'опрос кнопки
Loop
'================= ОБРАБОТЧИК =================
Button: 'обработка нажатия кнопки
'//ОБРАБОТКА ДОЛГОГО НАЖАТИЯ Label1: 'ждем когда кнопка отпустится While Btn = 0 'до тех пор пока кнопка удерживается Incr Count 'увеличиваем счетчик Waitms 50 'задержка If Count => 40 Then '50*40 = 2000 мсек. - 2 секунды ---> Ахтунг! Долгое нажатие должно быть в теч. этого промежутка времени Toggle Green 'меняем состояние ЗЕЛЕНОГО светодиода Waitms 50 'задержка Count = 0 'обнуляем счетчик Goto Ext 'уходим End If 'конец условия Wend
'//ОБРАБОТКА ДВОЙНОГО НАЖАТИЯ Waitms 10 If Btn = 0 Then Goto Label1 For Count = 0 To 100 'увеличиваем count Waitms 10 '10*100 = 1000 мсек = 1 секунда ---> Ахтунг! Двойное нажатие должно быть в теч. этого промежутка времени If Btn = 0 Then 'если в это время нажать кнопку Toggle Red 'меняем состояние КРАСНОГО светодиода Goto Ext 'выходим из цикла End If 'конец условия Next Count 'Reset Red 'если не нажали второй раз КРАСНЫЙ светодиод погашен
'//ЕСЛИ КНОПКА УДЕРЖИВАЛАСЬ МЕНЕЕ СЕКУНДЫ Toggle Blue 'меняем состояние ГОЛУБОГО светодиода Count = 0 'обнуляем счетчик Ext: 'метка Return 'возврат в основной цикл
Вложение:
1btn 3 mode.rar
Спасибо за пример кода. Код очень полезный. Не так давно сам искал нечто подобное. Для зажигания светодиодов он, несомнено, подойдёт, а вот как его совместить с динамической индикацией? Проблема то, как раз в сбое оной при применении ЦИКЛОВ в обработчике.
В приведенном коде прерываний нет. А если динамическая индикация на прерывании по таймеру, то они друг другу не помешают. Не кому остановить индикацию.
Всем Мира и добра! И свежей рыбы! Чтобы не вводить никого в заблуждение по поводу использования кнопки, выкладываю своё творение целиком. Пока РАБОТАТЬ НЕ ХОЧЕТ. Напомню цель: создать трёхразрядный счётчик импульсов с некоторым коэфициентом счёта (n импульсов будет считаться как 1) с возможностью ПОРАЗРЯДНОЙ настройки начала отсчёта. Всё это дело надо (крайне желательно) настраивать ОДНОЙ кнопкой. Очень желательно (но пока до этого я не дошёл) чтобы в режиме настройки, настраиваемый разряд мигал. Счётчик будет считать от настроенного числа к нулю (конкретно, предпологается подсчёт израсходованного топлива, с учётом вернувшегося по обратке в бак) с небольшой поправкой в плюс. Не спорю, на данном этапе, т. к. удалось разделить показания каждого разряда друг от друга, проще прицепить ТРИ кнопки и наспраивать каждый разряд (от 0 до 9 по кругу) СВОЕЙ кнопкой. Но это КРАЙНЕ не желательно. Вот что у меня НЕ получилось. Прошу помощи. Вроде бы должно, а не работает.
Код:
$regfile = "m8def.dat" ' Выбор типа контроллера. $crystal = 4000000 ' Частота генератора, Гц. $hwstack = 50 ' Размер аппаратного. $swstack = 30 ' и программных стеков. $framesize = 40
Config Timer0 = Timer , Prescale = 8 ' Конфигурация таймера Timer1. On Timer0 Индикация ' Назначение подпрограммы прерываний от Timer1 Enable Timer0 ' Разрешение прерываний от Timer1
Config Int0 = Falling ‘прерывание для счёта On Int0 Счёт Enable Int0
Config Int1 = Falling ‘прерывание для кнопки On Int1 Кнопка Enable Int1
Enable Interrupts ‘ разные нужные переменные
Dim Коэффициент_пересчёта As Integer Dim Результат_счёта_1 As Integer Dim Результат_счёта_2 As Integer Dim Результат_счёта_3 As Integer Dim Счетчик_разрядов As Byte Dim Flag_вперёд As Byte Dim Flag_назад As Byte Dim Flag_короткое_нажатие As Byte Dim Flag_длиное_нажатие As Byte Dim Flag_нажатие As Byte Dim Flag_настройка_1 As Byte Dim Flag_настройка_2 As Byte Dim Flag_настройка_3 As Byte Dim Счётчик_времени_нажатия As Byte Dim Счётчик_длиных_нажатий As Byte Dim Счётчик_коротких_нажатий As Byte Dim Значение_настраимаемого_разряда As Byte
Declare Sub Индикация() 'Declare Sub Обработка_нажатия() Declare Sub Кнопка() Declare Sub Счёт()
Do
Loop
Счёт:
If Pind.0 = 0 Then Incr Коэффициент_пересчёта Set Flag_вперёд Reset Flag_назад End If
If Pind.1 = 0 Then Decr Коэффициент_пересчёта Set Flag_назад Reset Flag_вперёд End If
If Flag_вперёд = 1 Then 'счёт вперед If Коэффициент_пересчёта = 3 Then 'вообще коэфициент пересчёта будет, примерно 1600 Incr Результат_счёта_3 'он будет находиться эксперементально, для каждого датчика Коэффициент_пересчёта = 0 'А такое значение, только для удобства отладки. End If
If Результат_счёта_3 = 10 Then Incr Результат_счёта_2 Результат_счёта_3 = 0 End If
If Результат_счёта_2 = 10 Then Incr Результат_счёта_1 Результат_счёта_2 = 0 End If
If Результат_счёта_1 = 10 Then Результат_счёта_3 = 0 Результат_счёта_2 = 0 Результат_счёта_1 = 0 End If End If
If Flag_назад = 1 Then 'счёт назад If Коэффициент_пересчёта = -3 Then Decr Результат_счёта_3 Коэффициент_пересчёта = 0 End If
If Результат_счёта_3 = 0 And Результат_счёта_2 > 0 Then Decr Результат_счёта_2 Результат_счёта_3 = 9 End If
If Результат_счёта_2 = 0 And Результат_счёта_1 > 0 Then Decr Результат_счёта_1 Результат_счёта_2 = 9 End If End If
Return
Индикация:
'чтобы индикация не зависала при нажатии кнопки, решил воткнуть 'обработку нажатий сюда,т.к. если вешаю всё это дело на обработчик INT1, 'индикация виснет.((( 'Думаю, что это не совсем правильно, 'но КАК ПРАВИЛЬНО-не знаю.
Incr Счётчик_времени_нажатия
'чтобы не допустить 'ложных срабатываний кнопки,не даём переменной БЕЗ НАДОБНОСТИ 'достигать порога срабатывания
If Flag_нажатие = 0 And Счётчик_времени_нажатия = 10 Then Счётчик_времени_нажатия = 0 End If
If Pind.3 = 0 Then Set Flag_нажатие End If If Pind.3 = 1 Then Reset Flag_нажатие End If
'Обработка_длительности_нажатия
If Счётчик_времени_нажатия >= 50 Then Set Portd.4 Set Flag_длиное_нажатие Счётчик_времени_нажатия = 0 End If
If Счётчик_времени_нажатия > 10 And Счётчик_времени_нажатия < 50 Then Reset Portd.4 Set Flag_короткое_нажатие Счётчик_времени_нажатия = 0 End If
'что делать при том или ином характере нажатия
If Flag_короткое_нажатие = 1 And Счётчик_длиных_нажатий > 1 Or Счётчик_длиных_нажатий < 4 Then Reset Flag_длиное_нажатие Incr Счётчик_коротких_нажатий Else Счётчик_коротких_нажатий = 0 End If
If Flag_длиное_нажатие = 1 Then Reset Flag_короткое_нажатие Incr Счётчик_длиных_нажатий End If
‘Все переключаемые порты со светодиодами- временная индикация ‘нужная только для отслеживания режимов работы МК при отладке ‘потом они будут уже не нужны и соответствующие строки кода ‘будут удалены 'при первом длинном нажатии
If Счётчик_длиных_нажатий = 1 Then Set Portd.5 Reset Portd.7 Set Flag_настройка_1 End If 'при втором длинном нажатии
If Счётчик_длиных_нажатий = 2 Then Set Portd.6 Reset Portd.5 Set Flag_настройка_2 End If 'при третьем длинном нажатии
If Счётчик_длиных_нажатий = 3 Then Set Portd.7 Reset Portd.6 Set Flag_настройка_3 End If
'при четвертом длинном нажатии
If Счётчик_длиных_нажатий = 4 Then Reset Portd.5 Reset Portd.6 Reset Portd.7 Reset Flag_длиное_нажатие Reset Flag_короткое_нажатие Reset Flag_настройка_1 Reset Flag_настройка_2 Reset Flag_настройка_3 Счётчик_длиных_нажатий = 0 Goto Счёт End If
'при коротком нажатии
If Flag_короткое_нажатие = 1 Then Incr Значение_настраимаемого_разряда If Значение_настраимаемого_разряда > 9 Then Значение_настраимаемого_разряда = 0 End If If Flag_настройка_1 = 1 Then Значение_настраимаемого_разряда = Результат_счёта_1 End If If Flag_настройка_2 = 1 Then Значение_настраимаемого_разряда = Результат_счёта_2 End If If Flag_настройка_3 = 1 Then Значение_настраимаемого_разряда = Результат_счёта_3 End If End If
'непосредственно индикация
Incr Счетчик_разрядов
If Счетчик_разрядов > 3 Then Счетчик_разрядов = 1 End If
If Счетчик_разрядов = 1 Then Portc = &B00000100 'зажигаем первое число
Select Case Результат_счёта_1 Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 Case 11 : Portb = &B11111111 End Select End If Waitms 5
If Счетчик_разрядов = 2 Then Portc = &B00000010 'зажигаем второе число
Select Case Результат_счёта_2 Case 0 : Portb = &B01000000 Case 1 : Portb = &B01111001 Case 2 : Portb = &B00100100 Case 3 : Portb = &B00110000 Case 4 : Portb = &B00011001 Case 5 : Portb = &B00010010 Case 6 : Portb = &B00000010 Case 7 : Portb = &B01111000 Case 8 : Portb = &B00000000 Case 9 : Portb = &B00010000 Case 11 : Portb = &B11111111 End Select End If Waitms 5
If Счетчик_разрядов = 3 Then Portc = &B00000001 'зажигаем третье число
Select Case Результат_счёта_3 Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 Case 11 : Portb = &B11111111 End Select End If Waitms 5 Return
Кнопка: Счётчик_времени_нажатия = 0 Return
Вот ещё Протеус
Добавлено after 7 minutes 22 seconds:
vem566 писал(а):
В приведенном коде прерываний нет. А если динамическая индикация на прерывании по таймеру, то они друг другу не помешают. Не кому остановить индикацию.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 36
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения