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

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

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

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


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


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

Сообщений 31 страница 60 из 74

31

В общем, все заработало, как запланировано, но есть вопросы. Например, обработка с энкодера - с*ка, теперь он косячит. Т.е. косячу явно я, но виноват-то он!

Соответственно, вопрос, вытекающий из вопроса: дальнейшее обсуждение исходника для сего девайса продолжать здесь или эту тему "Кракозяблы на LCD 20x4" завернуть и создать новую? Например "Таймер-термостат"? И в ней уже обсуждать правильную структуру исходника и тыкать меня носом? Дело в том, что я самоучка и, вопросов по теме у меня еще много. Да и завсегдатаем форума есть чем развлечься.

Лично я, вынес-бы обсуждение отдельного устройства в отдельную тему. Наверное так нужно было сделать с самого начала. Но я надеялся на то, что с кракозяблами на LCD все закончится или, что никто на форуме не пошевелится. А нет - живой еще форум! Чему я несказанно рад.

Отредактировано domen82 (2021-12-19 17:09:09)

0

32

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

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

Уточню еще раз - это черновик! Я его, конечно, подлизал, прокомментировал, но это не истина поэтому, прошу сильно не пинать.

Код:
'------------------------------------------------------------------------------
$regfile = "m8adef.dat"                                               'ATmega8A
$crystal = 8000000                                                    'внутренний 8МГц
'$prog &HFF , &H04 , &HDF , &HFF                                       'generated. Take care that the chip supports all fuse bytes.
$hwstack = 40
$swstack = 16
$framesize = 32
'------------------------------------------------------------------------------
Ddrb = &B11111110                                                     'RED2|RED1|SCK|MISO|MOSI|GREEN1|DQ|EN_BUTTON
Ddrc = &B10111111                                                     '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 Termos As Integer                                                 'термостат
Dim Temp As Integer                                                   'температура
Dim Temp_compare As Integer                                           'температура для сравнения с термостатом
Dim T As String * 4                                                   'температура для вывода на LCD
Dim Time_sec As Byte                                                  'секунды
Dim Time_min As Byte                                                  'минуты
Dim Time_hour As Byte                                                 'часы
Dim Time_dot As Bit                                                   'мигающее двоеточие
'------------------------------------------------------------------------------
Config Int0 = Rising                                                  'энкодер
On Int0 En_coder_sub
Enable Int0

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

Config Timer1 = Timer , Prescale = 64                                 'времазадающий генератор, 0.52 сек. + коррекция в подпрограмме
On Timer1 Time_count
Enable Timer1
'------------------------------------------------------------------------------
Cls : Cursor Off                                                      'СТАТИЧНАЯ ИНДИКАЦИЯ
Upperline : Lcd " TERMOS    .0" ; Chr(223) ; "     " ; Chr(223)       'первая строка
Lowerline : Lcd " TIMER    TIME      "                                'вторая строка
Thirdline : Lcd " ON        OFF      "                                'третья строка
Fourthline : Lcd " OFF        ON      "                               'четвертая строка
Enable Interrupts                                                     'прерывания разрешаем после формирования изображения, иначе LCD не успевает
'------------------------------------------------------------------------------
Do                                                                    'ОСНОВНОЙ ЦИКЛ
   Set Green1
   Gosub Lcd_sub                                                      'обновление LCD
   Gosub Time_sub                                                     'счет времени
   Gosub Temp_sub                                                     'температура
   Gosub Compare_sub
Loop
End
'------------------------------------------------------------------------------
Compare_sub:
   Temp_compare = Temp / 10                                           'откидываем десятые доли от температуры
   If Termos >= Temp_compare Then
      Set Red1
   Else
      Reset Red1
   End If
Return
'------------------------------------------------------------------------------
Lcd_sub:                                                              'ОБНОВЛЕНИЕ LCD
   Disable Interrupts                                                 'тормозим прерывания, что-бы LCD не сходил с ума

   Select Case Temp                                                   'ТЕМПЕРАТУРА
      Case Is < 0 : Locate 1 , 16 : Lcd " MIN"                        'ниже 0 не показываем
      Case 0 To 99 : Locate 1 , 16 : Lcd Format(t , " 0.0")           'от 0 до 9
      Case 100 To 999 : Locate 1 , 16 : Lcd Format(t , "00.0")        'от 10 до 99
      Case 1000 To 1200 : Locate 1 , 16 : Lcd " " ; Left(t , 3)       'от 100 до 120
      Case Is > 1200 : Locate 1 , 16 : Lcd " MAX"                     'выше 120 не показываем
   End Select

   Select Case Termos                                                 'ТЕРМОСТАТ
      Case 0 To 9 : Locate 1 , 9 : Lcd "  " ; Termos                  'от 0 до 9
      Case 10 To 99 : Locate 1 , 9 : Lcd " " ; Termos                 'от 10 до 99
      Case 100 To 120 : Locate 1 , 9 : Lcd Termos                     'от 100 до 120
   End Select

   Select Case Time_dot                                               'мигающее двоеточие
      Case 1 : Locate 2 , 18 : Lcd ":"
      Case 0 : Locate 2 , 18 : Lcd " "
   End Select

   Select Case S                                                      'УКАЗАТЕЛЬ
      Case 1 : Locate 1 , 1 : Lcd ">" : Locate 4 , 12 : Lcd " "       'TERMOS
      Case 2 : Locate 3 , 1 : Lcd ">" : Locate 1 , 1 : Lcd " "        'TIMER ON
      Case 3 : Locate 4 , 1 : Lcd ">" : Locate 3 , 1 : Lcd " "        'TIMER OFF
      Case 4 : Locate 2 , 10 : Lcd ">" : Locate 4 , 1 : Lcd " "       'TIME
      Case 5 : Locate 3 , 11 : Lcd ">" : Locate 2 , 10 : Lcd " "      'TIME OFF
      Case 6 : Locate 4 , 12 : Lcd ">" : Locate 3 , 11 : Lcd " "      'TIME ON
   End Select

   Select Case Time_hour                                              'ВРЕМЯ
      Case 0 To 9 : Locate 2 , 16 : Lcd "0" ; Time_hour               'часы от 0 до 9
      Case 10 To 23 : Locate 2 , 16 : Lcd Time_hour                   'часы от 10 до 23
   End Select

   Select Case Time_min
      Case 0 To 9 : Locate 2 , 19 : Lcd "0" ; Time_min                'минуты от 0 до 9
      Case 10 To 59 : Locate 2 , 19 : Lcd Time_min                    'минуты от 10 до 59
   End Select

   Enable Interrupts
   Waitms 100                                                         'уменьшить - начинает косячить энкодер
Return
'------------------------------------------------------------------------------
En_coder_sub:                                                         'ЭНКОДЕР
   Reset Green1 : Waitms 1                                            'антидребезг

   If En_1 = 1 Then                                                   'антидребезг
      Select Case S

         Case 1                                                       'указатель на TERMOS
            If En_2 = 1 Then                                          'крутим вправо
               Incr Termos                                            'увеличиваем TERMOS
            Else                                                      'крутим влево
               Decr Termos                                            'уменьшаем TERMOS
            End If
            If Termos > 120 Then Termos = 120                         'максимум 120гр.
            If Termos < 0 Then Termos = 0                             'минимум 1гр.

         Case 4                                                       'указатель на TIME
            If En_2 = 1 Then                                          'крутим вправо
               Incr Time_min                                          'увеличиваем TIME
            Else                                                      'крутим влево
               Decr Time_min                                          'уменьшаем TIME
            End If
            Time_sec = 0
      End Select
   End If
   Gifr = 64
