Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Дисплеи и индикация » Кракозяблы на LCD 20x4


Кракозяблы на LCD 20x4

Сообщений 1 страница 30 из 74

1

Ну в чем подвох-то а? Почему у всех все просто, а у меня постоянно грабли на пути? Много лет уже программирую АВРки под свои бытовые нужды и каждый раз бьюсь не над программой, а над разгадыванием очередной загадки. Аж зло берет иногда.

Вот очередная загадка:

https://upforme.ru/uploads/0000/25/b8/1864/t772013.jpg

Ну что не так-то? Почему эта проблема только у меня? Вот схема:

https://upforme.ru/uploads/0000/25/b8/1864/t719683.jpg

Схема стандартная, точь в точь из букваря. Управление индикатором стандартное, ровно как в учебнике. Что не так-то? Вот (на всякий случай) кусок кода:

Код:
'------------------------------------------------------------------------------
$regfile = "m48pdef.dat"                                    'ATmega48P
$crystal = 8000000                                          'внутренний 8МГц
'------------------------------------------------------------------------------
Ddrb = &B11111110                                           'RED2|RED1|SCK|MISO|MOSI|GREEN1|DQ|EN_BUTTON
Ddrc = &B11111111                                           'N/C, RESET, RS, E, D4, D5, D6, D7
Ddrd = &B00000011                                           'BUTTON_1|BUTTON_2|BUTTON_3|EN_2|INT_1|EN_1|OUT_2|OUT_1
'------------------------------------------------------------------------------
Red1 Alias Portb.6                                          'RED1
Red2 Alias Portb.7                                          'RED2
Green1 Alias Portb.2                                        'GREEN1
En_button Alias Pinb.0                                      'EN_BUTTON
Button_1 Alias Pind.7                                       'BUTTON_1
Button_2 Alias Pind.6                                       'BUTTON_2
Button_3 Alias Pind.5                                       'BUTTON_3
En_1 Alias Pind.2                                           'EN_1
En_2 Alias Pind.4                                           'EN_2
Int_1 Alias Pind.3                                          'INT_1
Out_1 Alias Portd.0                                         'OUT_1
Out_2 Alias Portd.1                                         'OUT_2
'------------------------------------------------------------------------------
Config 1wire = Portb.1                                      'DQ DS18B20
'------------------------------------------------------------------------------
Config Lcd = 20x4                                           'LCD 4 строки 20 символов
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
'------------------------------------------------------------------------------
Dim S As Byte : S = 1                                       'указатель
Dim X As Integer
Dim Termos As Integer                                       'термостат
Dim Temp As Integer                                         'температура
Dim Temp_lcd As Single                                      'температура
Dim Time_sec As Byte                                        'секунды
Dim Time_min As Byte                                        'минуты
Dim Time_hour As Byte                                       'часы
Dim Time_dot As Bit                                         'мигающее двоеточие
'------------------------------------------------------------------------------
Config Int0 = Falling                                       'энкодер
On Int0 En_coder_sub
Enable Int0

Config Int1 = Falling                                       'кнопки
On Int1 Button_sub
Enable Int1

Enable Interrupts
'------------------------------------------------------------------------------
Set Green1
Termos = 50
Time_min = 00
Time_hour = 00
Cls : Cursor Off
Gosub Refresh_lcd

Do                                                          'ОСНОВНОЙ ЦИКЛ
   1wreset
   1wwrite &HCC
   1wwrite &H44
   Waitms 480
   1wreset
   1wwrite &HCC
   1wwrite &HBE
   Temp = 1wread(2)

   Temp = Temp * 10
   Temp = Temp / 16
   Temp_lcd = Temp / 10

   'Locate 1 , 16 : Lcd Fusing(temp_lcd , "##.#") ; Chr(223)
    Gosub Refresh_lcd
   Gosub Time_counter
