Еще раз прошу помощи.
Сразу оговорюсь - пока отрабатывается на симуляторе Bascom, железо едет.
Идея и реализация взята с http://avrproject.ru/publ/menu_on_a_microcontroller_avr/1-1-0-33
Пока без отрисовки меню.
Как задумывалось - перемещение по пунктам меню - клавиши UP и DOWN, клавиша SET - короткое нажатие - функция OK, длинное - ESC
Что не получается - при нажатии кнопки наступает прерывание, программа уходит в Buttons, где обрабатывается нажатие кнопок.
Но! - если нажата, к примеру, PINC.2, после выполнения подпрограммы Up идет возврат обратно в Buttons, и, невзирая на состояние пинов PINC.3 и PINC.4 программа прыгает по очереди в Down и But_set, и только потом уходит в основной цикл.
$regfile = "m32def.dat" ' specify the used micro
$crystal = 16000000 ' used crystal frequency
$baud = 19200 ' use baud rate
$hwstack = 50 ' default use 32 for the hardware stack
$swstack = 32 ' default use 10 for the SW stack
$framesize = 64 ' default use 40 for the frame space
$sim
'=================================
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.1 , Rs = Portb.0
Config Lcd = 20 * 4
Config Int2 = Falling
Config Portc.2 = Input : Portc.2 = 1
Config Portc.3 = Input : Portc.3 = 1
Config Portc.4 = Input : Portc.4 = 1
Config Portb.2 = Input : Portc.2 = 1
Config Portd.7 = Output
'====переменные для опроса клавиаsтуры
Dim Temp_butt As Byte
Dim Temp2_butt As Byte
Dim A As Word
'====основной цикл================
On Int2 But_int
Enable Interrupts
Enable Int2
Cursor Off
A = 0
Do
Locate 1 , 1
Lcd "Main Display"
Loop
Buttons:
Set Portd.7
Debounce Pinc.2 , 0 , Up , Sub
Debounce Pinc.3 , 0 , Down , Sub
Debounce Pinc.4 , 0 , But_set , Sub
Return
But_set:
Temp2_butt = 0
If Pinc.4 = 0 Then
For Temp_butt = 0 To 250
Incr Temp2_butt : If Temp2_butt > 214 Then Goto Esc ' На долгое удержание
If Pinc.4 = 1 Then Exit For ' Выходим из цикла подсчета времени удержания кнопки
Waitms 14
Next
End If
Goto Ok
Ok:
A = 10 'обработка нажатия кнопки "OK"
If A = 11 Or A = 12 Or A = 13 Then
A = A * 10
End If
If A = 21 Or A = 22 Or A = 23 Then
A = A * 10
End If
If A = 31 Or A = 32 Or A = 33 Then
A = A * 10
End If
If A = 41 Or A = 42 Or A = 43 Then
A = A * 10
End If
If A = 10 Or A = 20 Or A = 30 Or A = 40 Then
Incr A
End If
Esc: 'обработка нажатия кнопки "ESC"
If A = 11 Or A = 12 Or A = 13 Then
A = 10
End If
If A = 21 Or A = 22 Or A = 23 Then
A = 20
End If
If A = 31 Or A = 32 Or A = 33 Then
A = 30
End If
If A = 41 Or A = 42 Or A = 43 Then
A = 40
End If
If A > 100 Then
A = A / 10
End If
Return
Down: 'обработка нажатия кнопки "DOWN"
If A = 10 Or A = 20 Or A = 30 Then
A = A + 10
End If
If A = 11 Or A = 12 Then
Incr A
End If
If A = 21 Or A = 22 Then
Incr A
End If
If A = 31 Or A = 32 Then
Incr A
End If
If A = 41 Or A = 42 Then
Incr A
End If
Return
Up: 'обработка нажатия кнопки "UP"
If A = 20 Or A = 30 Or A = 40 Then
A = A - 10
End If
If A = 12 Or A = 13 Then
Decr A
End If
If A = 22 Or A = 23 Then
Decr A
End If
If A = 32 Or A = 33 Then
Decr A
End If
If A = 42 Or A = 43 Then
Decr A
End If
Return
But_int:
Gosub Buttons
Return
EndПробовал так:
Buttons: Set Portd.7 If Pinc.2 = 0 Then Gosub Up End If If Pinc.3 = 0 Then Gosub Down End If If Pinc.4 = 0 Then Gosub But_set End If Return .... But_int: Waitms 50 If Pinc.2 = 0 Or Pinc.3 = 0 Or Pinc.4 = 0 Then Gosub Buttons End If Return
Все равно, поведение программы такое же. Даже больше того - если сгенирировать прерывание, но на PINC 2,3,4 оставить высокий уровень, программа все равно уходит Duttons и далее по кругу.
Отредактировано rustr (2013-12-09 03:24:59)

, поэтому не знал, что условия использования этой команды специфичны.