Return
'------------------------------------------------------------------------------
Button_sub:                                                           'КНОПКИ
   If En_button = 0 Then                                              'кнопка энкодера
      Incr S                                                          'увеличиваем номер пункта
      If S > 6 Then S = 1                                             'всегор 6 пунктов
   End If

   Reset Green1 : Waitms 100                                          'антидребезг
   Gifr = 128
Return
'------------------------------------------------------------------------------
Time_count:                                                           'ВРЕМЯ
   If Time_dot = 1 Then Incr Time_sec                                 'тикаем секунды
   Timer1 = 3000                                                      'корректировка точности часов
   Toggle Time_dot                                                    'мигающее двоеточие
Return
'------------------------------------------------------------------------------
Time_sub:                                                             'СЧЕТ ВРЕМЕНИ
   If Time_sec = 60 Then                                              'в минуте 60 сек.
      Incr Time_min
      Time_sec = 0
   End If

   If Time_min >= 60 Then
      Incr Time_hour                                                  'в часе 60 мин.
      Time_min = 0
   End If

   If Time_hour = 23 Then Time_hour = 0                               'в сутках 24 часа
Return
'------------------------------------------------------------------------------
Temp_sub:                                                             'ТЕМПЕРАТУРА
   If Time_dot = 1 Then
      1wreset
      1wwrite &HCC
      1wwrite &H44
   Else
      1wreset
      1wwrite &HCC
      1wwrite &HBE
      Temp = 1wread(2)
      Temp = Temp * 10
      Temp = Temp / 16
      T = Str(temp)                                                   'что-бы вывести дробную часть на LCD
   End If
Return
'------------------------------------------------------------------------------

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

+1

33

Не надо плодить темы, будет размыта линия обсуждения.
Лучше попросите Администрацию изменить заголовок.

Плиз, отредактируйте сообщение... ;)
Выделите листинг и нажмите "Свернутый текст" или "Цитата"...
А то тема в такие портянки превращается...  :canthearyou:

Вы таки упорно пытаетесь читать кнопки через одно прерывание ? ;)
Я же предложил вам уже готовый обработчик.
В использованном сейчас Mega8 прерываний PCINTx нет, но и в предыдущем Mega48 места хватало.

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

Config Int1 = Falling                                                 'кнопки

Только, кроме обработки кнопки энкодера у вас нигде не видны другие кнопки...

Далее... Зачем этот шаг ?

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

Compare_sub:
Temp_compare = Temp / 10                                       'откидываем десятые доли от температуры
....

Сделайте проще (выделено):

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

Temp_sub:
....
Temp = 1wread(2)
Temp = Temp \ 16

Сэкономите и на переменных и на ненужной арифметике.

И не слишком ли часто пинаете DS-ку - каждые пол-секунды ?
На 100500% уверен, что температура за этот промежуток ощутимо не изменится.
Сделайте 2, а то и 5 сек хотя бы... Лично я не буду к нему лезть чаще 30 сек - бессмысленно.
Хотя - дела ваше... ;)

Отредактировано Nord (2021-12-19 18:02:10)

0

34

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

лезть чаще 30 сек - бессмысленно

Так это ж термостат. За 30 секунд температура ого куда скакнуть может.

0

35

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

Так это ж термостат. За 30 секунд температура ого куда скакнуть может.

А за 0,5 сек она куда скаканет ? ;)
Да принимая во внимание, что "это ж термостат" - 2...3 сек будет вполне.
DS-ка не настолько скоростная... ;)

0

36

её оптимально опрашивать раз в 5-6 секунд, так как производитель указывает на саморазогрев чипа при замере.
У меня везде именно такой период опроса.

0

37

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

её оптимально опрашивать раз в 5-6 секунд, так как производитель указывает на саморазогрев чипа при замере.

Тем более !

0

38

Кстати...
Зачем использовать весьма тормозные Format(t , " 0.0") и подобные, если в вычислениях конечное значение целочисленное ?
Используйте конструкцию типа:

