библиотеку до конца пока не добил-надо оптимизировать еще,можно вообще на 6 крат замахнуться... 'ЗАДАЕМ ПОЗИЦИИ X Y poz_x = 0 poz_y = 0 call D3310printx4( "12:34") ' увеличение на 4
poz_x = 0 poz_y = 4 call D3310printx2( "6543210") 'увеличение на 2 для обычного шрифта позиция и вывод на жки задается так call D3310position(1 , 1) call D3310print( "12:34")
Прошу прощения, а почему цифры отображаются а шрифт (буквы) выходят крякозяброй?
Мяяяяяуууу!!! И всё таки (не без стакана, правда, валерьянки)) победил я этот счётчик с одной кнопкой! Который скоро будет считать сколько бензина было заправлено (по чеку!) и сколько осталось на данный момент. И не в условных делениях показометра, а в вполне нормальных литрах! Благодарю всех, кто откликнулся, указал на ошибки и подал идеи их решения! Вот что у меня получилось
Код:
$regfile = "m8def.dat" ' Выбор типа контроллера. $crystal = 4000000 ' Частота генератора, Гц. $hwstack = 50 ' Размер аппаратного. $swstack = 30 ' и программных стеков. $framesize = 40
Config Portb = Output 'конфигурация портов
Config Portc = Output
Config Portd = Input
Config Timer0 = Timer , Prescale = 64 ' Конфигурация таймера Timer1. On Timer0 Обработка_нажатия Enable Timer0 ' Назначение подпрограммы прерываний от Timer1
Config Timer2 = Timer , Prescale = 256 ' Конфигурация таймера Timer2. On Timer2 Индикация ' Назначение подпрограммы прерываний от Timer2 Enable Timer2 ' Разрешение прерываний от Timer2
Config Int0 = Falling On Int0 Счёт Enable Int0
Config Int1 = Falling On Int1 Кнопка Enable Int1 'кусок кода, отвечающий за запись текущего значения счётчика при отключении питания 'подсмотренный вот тут: http://bascomavr.3bb.ru/viewtopic.php?id=733 'за что огромное спасибо MACTEPok(ку) Config Aci = On , Compare = Off , Trigger = Rising Acsr.6 = 1 'входAIN0 на внутренний ИОН - 1,23V On Aci Снятие_питания 'подпрограмма прерывания от компаратора Enable Aci Start Ac
Enable Interrupts
'разные нужные переменные и флаги
Dim Коэффициент_пересчёта As Integer Dim Результат_счёта_1 As Byte Dim Результат_счёта_2 As Byte Dim Результат_счёта_3 As Byte ' переменные еепром Dim Результат_счёта_1_eep As Eram Byte At &H16 Dim Результат_счёта_2_eep As Eram Byte At &H17 Dim Результат_счёта_3_eep As Eram Byte At &H18
Dim Счетчик_разрядов 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 Flag_мигание As Byte Dim Счётчик_времени_нажатия As Byte Dim Счётчик_длиных_нажатий As Byte Dim Счётчик_мигания As Byte
Declare Sub Индикация() Declare Sub Обработка_нажатия() Declare Sub Кнопка() Declare Sub Счёт() Declare Sub Обработка_времени_нажатия() Declare Sub Короткое_нажатие() Declare Sub Длиное_нажатие() Declare Sub Снятие_питания()
Do Portd.0 = Acsr.5 ',будем наблюдать сработку компаратора 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
Индикация: 'обработка индикации происходит по прерыванию от timer2 (8 bit) Incr Счетчик_разрядов
If Счетчик_разрядов > 3 Then Счетчик_разрядов = 1 End If ' подготовка к миганию. принцип работы подсмотрено тут: ' http://bascom.at.ua/publ/issledovanie_raboty_7_seg_led_indikatorov_v_bascom/1-1-0-89 ' спасибо sasha_1973!
Incr Счётчик_мигания If Счётчик_мигания > Частота_мигания 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
If Счётчик_мигания > Длительность_горения_при_мигании And Счётчик_длиных_нажатий = 3 Then Portb = &B11111111 End If
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
If Счётчик_мигания > Длительность_горения_при_мигании And Счётчик_длиных_нажатий = 2 Then Portb = &B11111111 End If
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
If Счётчик_мигания > Длительность_горения_при_мигании And Счётчик_длиных_нажатий = 1 Then Portb = &B11111111 End If
End If Waitms 5
Return 'эта часть кода работает от внешнего прерывания int1, настроеного 'на срабатывание по низсходящему фронту, то есть, ИМЕННО в момент нажатия (1->0) кнопки 'потом её можно держать нажатой сколько угодно, но прерывания уже не произойдёт 'пока кнопку не отпустить и снова не нажать. Кнопка:
Счётчик_времени_нажатия = 0
If Pind.3 = 0 And Счётчик_длиных_нажатий > 0 Then Set Flag_короткое_нажатие rcall Короткое_нажатие End If
Return
Обработка_нажатия:
Incr Счётчик_времени_нажатия
If Pind.3 = 1 Then Reset Flag_короткое_нажатие End If
rcall Обработка_времени_нажатия
Return 'вот в этом куске кода у меня остался "косяк" и как его устранить я 'так и не додумался. Дело в том, что КОРОТКОЕ нажатие происходит ВСЕГДА раньше длинного 'на то оно и короткое! Чётко разделить разные нажатия получается только "закрыв МК глаза" циклом 'в течении которого ему всё равно что там ЕЩЁ помимо должно происходить! Ввиду этого, во время 'цикла, гаснет индикация. А без цикла, в момент переключения разрядов при их настройке, фиксируется 'ложное короткое нажатие и тем самым к настроеному как бы уже значению, прибавляется единица. 'То есть, если надо установить значение 5, то настраивать надо 4.
Обработка_времени_нажатия:
If Pind.3 = 0 And Счётчик_времени_нажатия >= 50 Then Set Flag_длиное_нажатие Incr Счётчик_длиных_нажатий Счётчик_времени_нажатия = 0 rcall длиное_нажатие End If
Return
Короткое_нажатие:
If Flag_короткое_нажатие = 1 And Flag_настройка_1 = 1 Then Incr Результат_счёта_3 If Результат_счёта_3 > 9 Then Результат_счёта_3 = 0 End If End If
If Flag_короткое_нажатие = 1 And Flag_настройка_2 = 1 Then Incr Результат_счёта_2 If Результат_счёта_2 > 9 Then Результат_счёта_2 = 0 End If End If
If Flag_короткое_нажатие = 1 And Flag_настройка_3 = 1 Then Incr Результат_счёта_1 If Результат_счёта_1 > 9 Then Результат_счёта_1 = 0 End If End If
Return
Длиное_нажатие: 'при первом длинном нажатии
If Счётчик_длиных_нажатий = 1 Then Set Flag_настройка_1 Reset Flag_настройка_3 End If
'при втором длинном нажатии
If Счётчик_длиных_нажатий = 2 Then Set Flag_настройка_2 Reset Flag_настройка_1 End If 'при третьем длинном нажатии
If Счётчик_длиных_нажатий = 3 Then Set Flag_настройка_3 Reset Flag_настройка_2 End If
'при четвертом длинном нажатии
If Счётчик_длиных_нажатий = 4 Then Reset Flag_длиное_нажатие Reset Flag_короткое_нажатие Reset Flag_настройка_1 Reset Flag_настройка_2 Reset Flag_настройка_3 Счётчик_длиных_нажатий = 0 End If
Return
Снятие_питания:
Portb = &B11111111 ' тушим порты для экономии электроэнергии Результат_счёта_1_eep = Результат_счёта_1 ' запись в еепром Результат_счёта_2_eep = Результат_счёта_2 Результат_счёта_3_eep = Результат_счёта_3
Waitms 2000 ' на 2с МК зависает, если питание вернулось, схема работает дальше Return
Буду примного благодарен, за идеи, как вылечить баг с лишним нажатием. Ну и надеюсь, что моё "творение" окажется кому нибудь полезным.
Что значит - победил? Это же обычная периферия, а не какой-нибудь неведомый протокол. Просто покажите Ваши изыскания, и разберемся.
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
А не проще по нажатию кнопки запускать While цикл, внутри которого что то считать. Условие выхода - отпускание кнопки, после чего проверяем что там насчитало внутри. Мало - короткое нажатие, много - долгое нажатия, очень много - очень долгое нажатие.. Как по мне так достаточно просто и надежнго.
Я как и вы был уверен что всё просто как табурет но не тут-то было.
Работы выше крыши, время не выделить... Речь не идет о том, что все просто, таймер у этого семейства довольно навороченный. Но если не углубляться во все навороты, то обычный Fast PWM в синхронном режиме не так сложно настроить. Другое дело что от всех этих "конфиг-таймеров" остается за кадром сам код. И если возникают какие-либо проблемы, то логичнее открыть даташит, и сконфигурировать периферию напрямую. Куда надежнее. А потом уже можно в пошаговой отладке (даже в самом баскоме) посмотреть что пишется этими магическими командами.
На одно только хочу обратить внимание у этого таймера: не забывайте прописывать OCR1C, это модуль счета для таймера Т1 (таймер считает от 0 и до OCR1C).
Так настраивается напрямую:
Код:
$regfile = "attiny26.dat" $crystal = 8000000
Ddrb = &B00001111 ' настройка пинов порта
Tccr1a = &B01010011 ' режимы ШИМ и вкл запуск ШИМ Tccr1b = &B00000001 ' прескаллер = синхронный режим без делителя
Ocr1a = 5 ' регистр сравнения для 1A Ocr1b = 200 ' регистр сравнения для 1B Ocr1c = 255 ' модуль счета для таймера (максимум счета)
Do
Loop
А с конфигурацией в баскоме нужно смотреть подробнее, у меня тут старая версия для проверки кода, в ней Ваш код не скомпилится...
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Последний раз редактировалось edm2007 Пт мар 24, 2017 07:42:18, всего редактировалось 1 раз.
вот в этом куске кода у меня остался "косяк" и как его устранить я 'так и не додумался. Дело в том, что КОРОТКОЕ нажатие происходит ВСЕГДА раньше длинного 'на то оно и короткое! Чётко разделить разные нажатия получается только "закрыв МК глаза" циклом 'в течении которого ему всё равно что там ЕЩЁ помимо должно происходить! Ввиду этого, во время 'цикла, гаснет индикация. А без цикла, в момент переключения разрядов при их настройке, фиксируется 'ложное короткое нажатие и тем самым к настроеному как бы уже значению, прибавляется единица. 'То есть, если надо установить значение 5, то настраивать надо 4.
Вообще говоря, все абсолютно логично, даже в Windows при двойном клике мышкой сначала посылается сообщение "Нажата_левая_кнопка_мыши", а потом "Двойной_клик_левой_кнопкой_мыши". И разбираться с этим можно только в обработчике "короткого" нажатия: если вы получили сигнал о коротком нажатии прежде чем его обработать, надо убедиться, что это на самом деле короткое нажатие, т.е. надо немножко подождать (примерно столько, сколько это короткое нажатие может длиться) и проверить, нажата ли все еще эта кнопка. только если кнопка уже не нажата, следует обработать короткое нажатие. ну а если еще нажата - обработка не требуется, надо дождаться сигнала о длинном нажатии.
сложно давать рекомендации, когда не очень понятно, как реализована у вас обработка кнопок... лично я в подобных случаях частенько запихивал логику "длинный-короткий" прямо в функцию опроса кнопок: если она возвращает результат с установленным старшим битом, то это долгое нажатие, в младших битах код кнопки.
как-то так...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
edm2007 Снимаю шляпу . И где вы там это углядели , тоже листал дш - но чёт с ходу не фига ни понял . Спасибо вам ! код в том виде что я выложил - работал на других мк без проблем . Для 26-ой я пробовал по всякому ну вот например..Спойлер$regfile = "attiny26.dat" Config Timer1 = Pwm , Compare_A_Pwm = Clear_Up , Compare_B_Pwm = Clear_Down , Prescale = 1
ddrb=255
start timer1 enable interrupts
dim l as Byte
Do wait 1 OCr1A = l 'PWM1A = l incr l Loop
End
_________________ Все мы работаем по методу Робинзона Крузо – ждем пятницу.
Ну да, места не так очевидны, но они есть, и их несколько:
Цитата:
In PWM mode, the Timer/Counter counts up to the value specified in the Output Compare Register OCR1C and starts again from $00. This feature allows limiting the counter “full” value to a specified value, lower than $FF
В режиме ШИМ таймер/счетчик считает до значения в регистре сравнения OCR1C и снова начинает с нуля. Это позволяет ограничить полное значение, и всякое такое...
Ну и в разделе
Цитата:
Timer/Counter1 in PWM Mode
Timer/Counter1 acts as an up-counter, counting from $00 up to the value specified in the Output Compare Register (OCR1C), and starting from $00 up again.
Таймер/счетчик ... считает от 0 до значения, указанного в OCR1C, и снова начинает с 0.
Цитата:
код в том виде что я выложил - работал на других мк без проблем .
Ну тут случай немного другой, да и на самом деле таймеры куда более гибкие, чем их использует среднестатистический баскомоводовед. Хотя, может что-то в новых версиях и изменилось, давно не заглядывал...
Вот у классической AT8, например, сколько режимов работы таймера Т1. И тоже ведь можно настроить модуль счета (TOP) как OCR1A. Только никто обычно так не углубляется. А зря...
Тут только вариантов ШИМ целых 12 штук!!! А в баскоме - "Config Timer = PWM"...
-"Какой у вас ШИМ?" -"А что, их несколько?"
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
коллеги, подскажите, где косяк: типа программный ШИМ, должен плавно зажигать светодиод. но светик загорается и горит ровно. МК Attiny2313a Config Portd.2 = Output : Led Alias Portd.2 Config Timer0 = Timer , Prescale = 1 : On Timer0 Pulse : Enable Timer0 : Enable Interrupts Dim Z As Byte , Y As Integer
Do Y = 10 Loop End
Pulse: Incr Z If Z >= Y Then : Reset Led : Z = 0 Else : Set Led : End If Return
вот в этом куске кода у меня остался "косяк" и как его устранить я 'так и не додумался. Дело в том, что КОРОТКОЕ нажатие происходит ВСЕГДА раньше длинного 'на то оно и короткое! Чётко разделить разные нажатия получается только "закрыв МК глаза" циклом 'в течении которого ему всё равно что там ЕЩЁ помимо должно происходить! Ввиду этого, во время 'цикла, гаснет индикация. А без цикла, в момент переключения разрядов при их настройке, фиксируется 'ложное короткое нажатие и тем самым к настроеному как бы уже значению, прибавляется единица. 'То есть, если надо установить значение 5, то настраивать надо 4.
Вообще говоря, все абсолютно логично, даже в Windows при двойном клике мышкой сначала посылается сообщение "Нажата_левая_кнопка_мыши", а потом "Двойной_клик_левой_кнопкой_мыши". И разбираться с этим можно только в обработчике "короткого" нажатия: если вы получили сигнал о коротком нажатии прежде чем его обработать, надо убедиться, что это на самом деле короткое нажатие, т.е. надо немножко подождать (примерно столько, сколько это короткое нажатие может длиться) и проверить, нажата ли все еще эта кнопка. только если кнопка уже не нажата, следует обработать короткое нажатие. ну а если еще нажата - обработка не требуется, надо дождаться сигнала о длинном нажатии.
сложно давать рекомендации, когда не очень понятно, как реализована у вас обработка кнопок... лично я в подобных случаях частенько запихивал логику "длинный-короткий" прямо в функцию опроса кнопок: если она возвращает результат с установленным старшим битом, то это долгое нажатие, в младших битах код кнопки.
как-то так...
Спасибо за замечание и совет! Суть идеи понятна. Буду пробывать.
коллеги, подскажите, где косяк: типа программный ШИМ...
Здравствуйте.
Для того чтобы написать программную ШИМ, нужна только одна вещь - знать как ШИМ работает. А дальше остается только описать ее работу своими словами. Например, так:
Dim Count As Byte , Bright As Byte ' переменные счетчика ШИМ и значения яркости
'----------
Bright = 100 ' значение яркости
Do
Loop
End
'----------
Pwm_prog: ' прерывание программной ШИМ на Т0
Incr Count
If Count = 255 Then ' модуль счета ШИМ Count = 0 End If
If Count < Bright Then ' управление светодиодом
Set Led
Else
Reset Led
End If
Return
Код:
Bright = 10
Код:
Bright = 100
Код:
Bright = 200
Изменяйте значение яркости, посмотрите как реагирует светодиод, разберитесь с работой кода, там ничего сложного нет. И после этого Вы без проблем допишите именно плавное зажигание / гашение светодиода.
Я смог, а Вы?
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 68
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения