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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Периферия » Кнопки, не хочет работать...


Кнопки, не хочет работать...

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

1

Еще раз прошу помощи.
Сразу оговорюсь - пока отрабатывается на симуляторе 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)

0

2

rustr возьми опрос кнопок Buttons: из последнего варианта и затолкай в процедуру обработчика прерывания But_int:
Возможно еще перед Return в прерывании придется бросить флаг этого прерывания из за дребезга.

0

3

Кстати, пробовал так тоже.
Что меня вконец озадачило - в симуляторе, после ухода из подпрограммы прерывания в по команде Gosub, программа возвращается обратно в пп прерывания, доходит до Return, и только потом уходит в основной код.

Отредактировано rustr (2013-12-09 10:09:58)

0

4

СОбственно этим и отличается команда Gosub от Goto

0

5

и вообще (на сколько мне память не изменяет) прерывание надо сбрасывать перед выходом из процедуры

0

6

Флаг прерывания сбрасывается при переходе на обработчик прерывания.
Но во время работы обработчика тот же самый дребезг может снова поднять флаг.
Поэтому не лишним бывает дополнительно сбрасывать флаг при выходе из обработчика.

Еще момент. Сброс флага прерывания осуществляется записью ЕДИНИЦЫ в соответствующий бит регистра GIFR

0

7

Я думал, что пп прерывания несколько отличается по работе от просто подпрограммы, вызываемой из кода. А так выходит, что прерывание остановило выполнение основной программы, ушло в соседнюю пп, потом вернулось, еще что-то проделало. И все это время основной код стоит?
Прерывание я сбрасываю, GIFR=64, так?
Где эту команду комильфо писать? К примеру, так?

Код:
But_int:
GIRF = 64 (?)
Denounce PINC.3 , 0 , Up 
Denounce PINC.4 , 0 , Down 
Denounce PINC.5 , 0 , Button
GIFR= 64 (?)
Return

Отредактировано rustr (2013-12-09 16:27:54)

0

8

Все правильно думаешь. Просто прерывание - это аппаратная часть МК, а обработчик - уже программная. Обнулять флаг перед выходом из обработчика, т.е. перед Return

0

9

Вот окно "железного" симулятора Bascom
http://s6.uploads.ru/t/cs06M.jpg
В красной рамке - уровни на пинах?
А в зеленой что?

0

10

То, что с буквой P - порты,  другом окне пиины. Это отдельные регистры МК

0

11

Блин, вот как надо было порты конфигурировать:

Код:
Config Pinc.2 = Input : Pinc.2 = 1
Config Pinc.3 = Input : Pinc.3 = 1
Config Pinc.4 = Input : Pinc.4 = 1
Config Pinb.2 = Input : Pinc.2 = 1

Так заработало в симуляторе.
А в Proteus не хочет работать.
Так, похоже, то Протеус не умеет работать с внешними прерываниями.
Вот такой вариант работает

Код:
Do
Locate 1 , 1
Lcd "Main Display"
Select Case A
Case 10 : Gosub 10
Case 20 : Gosub 20
Case 30 : Gosub 30
Case 40 : Gosub 40
End Select
Gosub But

Loop

But:
If Key_up = 0 Or Key_set = 0 Or Key_down = 0 Then
Waitms 25
If Key_up = 0 Or Key_set = 0 Or Key_down = 0 Then
Goto Buttons
End If
End If
Return

Отредактировано rustr (2013-12-10 23:53:01)

0

12

А весь код можно? Много ненужных операций в коде

0

13

Полностью программы еще нет, я пока только отдельные блоки готовлю.
Сейчас вот с меню воюю:

Код:
$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
Key_up Alias Pinc.2
Key_set Alias Pinc.3
Key_down Alias Pinc.4
Config Pinc.2 = Input : Pinc.2 = 1
Config Pinc.3 = Input : Pinc.3 = 1
Config Pinc.4 = Input : Pinc.4 = 1
Config Pinb.2 = Input : Pinc.2 = 1
Config Portd.7 = Output
'====переменные для опроса клавиаsтуры
Dim Temp_butt As Byte
Dim Temp2_butt As Byte
Dim A As Word
Dim Key_up As Bit
Dim Key_down As Bit
Dim Key_set As Bit
'====основной цикл================
On Int2 But_int
Enable Interrupts
Enable Int2
Cursor Off
A = 0

Do
Locate 1 , 1
Lcd "Main Display"
Select Case A
Case 10 : Gosub 10
Case 20 : Gosub 20
Case 30 : Gosub 30
Case 40 : Gosub 40
End Select


Loop

'====Опрос кнопок=================
Buttons:
Set Portd.7
If Key_up = 0 Then
Goto Up
End If
If Key_down = 0 Then
Goto Down
End If
If Key_set = 0 Then
Goto But_set
End If
Return

'====определение короткого или длинного нажатия кнопки SET
But_set:
Temp2_butt = 0
 If Key_set = 0 Then
  For Temp_butt = 0 To 250
   Incr Temp2_butt : If Temp2_butt > 214 Then Goto Esc      ' На долгое удержание
    If Key_set = 1 Then Exit For                            ' Выходим из цикла подсчета времени удержания кнопки
     Waitms 14
      Next
       End If
        Goto Ok
Return

'====обработка нажатия кнопки "OK"
Ok:
A = 10
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
Return

'====обработка нажатия кнопки "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

'====
10:                                                         'подпрограмма отрисовки на дисплее выделения первого пункта
Lcd "Set Time & Data        <"                              'в первой строке нарисовали курсор
Lowerline                                                   'пишем на второй строке
Lcd "Set Tank"
Thirdline                                                   'пишем на третьей строке
Lcd "Set measurements"
Fourthline                                                  'пишем на четвертой строке
Lcd "Set Timers"
Return                                                      'возвращаемся в основной цикл программы

'====
20:                                                         'подпрограмма отрисовки на дисплее выделения первого пункта
Lcd "label 1"                                               'в первой строке нарисовали курсор
Lowerline                                                   'пишем на второй строке
Lcd "label 2        <"
Thirdline                                                   'пишем на третьей строке
Lcd "label 3"
Fourthline                                                  'пишем на четвертой строке
Lcd "label 4"
Return                                                      'возвращаемся в основной цикл программы

'====
30:                                                         'подпрограмма отрисовки на дисплее выделения первого пункта
Lcd "label 1"                                               'в первой строке нарисовали курсор
Lowerline                                                   'пишем на второй строке
Lcd "label 2"
Thirdline                                                   'пишем на третьей строке
Lcd "label 3        <"
Fourthline                                                  'пишем на четвертой строке
Lcd "label 4"
Return                                                      'возвращаемся в основной цикл программы

'====
40:                                                         'подпрограмма отрисовки на дисплее выделения первого пункта
Lcd "label 1"                                               'в первой строке нарисовали курсор
Lowerline                                                   'пишем на второй строке
Lcd "label 2"
Thirdline                                                   'пишем на третьей строке
Lcd "label 3"
Fourthline                                                  'пишем на четвертой строке
Lcd "label 4        <"
Return                                                      'возвращаемся в основной цикл программы

'====обработчик прерывания=====
But_int:
Waitms 50
If Key_up = 0 Or Key_set = 0 Or Key_down = 0 Then
Goto Buttons
End If
Gifr = 64
Return

End

0

14

Сброс флага Int2:  Gifr = 32
Программа не работает потому что стек с ума сходит. Вместо Goto нужна команда Gosub. Иначе, уходя в подпрограмму командой Goto, в конце подпрограммы после Return у МК съедут мозги, возврата на место вызова предыдущей подпрограммы не будет.
В протеусе вместа .hex в МК пропишите .obj  запускаем эмуляцию кн. пауза. затем во вкладке отладка находим МК -> AVR Source Code и пошагово смотрим.

0

15

Честно, я не очень опытный программист, скорее даже очень неопытный :-), поэтому не знал, что условия использования этой команды специфичны.
Используя Goto я хотел сократить переходы, ускорить программу.
Протеусу я скармливаю именно файл .obj, но, тем не менее, глюки не проходят. Я уже 3 разных версии Bascom b 2 версии Proteus перебрал - все одно по прерыванию не отрабатывает.
Причем, пару дней назад работал!
Причем глюки вообще не понятные. Вот сократил код, оставил только обработчик прерывания

Код:
$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

'=================================
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
Key_up Alias Pinc.2
Key_set Alias Pinc.3
Key_down Alias Pinc.4
Config Pinc.2 = Input : Pinc.2 = 1
Config Pinc.3 = Input : Pinc.3 = 1
Config Pinc.4 = Input : Pinc.4 = 1
Config Pinb.2 = Input : Pinc.2 = 1
Config Portd.7 = Output
'====переменные для опроса клавиаsтуры
Dim Key_up As Bit
Dim Key_down As Bit
Dim Key_set As Bit
'====основной цикл================
On Int2 But_int
Enable Interrupts
Enable Int2
Cursor Off

Do
Locate 1 , 1
Lcd "Main Display"
Loop

'====обработчик прерывания=====
But_int:
Waitms 50
If Key_up = 0 Or Key_set = 0 Or Key_down = 0 Then
Set Portd.7
End If
Gifr = 32
Return

End

И вот, что в Протеусе:
http://s7.uploads.ru/t/ns3F2.jpg
Откуда эти переменные?

0

16

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

В протеусе вместа .hex в МК пропишите .obj

+1. Очень удобно и полезно. В свое время только этим отловил порчу переменной в памяти.

Автору: можно поинтересоваться, чем таким незначительным будет заниматься устройство, что кнопки меню повешены на прерывания да еще и каждая на свой пин? Я делал обработку для 12-ти кнопок, 8 из которых на короткое и длительное нажатие (и с быстрым повторением, типа установки часов). Использовался лишь таймер и один пин АЦП. А устройство занималось постоянным опросом пяти аналоговых датчиков, в зависимости от значения управляло автоматикой и отображало это все на LCD 20*4. Правда, работа с кнопками находилась в обработчике переполнения таймера, так как не занимала много времени. Конечно, не во всех задачах удается получить такое сочетание.

Если данная тема о получении бесценного опыта, то замечательно.

0

17

А как получить опыт, не наступая на грабли?
Пытаюсь сделать контроллер для насосной станции.
Контроллер будет разделен на 2 части - "горячая" -контроль тока и напряжения в 3 фазах + контроль обрыва фаз, плавный пуск на симисторах (соответственно, детектирование 0).
"Холодная" -работа по таймерам, контроль уровня воды (хочу попробовать сенсор HC-SR04), индикация.

Это не коммерческая работа, а так, для дачи (общественная водокачка), и больше для интереса.

Отредактировано rustr (2013-12-11 20:00:49)

0

18

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

Контроллер будет разделен на 2 части - "горячая" -контроль тока и напряжения в 3 фазах + контроль обрыва фаз

Если это самая ответственная часть, так и делайте упор на АЦП, а кнопки - это очень медленное железо, зачем их засовывать в прерывание, другое дело если экстренный Stop двигателей, тогда да, а так, зачем?

Если хотите скиньте все (симуляция+исходники) на мыло.

0

19

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

А как получить опыт, не наступая на грабли?

Согласен на 1000%!!!

0

20

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

сли это самая ответственная часть, так и делайте упор на АЦП, а кнопки - это очень медленное железо, зачем их засовывать в прерывание, другое дело если экстренный Stop двигателей, тогда да, а так, зачем?

Да я просто уже зациклился - почему симуляция работать не хочет-то?!!
Файлы:
http://rusfolder.com/images/download_2.jpg

0

21

Дайте своё мыло в личку

0

22

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

0

23

По ссылке не все файлы???????????

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

Да я просто уже зациклился - почему симуляция работать не хочет-то?!!
Файлы:

0

24

Глюк в том, что при нажатии на кнопку, по прерыванию, должен просто загореться светодиод на PORTD.7.
И ни фига.
Я уже начинаю подозревать, что либо память, либо проц глючат.

http://s6.uploads.ru/t/USNrz.jpg

Отредактировано rustr (2013-12-11 20:47:22)

0

25

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

По ссылке не все файлы???????????

Так почти ничего еще не готово. Только начал.

0

26

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

Так почти ничего еще не готово. Только начал

Смотрите почту, нет файлика для датчика?

0

27

убери резисторы с кнопок и будет тебе щастье

0

28

А как же без подтяжки? Или только в протеусе их не учитывать?
Убрал, реагирует только на PINC.2

Код:
But_int:
Waitms 50
If Key_up = 0 Or Key_set = 0 Or Key_down = 0 Then
Gosub Buttons
End If
Gifr = 32
Return

0

29

Резисторы R9, R10, R13 убрать. То есть кнопки подключить напрямую к сигналам SET, UP, DOWN. Ну и INT2 не мешало бы подтянуть к питанию. Так вроде срабатывает на кнопки. Только в подпрограмме "button" явно чего-то не хватает :) Я смотрел 108.bas
Я удалил этот соник, а то без HEX для него, симуляция не запускается.

http://rusfolder.com/images/download_1.jpg

Отредактировано SIvan (2013-12-11 22:03:55)

0

30

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

0


Вы здесь » Программирование ATMEL в BASCOM. » Периферия » Кнопки, не хочет работать...