Loop
End
'------------------------------------------------------------------------------
Time_counter:                                               'ВРЕМЯ
   If Time_dot = 1 Then
      Locate 2 , 18 : Lcd ":"

      Incr Time_sec                                         'секунды
      If Time_sec = 60 Then
         Incr Time_min
         Time_sec = 0
      End If

      If Time_min = 60 Then                                 'минуты
         Incr Time_hour
         Time_min = 0
      End If

      If Time_min < 10 Then
         Locate 2 , 19 : Lcd "0" ; Time_min
      Else
         Locate 2 , 19 : Lcd "" ; Time_min
      End If

      If Time_hour = 24 Then Time_hour = 0                  'часы

      If Time_hour < 10 Then
         Locate 2 , 16 : Lcd "0" ; Time_hour
      Else
         Locate 2 , 16 : Lcd "" ; Time_hour
      End If

   Else
      Locate 2 , 18 : Lcd " "
   End If
   Toggle Time_dot
Return
'------------------------------------------------------------------------------
Refresh_lcd:                                                'ИНДИКАЦИЯ
     Cursor Off
   Locate 1 , 2 : Lcd "THERMOS "
   Locate 1 , 10 : Lcd Termos ; ".0" ; Chr(223)
   Locate 1 , 16 : Lcd Fusing(temp_lcd , "##.#") ; Chr(223)
   Locate 2 , 2 : Lcd "TIMER    TIME"
   Locate 3 , 2 : Lcd "ON"
   Locate 3 , 5 : Lcd "30:00"
   Locate 3 , 12 : Lcd "OFF"
   Locate 3 , 16 : Lcd "10:00"
   Locate 4 , 13 : Lcd "ON"
   Locate 4 , 16 : Lcd "22:30"
   Locate 4 , 6 : Lcd "18:10"
   Locate 4 , 2 : Lcd "OFF"
Return
'------------------------------------------------------------------------------
En_coder_sub:                                               'ЭНКОДЕР
   Waitms 1                                                 'антидребезг
   If En_1 = 0 Then                                         'антидребезг
      Select Case S
         Case 1
            If En_2 = 0 Then                                'крутим вправо
               Incr Termos                                  'увеличиваем номер строки
               If Termos > 99 Then Termos = 99
            Else                                            'крутим влево
               Decr Termos                                  'уменьшаем номер строки
               If Termos < 10 Then Termos = 10
            End If
      End Select
   End If
   'Locate 1 , 10 : Lcd Termos ; ".0" ; Chr(223) ; " "
Return
'------------------------------------------------------------------------------
Button_sub:                                                 'КНОПКИ
   If En_button = 0 Then
      Incr S
      If S > 6 Then S = 1

      Select Case S
         Case 1 : Locate 1 , 1 : Lcd ">"
         Case 2 : Locate 3 , 1 : Lcd ">"
         Case 3 : Locate 4 , 1 : Lcd ">"
         Case 4 : Locate 2 , 10 : Lcd ">"
         Case 5 : Locate 3 , 11 : Lcd ">"
         Case 6 : Locate 4 , 12 : Lcd ">"
      End Select
   End If
   Reset Green1 : Waitms 100 : Set Green1                   'антидребезг
Return
'------------------------------------------------------------------------------

Хотя, я уже перепробовал все возможные варианты:

1. Разные способы вывода информации на дисплей: по таймеру, в прерывании, в обработчике нажатий кнопок, каждый символ по отдельности и все вместе. Ничего не помогает.

2. Повесил конденсаторы параллельно всем кнопкам и энкодеру, обвесил ими все питание повсюду. Результата нет.

3. В разрыв цепей D1-D4 впаял RC-фильтры. Результата нет по прежнему нет. Че делато-то?

4. Штудировал Гугл и подобные форумы - никто так и не решил проблему.

5. Менял дисплеи на подобный и даже на 16х2 - толку нет. Менял МК, менял платы, разводку - ничего!

