Ну в чем подвох-то а? Почему у всех все просто, а у меня постоянно грабли на пути? Много лет уже программирую АВРки под свои бытовые нужды и каждый раз бьюсь не над программой, а над разгадыванием очередной загадки. Аж зло берет иногда.
Вот очередная загадка:
Ну что не так-то? Почему эта проблема только у меня? Вот схема:
Схема стандартная, точь в точь из букваря. Управление индикатором стандартное, ровно как в учебнике. Что не так-то? Вот (на всякий случай) кусок кода:
'------------------------------------------------------------------------------
$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)





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