If Temp < 10 Then
      Locate 1 , 16 : Lcd "0"; Temp           'от 0 до 9
Else
      Locate 1 , 16 : Lcd Temp                  'от 10 до 99
End If

Отредактировано Nord (2021-12-19 18:25:01)

0

39

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

Плиз, отредактируйте сообщение...
Выделите листинг и нажмите "Свернутый текст" или "Цитата"...
А то тема в такие портянки превращается...

Согласен, нажал "код" - наверное так правильнее будет?

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

Вы таки упорно пытаетесь читать кнопки через одно прерывание ?
Я же предложил вам уже готовый обработчик.
В использованном сейчас Mega8 прерываний PCINTx нет, но и в предыдущем Mega48 места хватало.

Мне так удобнее в других проектах, и в этом. Спасибо за "готовый обработчик" - сохранил себе в архив. В мегу48 все запланированное "не влезло" (так хотелось от нее избавиться) - поэтому и не использую "частные" особенности для конкретного МК - что-бы можно было легко перейти на другой.

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

Только, кроме обработки кнопки энкодера у вас нигде не видны другие кнопки...
Далее... Зачем этот шаг ?

Написал-же: Ч Е Р Н О В И К !!! Кнопки будут, еще кнопки будут! Сейчас, только, кнопка энкодера работает. С остальными все будет по такому-же принципу. Схему видели: работает одна кнопка - РАБОТАЮТ ВСЕ. Зачем засирать черновик ненужными даными?

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

Temp = Temp \ 16

Чем предложенный "Temp = Temp \ 16" отличается от моего "Temp = Temp / 16"? Я исхожу из логики арифметических действий. Но могу быть не прав - аргументируйте свой ответ.

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

И не слишком ли часто пинаете DS-ку - каждые пол-секунды ?

Да что Вы к этой DS-ке прикопались? Какая разница для проекта (в целом) как часто я ее опрашиваю? Согласен, часто - но это же не мешает решению поставленного вопроса?

0

40

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

Кнопки будут, еще кнопки будут! Сейчас, только, кнопка энкодера работает.Зачем засирать черновик ненужными даными?

Использую вашу схемотехнику и ваши исходники.
Я призываю вписать в обработчик сразу все, что он должен делать и использовать эти данные в ходе развития программы.
Добавьте три строки:
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

Поверьте, так будет проще, чем потом листать программу в поисках "где-то что-то забыл..." ;)

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

Чем предложенный "Temp = Temp \ 16" отличается от моего "Temp = Temp / 16"? Я исхожу из логики арифметических действий. Но могу быть не прав - аргументируйте свой ответ.

/ 16 - результат деления будет с дробной частью, а если \ 16, это - целочисленное деление.
Тем более, что вы используете тип Integer для расчета температуры.
Читайте Справку https://avrhelp.mcselec.com/
Сразу избавляетесь от ненужных "нулей", которые зазря висят на дисплее, экономите время работы п/п и объем кода.

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

Да что Вы к этой DS-ке прикопались? Какая разница для проекта (в целом) как часто я ее опрашиваю? Согласен, часто - но это же не мешает решению поставленного вопроса?

Больше не буду...  :blush:
Просто делайте сразу "по уму", а то при дальнейшей работе все может "поплыть".

Отредактировано Nord (2021-12-19 22:01:26)

0

41

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

обработка с энкодера - с*ка, теперь он косячит.

В чем выражается "косяк" ?
Я в Протеусе "крутилку"  и его кнопку наблюдаю адекватно...

Отредактировано Nord (2021-12-19 19:53:09)

0

42

Выводы энкодера и кнопок подтянуты к плюсу резисторами?

0

43

  написал(а):

обработка с энкодера - с*ка, теперь он косячит.

Работа с энкодерами

+1

44

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

Выводы энкодера и кнопок подтянуты к плюсу резисторами?