6. Пришел к выводу, что проблема явно не в МК - он в этот момент продолжает работать. Если сдернуть питание с дисплея, он сбрасывается и, на какое-то, время все приходит в норму. Стоит покрутить энкодер или потыкать кнопки - он опять с ума сходит.

Данная ситуация проявляется у меня уже не на первом устройстве, как с ней бороться, ума не приложу. Выручайте друзья.

Отредактировано domen82 (2021-12-20 19:11:32)

0

2

А можно конкретно написать - что не так? Информация какая - то выводится. Не то выводится, так напишите, как должно быть, а то в коде копаться вообще не хочется.

0

3

Строка "Ddrc = &B11111111                                           'N/C, RESET, RS, E, D4, D5, D6, D7" абсолютно не нужна.
RESET - это вход по умолчанию и по вашему подключению, а вы конфигурируете этот пин, как выход.
Остальные пины (для дисплея) указываются далее.

В п/п "Индикация" строку Cursor OFF можно убрать. Команда уже выполнена ранее.

Что за вариация ?
Locate 2 , 19 : Lcd "" ; Time_min
Locate 2 , 16 : Lcd "" ; Time_hour

Сделайте проще:
Locate 2 , 19 : Lcd Time_min
Locate 2 , 16 : Lcd Time_hour

Попробуйте (для начала) вынести работу с DS-кой в отдельную п/п.
У вас Главный цикл молотит только ради его чтения, "отзываясь" только на прерывания.
Да и дергать DS-ку чаще минуты (ИМХО) нет смысла.
Температура - понятие слишком инертное... ;)

Отключайте прерывания при работе с DS-кой и в п/п вывода на дисплей.
Перед выходом из п/п снова включайте.

Меняйте на дисплее только те значения, которые действительно меняются (температура, время и т.п.).
Всю "заголовочную" часть оставляйте неизменной (TIMER, THERMOS).
Старайтесь не использовать CLS, лучше "забивайте" нужные позиции "пробелами".

Честно говоря, так и не понял, что у вас является эталоном для отсчета времени...  :dontknow:
Про обработку прерывания кнопок вообще целый список вопросов... ;)
Как и по самим прерываниям...

Отредактировано Nord (2021-12-14 21:05:09)

0

4

Andrusha написал(а):

А можно конкретно написать - что не так? Информация какая - то выводится. Не то выводится, так напишите, как должно быть, а то в коде копаться вообще не хочется.

У него происходит "глобальный сдвиг" выводимой информации.
Например, написано Locate 1 , 2 : Lcd "THERMOS ", а, судя по фото, вывод аж в середине 3-й строки.
Символы неведомые добавляются... ;)

Отредактировано Nord (2021-12-14 23:10:52)

0

5

длина проводов какая? конденсаторы у LCD и МК есть? Какие?

0

6

Александр Д. написал(а):

длина проводов какая? конденсаторы у LCD и МК есть? Какие?

Маловероятно, что это настолько критично в данном случае.
В блоке КУ для "Патриота" шлейф до дисплея был почти 50 см из-за невозможности проложить напрямую.
Но и даже "внатяг" было бы не менее 35 см... Шлейф после прокладки обрезался "по месту".
Все работало, дисплей не сбоил. И это - в условиях автомобиля...

0

7

Еще заметил...
У вас :
$regfile = "m48pdef.dat"

Попробуйте:
$regfile = "m48def.dat"
или
$regfile = "m48pbdef.dat"

Я уже как-то описывал свои "наблюдения" про нестыковку указанного МК в $regfile и используемого в железе... ;)
Пришлось подбирать...

0

8

Nord написал(а):

Что за вариация ?
Locate 2 , 19 : Lcd "" ; Time_min
Locate 2 , 16 : Lcd "" ; Time_hour

