Если второе, то придется вернуться к дробному делению и форматированию...
Ну, так мы с этого и начали.
Жду 600 секунд......
Программирование ATMEL в BASCOM. |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » Программирование ATMEL в BASCOM. » Дисплеи и индикация » Кракозяблы на LCD 20x4
Если второе, то придется вернуться к дробному делению и форматированию...
Ну, так мы с этого и начали.
Жду 600 секунд......
Ну, так мы с этого и начали.
Ну, тут телепатов нет, а все выкладываемые вами "черновики" отображали в виде "хх.0"... 
Что можно было из этого предположить ? 
Зачем использовать весьма тормозные Format(t , " 0.0")
Меня всегда удивляет разный подход людей к программированию. Многим просто жизненно необходимо впихнуть в тиньку невпихуемое и обязательно сделать так, чтобы скорость обработки была минимальной, хотя процесс, которым управляет МК ну оооооочень медленный. Я согласен с тем, что алгоритм должен быть максимально оптимизирован, но иногда ухищрения программеров настолько всё запутывают, что по прошествии некоторого времени её не поймет ни сам программер, ни другой человек. На мой взгляд нужно грамотно составить, ну даже не ТЗ, а некий свод требований к своему изделию и там конкретно уточнить что нам нужно будет для реализации. Например не тинька, а мега, не 8 кб, а 32. Есть у нас критичные по времени фрагменты или нет, какую частоту при этом нужно выбрать. Писать ли на АСМ или обойдёмся Бейсиком. Вообщем ещё много чего. В институте нас учили, что прежде чем писать программу нужно накидать блок-схему алгоритма. Грешен, часто не делаю этого, но иногда очень помогает, особенно когда что то длинное. Вывод: создание изделия, даже любительского, требует хорошей подготовки. Честно говоря нас немного развратили МК. То, что раньше приходилось собирать по кирпичикам, сейчас умещается в несколько строчек кода. Это здорово, но думать всё равно нужно. Вот такой трактат получился. 
Прошу прощения за оффтоп. 
Отредактировано sva-don (2021-12-21 11:00:23)
Всё зависит от задачи И ситуации.
Например, я стараюсь не применять ассемблер, так как бывает потребность переноса кода в PIC (редко, но бывает).
Когда есть время И желание, могу впихнуть невпихуемое в Tiny. А когда нет того или другого - беру что-то пожирнее (Мегу).
Блок-схемы рисовал в начале пути, году в 1994-1999, вряд ли позже. Хотя бывают случаи, когда не помогают ни деление на модули-подпрогаммы, всё в голове не укладывается из-за большого кода, тогда распечатываю, раскладываю на столе или полу, и смотрю...
Хотя бывают случаи, когда не помогают ни деление на модули-подпрограммы, всё в голове не укладывается из-за большого кода, тогда распечатываю, раскладываю на столе или полу, и смотрю...
Иы одинаково мыслим. Я делаю тоже самое.
Тут Nord как то правильно писал. Надо начинать поэтапно. Есть кнопки, отработай, есть меню, отработай и т.д.. Тогда из этих кирпичиков всё понемногу складывается. Очень важно структурировать программу так, чтобы не путаться в ней потом. Как можно больше комментариев. Конечно Бейсик очень скуп на такие дела, но приходится изворачиваться. Хотя бы сделали так, чтобы в одной строке можно было несколько операций написать, а то совсем фигня получается. Я уже молчу про классы, наследование, инкапсуляцию и другие подобные вещи.
Domen82 извини, намусорил я тут. Всё, всё ухожу. 
На мой взгляд нужно грамотно составить, ну даже не ТЗ, а некий свод требований к своему изделию и там конкретно уточнить что нам нужно будет для реализации. Например не тинька, а мега, не 8 кб, а 32.
Я обычно подхожу с другой стороны, т.к. 98% изначально отрабатываю в Протеусе...
Начинаю с "жирного" - Mega32 или 328, в зависимости от потребности "в ногах".
По мере отработки кода откатываюсь "вниз", были случаи, когда найденные решения позволили даже Tiny25... 
Приветствую всех участников дискуссии. Спасибо за советы.
Прошу прощения за особенность внезапно пропадать на неопределенное время - связано с основной работой.
Проблема с кракозяблами на дисплее надеюсь решена. Сделал так:
1. Основная информация (наполнение) статична.
2. Меняются только значения переменных.
3. На время обработки индикации тормозим прерывания.
Проблема с энкодером решилась еще проще:
1. Заметил, что энкодер косячит только в определенном положении движка. Примерно в диапазоне 9-12 часов. В остальном все нормально. "Проблемный" энкодер был куплен, естественно, у Китайцев. Как и принято - "давным-давно".
2. 30 декабря на почту пришла посылка с очередной партией Китайского гoвна. Впаял "новый" энкодер и... стало заметно лучше, но не идеально - в диапазоне 11-12 часов происходил "перескок" в противоположную сторону.
3. Тут я понял, что иду в правильном направлении. В закромах нашел энкодеры купленные в ЧИП-НН, впаял и все заработало! Не знаю где эти парни закупали радиодетали, но качество у них всегда было на высоте.
На данном этапе (как обычно) реализованы не все задуманные функции, но это дело наживное. Пока так:
1. Дисплей показывает все, что запланировано.
2. Измеряем температуру теплоносителя.
3. Работает термостат. Гистерезис делать не стал - исполнительное устр-во ТЭН итак инерционный.
4. Шагает время. Особая точность не нужна, поэтому не стал заморачиваться с кварцем - минута в минуту за сутки достаточно.
5. Кнопочки шморгают красным светодиодом. В будущем для них будет свое применение.
Исходник пока выглядит так:
'------------------------------------------------------------------------------
$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 'мигающее двоеточие
Dim Timer_on_sec As Byte 'секунды TIMER ON
Dim Timer_on_min As Byte 'минуты TIMER ON
'------------------------------------------------------------------------------
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 'СТАТИЧНАЯ ИНДИКАЦИЯ
Deflcdchar 1 , 16 , 24 , 28 , 30 , 28 , 24 , 16 , 32 'жирный указатель
Upperline : Lcd " TERMOS .0" ; Chr(223) ; " " ; Chr(223) 'первая строка
Lowerline : Lcd " TIMER TIME " 'вторая строка
Thirdline : Lcd " ON 00:00 OFF 00:00" 'третья строка
Fourthline : Lcd " OFF 00:00 ON 00:00" 'четвертая строка
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
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
Case Is <> 0 : Locate 1 , 9 : Lcd " 0" 'при первом чтении ERAM переменная равна непонятно чему
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 Chr(1) : Locate 4 , 12 : Lcd " " 'TERMOS
Case 2 : Locate 3 , 1 : Lcd Chr(1) : Locate 1 , 1 : Lcd " " 'TIMER ON
Case 3 : Locate 4 , 1 : Lcd Chr(1) : Locate 3 , 1 : Lcd " " 'TIMER OFF
Case 4 : Locate 2 , 10 : Lcd Chr(1) : Locate 4 , 1 : Lcd " " 'TIME
Case 5 : Locate 3 , 11 : Lcd Chr(1) : Locate 2 , 10 : Lcd " " 'TIME OFF
Case 6 : Locate 4 , 12 : Lcd Chr(1) : 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 2
If En_2 = 1 Then 'крутим вправо
Incr Timer_on_min 'увеличиваем TIMER
Else 'крутим влево
Decr Timer_on_min 'уменьшаем TIMER
End If
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 = 2900 'корректировка точности часов
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
'------------------------------------------------------------------------------Отредактировано domen82 (2022-01-10 19:18:06)
И еще вопрос, пользуясь случаем. Видел у кого-то в исходнике команду (оператор, х/з как правильно называется), что-бы не стиралась ПЗУ во время обновления прошивки в МК. Тогда значения не придал, а сейчас не могу вспомнить.
Ёханки, да зачем эти 600 секунд? Мы так вечность общаться будем.
Купить премиум доступ, смеетесь? На форуме народу - перекатиполе скучает. Смысл?
Отредактировано sasha_1973 (2022-01-11 05:49:05)
что-бы не стиралась ПЗУ во время обновления прошивки в МК
Программируете фьюз EESAVE.
что-бы не стиралась ПЗУ во время обновления прошивки в МК
Почитайте повнимательнее Установка FUSE-битов
___
попрошу без мата!
Отредактируйте сообщение - уберите мат!!!
domen82
Мне кажется, что очень часто опрашивается градусник 18б20.
Я у себя в "умном доме" сделал привязку к счетчику секундных импульсов. Запрос на измерение градусника по 59 секунде, запрос на результат на 00 секунде.
Измерение температуры 1 раз в минуту вполне достаточно. И гистерезис будет не температурный, а временной.
Вы здесь » Программирование ATMEL в BASCOM. » Дисплеи и индикация » Кракозяблы на LCD 20x4