См. схему в первом посту

0

45

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

Работа с энкодерами

"Для кого все это делается ?" (с) не моё ;)

+1

46

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

"Для кого все это делается ?" (с) не моё

А шоб було.

Просто всем интересно наступать на грабли, хорошо, если один раз.

0

47

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

всем интересно наступать на грабли

На своём опыте заметил, только работа над своими граблями глубоко откладывается в памяти, позволяет разобраться в вопросе и избежать последующих ошибок. Чужой код - это рыба, а нужны удочки.  :flag:

+5

48

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

На своём опыте заметил, только работа над своими граблями глубоко откладывается в памяти

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

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

Чужой код - это рыба, а нужны удочки.

Рыбалка - это азартное занятие. Лично я - далеко не рыбак !

А разве не возникает азарта, когда кто-то (как в этой теме, например) задает вопрос и ты начинаешь "ловить рыбку" в чужом коде, имея в качестве удочки только собственный опыт и знания ?
Да, здесь далеко не все такие великие и всезнающие...
Но ведь интересно, да еще и помочь хочется... Если действительно можешь... ;)

Отредактировано Nord (2021-12-20 01:23:04)

+2

49

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

Сразу избавляетесь от ненужных "нулей", которые зазря висят на дисплее, экономите время работы п/п и объем кода.

Приветствую. Не стану упираться, но вот, что мы видим на дисплее, когда "/16":

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

- никаких нолей! Просто цифра без точки отделяющей десятые доли градуса. Т.е. цифра "176" это "17.6*С"

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

Зачем использовать весьма тормозные Format(t , " 0.0") и подобные, если в вычислениях конечное значение целочисленное ?

Согласен, не лучший вариант. Но как тогда мне отделить дробную часть от целой? Не придумал ничего лучше чем Integger преобразовать в String уже его Format-ировать. Мне самому такой подход не нравится - лишнее это все. В идеале, нужно как-то придумать выводить "176" на дисплей, но что-бы с точкой: "17.6"

0

50

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

В чем выражается "косяк" ?
Я в Протеусе "крутилку"  и его кнопку наблюдаю адекватно...)

В одну сторону считает отлично и быстро, а в другую через раз. Еще и поганит - крутишь на один щелчок влево, а он сначала на одну цифру вправо скакнет, а потом нормально влево считает. Быстро крутишь влево - пропускает щелчки. Вправо все работает идеально. Поменял местами вывода на энкодере (физически перепаял) - то же самое. т.е. энкодер точно не причем - косяк в программе.

Должно пройти, по крайней мере 600 секунд, между отправкой сообщений. Пожалуйста, попробуйте отправить очередное сообщение немного позже

Друзья, как мне с вами общаться с такими паузами между постами? У меня борода заново отрастает пока я пережидаю этот каприз :) Чей недоразвитый мозг это придумал вообще? На форуме итак народу нет, вы еще и палки в колеса вставляете тем, кто хоть немного увлечен.

0

51

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

/ 16 - результат деления будет с дробной частью, а если \ 16, это - целочисленное деление

Сейчас попробовал так и так - ничего не меняется на дисплее.

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

Читайте Справку

Если-бы я умел читать, тогда мне Ваши советы были-бы не нужны! Мы здесь для того и собрались, что-бы делиться практическим опытом "наступания на грабли".

0

52

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

Не стану упираться, но вот, что мы видим на дисплее, когда "/16"

Вы используете Integer в качестве переменной для значения температуры.
Мои пробы показали, что в данном случае использование \ или / значения не имеет - в результате будет целое число.
Уже давно использую такую "связку":

Dim Temp As Integer
....
Temp = 1wread(2, PIND, 6)
Temp = Temp\16                          ' Получаем готовую температуру с знаком

Никаких проблем, получаю ожидаемое... ;)
А вы для чего-то до деления умножаете на 10...
Вот ваш пересчет:

Temp = 1wread(2)
Temp = Temp * 10
Temp = Temp / 16

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

Поменял местами вывода на энкодере (физически перепаял) - то же самое. т.е. энкодер точно не причем - косяк в программе.

Попробуйте вот эту наработку Александра из темы, уже предложенной им ранее Исследование энкодера
Проверено практически - работает "на ура".

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

Если-бы я умел читать...

Повеселили, спасибо... ;)
Разумеется, у каждого свой подход к поиску решения.

Отредактировано Nord (2021-12-20 19:48:41)

0

53

Еще вопрос, как на LCD вывести символ:

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

- Chr(016) ничего не выводит (пустое место)?

0

54

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

А вы для чего-то до деления умножаете на 10...

Код:
   1wreset
   1wwrite &HCC
   1wwrite &HBE
   T = 1wread(2)
   Минус = T.15                  ' читаем знак температуры
   T = Abs(t)
   T = T * 10
   T = T / 16

Вот так получается значение температуры с десятыми, но в виде целого числа. Остаётся поставить точку. Подсмотрел у одного поляка.

0

55

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

Dim Temp As Integer
....
Temp = 1wread(2, PIND, 6)
Temp = Temp\16                          ' Получаем готовую температуру с знаком

Пробовал - дробная часть отпала совсем:

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

Код:
'------------------------------------------------------------------------------
$regfile = "m8adef.dat"                                               'ATmega8A
$crystal = 8000000                                                    'внутренний 8МГц
'$prog &HFF , &H04 , &HDF , &HFF                                       'generated. Take care that the chip supports all fuse bytes.
'$hwstack = 40
'$swstack = 16
'$framesize = 32
'------------------------------------------------------------------------------
Ddrb = &B11111110                                                     'RED2|RED1|SCK|MISO|MOSI|GREEN1|DQ|EN_BUTTON
Ddrc = &B10111111                                                     '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 Termos As Integer : Dim Termos_eram As Eram Integer               'термостат
Dim Temp As Integer                                                   'температура
Dim Temp_compare As Integer                                           'температура для сравнения с термостатом
Dim T As String * 4                                                   'температура для вывода на LCD
Dim Time_sec As Byte                                                  'секунды
Dim Time_min As Byte                                                  'минуты
Dim Time_hour As Byte                                                 'часы
Dim Time_dot As Bit                                                   'мигающее двоеточие
'------------------------------------------------------------------------------
Config Int0 = Rising                                                  'энкодер
On Int0 En_coder_sub
Enable Int0

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

Config Timer1 = Timer , Prescale = 64                                 'времазадающий генератор, 0.52 сек. + коррекция в подпрограмме
On Timer1 Time_count
Enable Timer1
'------------------------------------------------------------------------------
Cls : Cursor Off                                                      'СТАТИЧНАЯ ИНДИКАЦИЯ

Upperline : Lcd " TERMOS    .0" ; Chr(223) ; "     " ; Chr(223)       'первая строка
Lowerline : Lcd " TIMER    TIME      "                                'вторая строка
Thirdline : Lcd " ON        OFF      "                                'третья строка
Fourthline : Lcd " OFF        ON      "                               'четвертая строка
Enable Interrupts                                                     'прерывания разрешаем после формирования изображения, иначе LCD не успевает

Termos = Termos_eram                                                  'достаем уставку TERMOS из памяти
'------------------------------------------------------------------------------
Do                                                                    'ОСНОВНОЙ ЦИКЛ
   Set Green1
   Gosub Lcd_sub                                                      'обновление LCD
   Gosub Time_sub                                                     'счет времени
   Gosub Temp_sub                                                     'температура
   Gosub Compare_sub                                                  'сравнение заданых параметров
Loop
End
'------------------------------------------------------------------------------
Compare_sub:
   Temp_compare = Temp / 10                                           'округляем до целых
   If Temp_compare >= Termos Then                                     'гистерезис 1гр.
      Set Red1
   Else
      Reset Red1
   End If