Здравствуйте. Это ЧЕРНОВИК! Я его правил-переправил уже 100500 раз, поэтому он и выглядит так неприглядно. Какой смысл каждый раз его вылизывать при каждом исправлении. Из-за этого же не может дисплей с ума сходить. Проблема явно в чем-то другом.

0

9

в программе есть прерывания?

0

10

Nord написал(а):

Еще заметил...
У вас :
$regfile = "m48pdef.dat"

Попробуйте:
$regfile = "m48def.dat"
или
$regfile = "m48pbdef.dat"

$regfile = "m48def.dat" пробовал - компилируется, но программатор в Баскоме ругается.
$regfile = "m48pbdef.dat" - не пробовал, вечером попробую напишу.

0

11

Александр Д. написал(а):

в программе есть прерывания?

Конечно есть.
Кнопки на INT1
Энкодер на INT0
Также пробовал задействовать TIMER0(1) для обработки температуры или вывода инф. на дисплей - ничего не помогает. В какой-то момент он просто сходит с ума и все. Даже принудительная отправка в него CLS или INITLSD не помогают - не реагирует, только кракозяблы пляшут.
Пробовал тормозить прерывания на время отправки команд в дисплей - пофиг ему все.

0

12

Nord написал(а):

Попробуйте (для начала) вынести работу с DS-кой в отдельную п/п.

Идея, как вариант. Вечером попробую, отпишусь.

Nord написал(а):

У вас Главный цикл молотит только ради его чтения, "отзываясь" только на прерывания.

Nord написал(а):

Да и дергать DS-ку чаще минуты (ИМХО) нет смысла.

Ему какая разница что "молотить"? Уберу работу с DS-кой в отдельную п/п, он же все равно будет молотить пустое место. Это же черновик - пробую разные варианты.

Nord написал(а):

Меняйте на дисплее только те значения, которые действительно меняются (температура, время и т.п.).
Всю "заголовочную" часть оставляйте неизменной (TIMER, THERMOS).
Старайтесь не использовать CLS, лучше "забивайте" нужные позиции "пробелами".

В точности так пробовал - не помогает. :(

0

13

domen82 написал(а):

Конечно есть.
Кнопки на INT1
Энкодер на INT0

Размеры стеков какие? В коде они не заданны.
И еще по поводу прерываний.
Не нужно выводить на дисплей из основного кода и прерываний. Если при выводе из основного кода "прилетит" прерывание в котором тоже вывод на дисплей, будут ошибки примерно такие как у вас. Если переделывать код не хочется, запрещайте прерывания на время вывода из основной части кода.

0

14

Определите размер стеков и фреймбуфера, без них бывает не работает.

0

15

sla174 написал(а):

Определите размер стеков и фреймбуфера, без них бывает не работает.

Как?

0

16

domen82 написал(а):

Как?

$hwstack = 32
$swstack = 32
$framesize = 64

0

17

Пётр написал(а):

Размеры стеков какие? В коде они не заданны.
И еще по поводу прерываний.
Не нужно выводить на дисплей из основного кода и прерываний. Если при выводе из основного кода "прилетит" прерывание в котором тоже вывод на дисплей, будут ошибки примерно такие как у вас. Если переделывать код не хочется, запрещайте прерывания на время вывода из основной части кода.

Так ведь когда исполняется прерывание, выполнение основного цикла прекращается? Т.е. даже если команды дублируют (или повторяют) друг друга, то они все равно будут выполняться в строгой очередности? Или, если в момент выполнения команды в основном цикле, наступает прерывание, то выполнение этой команды прекращается "на пол-пути?, не дожидаясь ее завершения? А после завершения обработки прерывания? Продолжается выполняться прерванная команда или она "забывается" и начинает выполняться следующая? Хм, очень интересно.

0

18

domen82 написал(а):

Так ведь когда исполняется прерывание, выполнение основного цикла прекращается?

Прерывание на уровне ассемблера (машинного кода), а не на уровне исходного. Представьте что во время выполнения строки из основного кода

Код:
Locate 2 , 19 : Lcd "0" ; Time_min

произойдет прерывание и будут выполнены строки

Код:
Button_sub:                                                 'КНОПКИ
   If En_button = 0 Then
      Incr S
      If S > 6 Then S = 1

      Select Case S
         Case 1 : Locate 1 , 1 : Lcd ">"
         Case 2 : Locate 3 , 1 : Lcd ">"
         Case 3 : Locate 4 , 1 : Lcd ">"
         Case 4 : Locate 2 , 10 : Lcd ">"
         Case 5 : Locate 3 , 11 : Lcd ">"
         Case 6 : Locate 4 , 12 : Lcd ">"
      End Select
   End If
   Reset Green1 : Waitms 100 : Set Green1                   'антидребезг
Return

Строка состоит из множества ассемблерных инструкций и прерваться может на любом этапе исполнения. В итоге будет сбой вывода на дисплей.
Waitms не желателен в прерывании.

domen82 написал(а):

Или, если в момент выполнения команды в основном цикле, наступает прерывание, то выполнение этой команды прекращается "на пол-пути", не дожидаясь ее завершения? А после завершения обработки прерывания? Продолжается выполняться прерванная команда

Именно так.

0

19

Александр Д. написал(а):

длина проводов какая?

15мм максимум :) - прямые проводники на печатной плате, параллельно друг-другу.