Return
'------------------------------------------------------------------------------
Lcd_sub:                                                              'ОБНОВЛЕНИЕ LCD
   Disable Interrupts                                                 'тормозим прерывания, что-бы LCD не сходил с ума

   Select Case Temp                                                   'ТЕМПЕРАТУРА
      Case Is < 0 : Locate 1 , 16 : Lcd " MIN"                        'ниже 0 не показываем
      'Case 0 To 99 : Locate 1 , 16 : Lcd Format(t , " 0.0")           'от 0 до 9
      'Case 100 To 999 : Locate 1 , 16 : Lcd Format(t , "00.0")        'от 10 до 99
      'Case 1000 To 1200 : Locate 1 , 16 : Lcd " " ; Left(t , 3)       'от 100 до 120
      Case 0 To 1200 : Locate 1 , 16 : Lcd Temp
      Case Is > 1200 : Locate 1 , 16 : Lcd " MAX"                     'выше 120 не показываем
   End Select

   Select Case Termos                                                 'ТЕРМОСТАТ
      Case 0 To 9 : Locate 1 , 9 : Lcd "  " ; Termos                  'от 0 до 9
      Case 10 To 99 : Locate 1 , 9 : Lcd " " ; Termos                 'от 10 до 99
      Case 100 To 120 : Locate 1 , 9 : Lcd Termos                     'от 100 до 120
   End Select

   Select Case Time_dot                                               'мигающее двоеточие
      Case 1 : Locate 2 , 18 : Lcd ":"
      Case 0 : Locate 2 , 18 : Lcd " "
   End Select

   Select Case S                                                      'УКАЗАТЕЛЬ
      Case 1 : Locate 1 , 1 : Lcd ">" : Locate 4 , 12 : Lcd " "       'TERMOS
      Case 2 : Locate 3 , 1 : Lcd ">" : Locate 1 , 1 : Lcd " "        'TIMER ON
      Case 3 : Locate 4 , 1 : Lcd ">" : Locate 3 , 1 : Lcd " "        'TIMER OFF
      Case 4 : Locate 2 , 10 : Lcd ">" : Locate 4 , 1 : Lcd " "       'TIME
      Case 5 : Locate 3 , 11 : Lcd ">" : Locate 2 , 10 : Lcd " "      'TIME OFF
      Case 6 : Locate 4 , 12 : Lcd ">" : Locate 3 , 11 : Lcd " "      'TIME ON
   End Select

   Select Case Time_hour                                              'ВРЕМЯ
      Case 0 To 9 : Locate 2 , 16 : Lcd "0" ; Time_hour               'часы от 0 до 9
      Case 10 To 23 : Locate 2 , 16 : Lcd Time_hour                   'часы от 10 до 23
   End Select

   Select Case Time_min
      Case 0 To 9 : Locate 2 , 19 : Lcd "0" ; Time_min                'минуты от 0 до 9
      Case 10 To 59 : Locate 2 , 19 : Lcd Time_min                    'минуты от 10 до 59
   End Select

   Enable Interrupts
   Waitms 100                                                         'уменьшить - начинает косячить энкодер
Return
'------------------------------------------------------------------------------
En_coder_sub:                                                         'ЭНКОДЕР
   Reset Green1 : Waitms 1                                            'антидребезг

   If En_1 = 1 Then                                                   'антидребезг
      Select Case S

         Case 1                                                       'указатель на TERMOS
            If En_2 = 1 Then                                          'крутим вправо
               Incr Termos                                            'увеличиваем TERMOS
            Else                                                      'крутим влево
               Decr Termos                                            'уменьшаем TERMOS
            End If
            If Termos > 120 Then Termos = 120                         'максимум 120гр.
            If Termos < 0 Then Termos = 0                             'минимум 1гр.

         Case 4                                                       'указатель на TIME
            If En_2 = 1 Then                                          'крутим вправо
               Incr Time_min                                          'подводим минуты
            Else                                                      'крутим влево
               Decr Time_min                                          'подводим часы
            End If
            Time_sec = 0
      End Select
   End If

   Termos_eram = Termos                                               'сохраняем уставку TERMOS в памяти
   Gifr = 64