Александр Д. написал(а):

конденсаторы у LCD и МК есть? Какие?

Разрезал дорожки от МК к линиям D4-D7, в разрыв впаял резисторы. Со стороны дисплея, параллельно линиям, на массу припаял конденсаторы. Резисторы пробовал от 47Ом до 1кОм, конденсаторы от 22пФ до 0.1мкФ. Не помогло ничего.

Отредактировано domen82 (2021-12-15 14:20:18)

0

20

domen82 написал(а):

Так ведь когда исполняется прерывание, выполнение основного цикла прекращается?

Ваша догадка на удивление верна. ;)

В п/п прерывания (обработчике) оставьте минимум операций.
Выставьте флаг срабатывания прерывания, например Флаг_INT1 = 1, прочитайте значение порта, на котором кнопки, которые вообще не понятно, где в вашем "черновике" считываются и бегом в Return.
А в Главном цикле уже принимайте решение, как реагировать на выставленный флаг.

domen82 написал(а):

Ему какая разница что "молотить"?
Уберу работу с DS-кой в отдельную п/п, он же все равно будет молотить пустое место.

И пусть молотит.
Если программа построена на прерываниях, то Главный цикл может оказаться вообще пустым DO....LOOP и все будет работать. ;)

У вас Главный цикл, пока обрабатывает DS-ку, может быть прерван прерыванием, да еще и не одним ;)
Устройства 1-Wire - синхронные элементы, не любят непредвиденных протоколом пауз и сбрасываются в режим ожидания.
Например, выполнены команды:
1wreset
1wwrite &HCC
1wwrite &HBE...
... и тут - опаньки... Прерывание прилетело... Все !
Команда
Temp = 1wread(2)
... уже выполнена не будет, т.к. будет превышение таймаута (нарушение протокола 1-Wire).
В результате вы в качестве температуры будете лицезреть прошлую прочитанную (в лучшем случае) или чепуху, если прерывание придет в процессе выполнения 1wread(2).

Обработчику прерывания фиолетово, чем сейчас занят МК, он разве что однобайтовую команду даст закончить. ;)

Далее...
Не получен ответ, что является "источником" для отсчета в п/п :Time_counter:     'ВРЕМЯ"...
У вас все завязано на только вам понятно как "что-то там считающей" переменной Time_sec... ;)

Incr Time_sec                                         'секунды
    If Time_sec = 60 Then
... ну и дальше...
Return

Включите таймер, определите прерывание для него.

Дальше, как описано выше - выставить флаг, желательно только его и покинуть обработчик...
Кстати, в ходе "принятия решения" определите периодичность обработки DS-ки (вызова п/п).

0

21

domen82 написал(а):

Разрезал дорожки от МК к линиям D4-D7, в разрыв впаял резисторы.

Зачем ?  o.O
Логику рассуждений объясните... ;)

0

22

И еще по прерываниям...
У вас все кнопки разнесены по разным ногам МК.
Для сведения - у линейки ATMega48-...-328 есть прерывания PCINTх.
Используйте их и забудьте про INT1. ;)
Все же уже все расписано Прерывания INT0, INT1, PCINTx Atmega8_88_328

Правду Александр говорит - "Для кого это все делается ?" ;)

0

23

Попробовал в Proteus ваш "черновик" без каких-либо изменений.
Схему упростил, от энкодера оставил только кнопку.

Значение температуры при старте лагает - 85°, дальше считывается адекватно...
Время тикает вроде нормально, но хоть тресни - не пойму, где "источник"... ;)
Нажатия кнопок SB1...3 ожидаемо не приводят ни к какому результату...
На дисплее все нормально.
https://upforme.ru/uploads/0000/25/b8/1743/t127798.jpg

+1

24

Кажется, начинаю понимать, на какие грабли вы периодически наступаете... ;)
Выши слова из начального поста:

domen82 написал(а):

6. Пришел к выводу, что проблема явно не в МК - он в этот момент продолжает работать. Если сдернуть питание с дисплея, он сбрасывается и, на какое-то, время все приходит в норму. Стоит покрутить энкодер или потыкать кнопки - он опять с ума сходит.
            Данная ситуация проявляется у меня уже не на первом устройстве, как с ней бороться, ума не приложу.

Вы упорно не выполняете п.5 из рекомендуемых Советы по оформлению программы ;)

Начните сначала, не меняя схемотехнику.
Отработайте вывод на дисплей.
Отработайте "человеческий" отсчет времени (в вашей версии будет чудить).
Подключите к работе DS-ку.
Подключите к работе кнопки (их роль нам пока неизвестна).
Подключите к работе энкодер (тут немного понятнее)...

Если делать все поэтапно, то вылезающие баги будут наиболее вероятны из-за нововведений в программу.
Будет гораздо легче искать и бороться.
Разумеется, применив ранее изложенные предложения в этой теме... ;)

У вас не схематическая, а программная ошибка гуляет.
Исправляйте.

Отредактировано Nord (2021-12-15 23:55:32)

+1

25

Nord написал(а):

Попробовал в Proteus ваш "черновик" без каких-либо изменений.

аналогично, всё работает

https://upforme.ru/uploads/0000/25/b8/1217/t811485.jpg

+1

26

Приветствую парни! Проблему я решил, вроде работает без косяков. Проблема была в том, что в момент отправки команды в дисплей срабатывало прерывание энкодера или кнопки. Вот дисплей и сходил с ума. Короче я понял так: на время исполнения подпрограммы вывода информации на дисплей нужно тормозить некоторые прерывания или исполнять подпрограмму в обработчике TIMERа. Попробовал так и так - все работает. СПАСИБО всем откликнувшимся - в прямом смысле слова "наставили на путь истинный".

Я еще немного потренируюсь над своим "изобретением", подлижу исходник и выложу на показ. А то правильно получилось - носом в черновик натыкали (не подумал).

0

27

Nord написал(а):

На дисплее все нормально.

sasha_1973 написал(а):

аналогично, всё работает

Ну не мне же вам рассказывать про Протеус? Что наивные-то такие? В Протеусе всегда все работает, а вот реальность сурова - с железом приходится по**ться. Иной раз пока до готового устройства поделку доведешь, уже не нет в ней такой необходимости, соразмерной потраченному на нее времени.

Nord написал(а):

У вас все кнопки разнесены по разным ногам МК.

Может мне так удобнее?