Return
'------------------------------------------------------------------------------
Button_sub:                                                           'КНОПКИ
   If En_button = 0 Then                                              'кнопка энкодера
      Incr S                                                          'увеличиваем номер пункта
      If S > 6 Then S = 1                                             'всегор 6 пунктов
   End If

   Reset Green1 : Waitms 100                                          'антидребезг
   Gifr = 128
Return
'------------------------------------------------------------------------------
Time_count:                                                           'ВРЕМЯ
   If Time_dot = 1 Then Incr Time_sec                                 'тикаем секунды
   Timer1 = 3000                                                      'корректировка точности часов
   Toggle Time_dot                                                    'мигающее двоеточие
Return
'------------------------------------------------------------------------------
Time_sub:                                                             'СЧЕТ ВРЕМЕНИ
   If Time_sec = 60 Then                                              'в минуте 60 сек.
      Incr Time_min
      Time_sec = 0
   End If

   If Time_min >= 60 Then
      Incr Time_hour                                                  'в часе 60 мин.
      Time_min = 0
   End If

   If Time_hour = 24 Then Time_hour = 0                               'в сутках 24 часа
Return
'------------------------------------------------------------------------------
Temp_sub:                                                             'ТЕМПЕРАТУРА
   If Time_dot = 1 Then
      1wreset
      1wwrite &HCC
      1wwrite &H44
   Else
      1wreset
      1wwrite &HCC
      1wwrite &HBE
      Temp = 1wread(2)
      'Temp = Temp * 10
       Temp = Temp \ 16
      'T = Str(temp)                                                   'что-бы вывести дробную часть на LCD
   End If
Return
'------------------------------------------------------------------------------

Получается, что "Temp = Temp * 10" перед "Temp = Temp \ 16" отделяет целую часть от дробной! Как бы еще придумать отделить дробную часть от целой?

0

56

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

Еще вопрос, как на LCD вывести символ:
- Chr(016) ничего не выводит (пустое место)?

Значит этого символа нет в знакогенераторе дисплея. ;)

В Bascom есть оператор Deflcdchar.
В меню "Tools \ LCD Designer".
Рисуете нужный вам символ и получаете строку типа:
Deflcdchar 1 , 31 , 31 , 32 , 32 , 32 , 32 , 32 , 32  - где "1" - номер этого символа.
Таких символов можно создать 8 шт.

В программе, когда это нужно, пишете (например):
Locate 1, 9
Lcd Chr(х)    - где "х" - номер вашего символа из созданных выше

+1

57

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

Получается, что "Temp = Temp * 10" перед "Temp = Temp \ 16" отделяет целую часть от дробной! Как бы еще придумать отделить дробную часть от целой?

Результат разделить на 10.
Только Integer тут уже не прокатит, придется для конечного результата использовать Single

0

58

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

Вот так получается значение температуры с десятыми, но в виде целого числа. Остаётся поставить точку. Подсмотрел у одного поляка.

Так оно у меня и так получается в виде целого числа. И без Поляка обошелся. Вопрос: как поставить точку?

0

59

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

Так оно у меня и так получается в виде целого числа. И без Поляка обошелся. Вопрос: как поставить точку?

Так вам надо в формате "хх.0" или все-таки с "десятыми" на дисплей выводить ?
Если первое, то:
Lcd Temp; ".0"

Если второе, то придется вернуться к дробному делению и форматированию...

0

60

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

В Bascom есть оператор Deflcdchar.

Работает, с*ка!

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

0


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