Nord написал(а):

Зачем ?  o.O
Логику рассуждений объясните... ;)

Да я когда не знал как победить этот сумасшедший дисплей, я в отчаянье был на все готов - лазил по разным форумам и начитался такого бреда, такого насоветовали. Сам-то я прекрасно понимаю, что это нафиг не нужно. Но человек на форуме утверждал, что ему помогло - вот и решил попробовать. Я эти резисторы в схему не планировал и не рисовал и на плате не разводил. Просто, выше, один из участников нашей дискуссии спросил про эти резисторы, вот я ему и объяснил, что такой метод я уже попробовал.

0

28

domen82 написал(а):

Nord написал(а):У вас все кнопки разнесены по разным ногам МК.
Может мне так удобнее?

Я не призывал кнопки лепить на одну ногу МК. ;)
Я лишь указал на возможность использования для каждой кнопки отдельного прерывания, что заметно облегчило бы работу с кнопками.

+1

29

Использование прерываний PCINTх применительно к вашей схемотехнике.

Добавляете переменную:

Dim flag_knop As Byte                                     ' флаг нажатия кнопки

Определяете прерывания:

Config Int0 = Falling                                       'энкодер
On Int0 En_coder_sub

'Config Int1 = Falling                                       'кнопки
'On Int1 Button_sub

PCMSK2.PCINT21 = 1                                     ' прерывание от SB3
PCMSK2.PCINT22 = 1                                     ' прерывание от SB2
PCMSK2.PCINT23 = 1                                     ' прерывание от SB1
On PCInt2 Button_sub

Enable Pcint2
Enable Int0
'Enable Int1
Enable Interrupts

Обработчик прерываний от кнопок теперь выглядит так:

Button_sub:                                                 'КНОПКИ

If PIND.7 = 0 Then flag_knop = 1       ' кнопка SB1
If PIND.6 = 0 Then flag_knop = 2       ' кнопка SB2
If PIND.5 = 0 Then flag_knop = 3       ' кнопка SB3

Return

Дальше в Главном цикле описываете реакцию программы в зависимости от значения flag_knop...

В результате освобождаем INT1 для других целей и четко выделяем каждую кнопку.

0

30

domen82 написал(а):

Проблема была в том, что в момент отправки команды в дисплей срабатывало прерывание энкодера или кнопки. Вот дисплей и сходил с ума.

Про это вам сказали в самом начале. ;)

domen82 написал(а):

Короче я понял так: на время исполнения подпрограммы вывода информации на дисплей нужно тормозить некоторые прерывания или исполнять подпрограмму в обработчике TIMERа.

В целом все верно, только не надо загружать обработчик TIMERа.
Пусть он занимается только своим делом - "тики" отсчитывает. ;)

Config Timer1 = Timer, Prescale = 64        ' Переполнение примерно 0,5 сек (0,524 сек)

.....

On Timer1 pulse             ' добавляем к другим назначениям прерываний
Enable Timer1

.....
'                                    Главный цикл
If count = 1 Then
    Incr count_disp    ' отсчет "тиков" для дисплея
    Incr count_min    ' отсчет "тиков" для времени
    Incr count_ds      ' отсчет "тиков" для чтения DS-ки
    count = 0
End If

.....

pulse:         ' обработка прерывания TIMER1

count = 1

Return

А вот в Главном цикле, отсчитав нужное количество "тиков", делайте вызов п/п вывода на дисплей и пр.
Допустим:
count_disp = 4        ' вывод на дисплей каждые 2 сек
count_min = 120     ' отсчитана 1 минута
count_ds = 240       ' каждые 2 мин читаем DS-ку
Не забывайте обнулять значение этих переменных при достижении максимальных значений.

Отредактировано Nord (2021-12-17 22:56:52)

0


Вы здесь » Программирование ATMEL в BASCOM. » Дисплеи и индикация » Кракозяблы на LCD 20x4