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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » управление одной кнопкой


управление одной кнопкой

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

1

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

0

2

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

Config Int0 = Falling
On Int0 Button
Enable Int0
Enable Interrupts

Dim M As Byte
Dim Change As Byte
M = 1
Change = 0

Main_program:
   Do
      If Change = 1 Then Change = 0
      If M = 1 Then
         Label1:
         ' тут управляем огоньками в 1 режиме
         If Change = 0 Then Goto Label1
      End If
      If M = 2 Then
         Label2:
         ' тут управляем огоньками во 2 режиме
         If Change = 0 Then Goto Label2
      End If
      If M = 3 Then
         Label3:
         ' тут управляем огоньками в 3 режиме
         If Change = 0 Then Goto Label3
      End If
   Loop Until Change = 1
Change = 0
Goto Main_program
End

Button:
   Change = 1
   Incr M
   If M > 3 Then M = 1
Return

На INT0 ножку контроллера подключить кнопку, замыкающую на землю. На эту же ножку резистор 1к-10к на плюс питания контроллера.
Программы управления огоньками сочиняйте сами. Только ВЫ знаете, как и в каком порядке они должны мигать.

0

3

прерывание на нажатие
инкримент переменной
в основном цикле проверка
значение переменной стало больше Х - сброс

0

4

большое спасибо SIvan, это если одна кнопка и на вход INT0 МК. Задачу описал  чуть не корректно. Устройство на меге 16. будет 8 кнопок, подключенных на порт В, каждая из которых будет работать описанным выше образом. с программами управления устройствами справился, а вот заставить их работать от кнопок таким образом пока не смог. Мне бы примерчек для одной кнопки на порт В, а там,я думаю, сам осилю...заранее спасибо..

0

5

http://uploads.ru/t/J/7/K/J7Kuc.png
Для 8 кнопок можно сделать так:

Код:
'*****************************************************************************
'*                             Клавиатура                                    *
'*****************************************************************************

$regfile = "m8def.dat"                                    'Определение кристалла и частоты
$crystal = 4000000
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 8                                                ' default use 8 for the SW stack
$framesize = 24                                             ' default use 24 for the frame space

'--------------------------------- Переменные ---------------------------------

'Для работы с кнопками
Dim Key As Byte                                             'Байт из клавиатуры

'Флаг срабатывания прерывания
Dim Kbd_int As Byte                                         'Нажата кнопка на клавиатуре


'----------------------------- Конфигурирование -------------------------------
 Disable Interrupts
'Порт клавиатуры включить подтяжку
 Config PortB = Input
 Portb = &HFF

'Конфигурация прерываний
 Config Int0 = Falling                                      'прерывания от кнопок

'Определить подпрограмму прерываний
 On Int0 Keyboard Nosave

'Разрешить прерывание INT0
 Enable Int0

 Enable Interrupts

'----------------------- Главная программа ------------------------------------
Main:

'Процедура сканирования клавиатуры
If Kbd_int <> 0 Then
  Kbd_int = 0
cli

'Обработка кнопки S1
 If Key = &FE Then
'Программа обработки программы 1
 End If

'Обработка кнопки S2
 If Key = &FD Then
'Программа обработки программы 2
 End If

'Обработка кнопки S3
 If Key = &FB Then
'Программа обработки программы 3
 End If

'Обработка кнопки S4
 If Key = &F7 Then
'Программа обработки программы 4
 End If

'Обработка кнопки S5
 If Key = &EF Then
'Программа обработки программы 5
 End If

'Обработка кнопки S6
 If Key = &DF Then
'Программа обработки программы 6
 End If

'Обработка кнопки S7
 If Key = &BF Then
'Программа обработки программы 7
 End If

'Обработка кнопки S8
 If Key = &7F Then
'Программа обработки программы 8
 End If


sei
Goto Main
End If

'------------------------------------------------------------------------------
'Спим
Idle
Goto Main
Stop

'-------------------------- Прерывания ----------------------------------------
'Прерывание от клавиатуры
Keyboard:
  push r24
  Waitms 50
  Key = PinB
  Kbd_int = 1
  pop r24
Return

Если кнопки будут сильно "дребезжать", что проявится в не стабильном управлении, необходимо увеличить задержку в п/п прерывания. Сейчас там стоит 50 мс.
Защиты от нажатия нескольких кнопок нет. В этом случае программа проигнорирует команду.
А для того, чтобы сохранить побольше выводов у МК, я часто пользуюсь расширителем портов PCF8574. Он управляется по TWI и позволяет всего двумя проводами подключить клавиатуру 4х4.

Отредактировано sva-don (2011-10-17 16:54:41)

0

6

Еще классическим решением для нескольких кнопок является использование АЦП.

0

7

Спасибо, ребята, завтра обязательно попробую.

0

8

SIvan, с АЦП пока не разбирался .sva-don, а я так понимаю схема опять управляется по выводу прерывания MK Int0? да? дело в том, что устройство я уже собрал, и кнопки подключены по схеме, представленной на рисунке, все остальные порты задействованы на выход... вhttp://uploads.ru/t/J/V/B/JVBPg.gif

0

9

Можно конечно и так, но в данном случае вопрос определения момента нажатия определяете вы. Проще говоря необходимо периодически считывать порт В и по считанному коду определять номер нажатой клавиши. Обработка точно такая же, как я указал выше. Т.е. If Key=... и т.д. Период опроса можно задать одним из таймеров контроллера. Включив его на счет и определив ему п/п прерывания.

0

10

Подскажи как переодически опрашивать порт В? сейчас изучаю лит-ру по bascom-y, но на это бывает очень мало свободного времени ...

0

11

Очень просто. Берешь таймер, например Timer0. Включаешь его в режим счетчика. Разрешаешь прерывания по переполнению. В программе обработки прерывания читаешь порт и устанавливаешь флаг Kbd_Int. (Так, как в моем примере выше). Остальная программа та же. Т.е. в прорамме, приведенной выше нужно только настроить таймер на счет и прерывания, все остальное остается тем же.

0

12

Доброго времени суток!
На Вашем примере, SIvan попробовал мигание светодиодами сделать. кнопка находится у меня на порте PD.5, еще желательно PD.0 и PD.1 управление скорости бы приделать. Помогите пожалуйста. Где у меня ошибки? Я новичок в программировании

0

13

Gavrilov_S
А что у вас за ошибки?
Если больше одной кнопки, то в сообщении №5 есть пример подключения. При входе в программу прерывания, проверяйте ножки, на которые вы подключили кнопки. Попробую проявить телепатические способности... Скорость мигания у вас задана командами Wait в основоной программе? Так вот ими и манипулируйте.

0

14

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

0

15

Gavrilov_S
напишите тип контроллера и куда какие кнопки подключены. Лучше со схемкой. Ну и программу.

Отредактировано SIvan (2011-12-16 07:32:31)

0

16

и я снова тут. и опять обращаюсь с просьбой. помогите с кодом программы. как необходимо прописать кнопки, что бы при первом нажатии на кнопку включалась управляющая программа, а при повторном нажатии на эту же кнопку управляющая программа выключалась. устройство собранно по схеме представленной в сообщении №8. может кто поможет примерчиком с пояснениями. повторюсь васком осваиваю недавно, еще новичок.. в голове крутится алгоритм, при нажатии на кнопку, устанавливаем  флаг нажатия, переходим на подпрограмму управления нагрузкой (мигание светодиодоми), сбросить флаг нажатия, при повторном нажатии установить флаг выключения, выключить программу управления...может чего и напутал, но думаю как то так...реализовать пока не смог...устройство собранно, каждая кнопка включает свой эффект, свою п.программу... и последняя включает автоматическое перебирание данных эффектов...

Отредактировано Евгений86 (2011-12-27 09:44:16)

0

17

Вот код, один раз нажали вкл - другой раз выкл:

Код:
 Config Debounce = 10                                        'время задержки в мс
Config Pind.7 = Input                                       'настройка пина d7 на вход
Config Pinb.1 = Output                                      'настройка пина b1 на выход
Set Portd.7                                                 'включить внутренний подтягивающий резистор
Reset Portb.1                                               'сбросить порт
Vv Alias Pind.7                                             'присваиваем порту имя Vv

1:                                                          'метка

Do                                                          'основной цикл программы

Debounce Vv , 0 , Led_on                                    'если нажали кнопку, то идти на Led_on


Loop                                                        'конец основного цикла


Led_on:
Do                                                          'подпрограмма включения
Set Portb.1
Goto 2
Loop

2:                                                          'ждем второго нажатия
Do
Debounce Vv , 0 , Led_off
Loop

Led_off:                                                    'подпрограмма выключения
Do
Reset Portb.1
Goto 1
Loop

End                                                         'конец программы

0

18

Встречалась запись более короткая:

Код:
Config Portb.1 = Output :  Set Portd.7   '  конфигурируем порт В1 на выход, D7 на вход и включаем внутренний подтягивающий резистор на порт D7
  Do
    Debounce Pind.7 , 0 , En , Sub
  Loop
En:
Toggle Portb.1  
Return

или

Config Portb.1 = Output : Config Pind.7 = Input : Set Portd.7  '  конфигурируем порт В1 на выход и включаем внутренний подтягивающий резистор на порт D7
  Do
       Bitwait Pind.7 , reset  ' ждем пока на пине не появится 0 (ждем нажатия)
       Toggle Portb.1           ' инвертируем состояние порта
       Bitwait Pind.7 , set     ' ждем пока на пине не появится 1 (ждем отпускания)
  Loop

0

19

да, я видел эти примеры здесь на форуме,ток не работают они,(пример из сообщения №17) если в п.программе организован цикл (бегущий огонь, к примеру), повторное нажатие клавиши уже программу управления светодиодами не выключает, подозреваю, что из цикла программа уже не выходит... в сообщении №18 не пойму как указать ссылку, что при первом нажатии включается программа управления светодиодами, при повторном-выключается...

0

20

Я думаю если Вы предоставите код, или тот кусок который не работает то и ответ будет точнее.

0

21

Пример для 3 режимов. Исходник Bascom, проект Proteus 7.7 SP2.
http://narod.ru/disk/35990907001/leds.rar.html

0

22

Точнее, управление тремя кнопками, т.к. ТЗ в процессе обсуждения изменилось :) Кнопки "Режим", "Медленнее", "Быстрее".
На данный момент 7 скачиваний файла. Отпишитесь по результатам.

Отредактировано SIvan (2011-12-30 14:42:13)

0

23

SIvan Добрый день!
Код проверю только сегодня вечером.
Я собрал макетки на 2 контроллра Tiny2313 и Mega48.
По простым программа можно и на tiny2313.
Я щас научился управлять только светодиодами бегущие огни только не могу управлять кнопками.

0

24

кнопка у меня посему то срабатывает только на PD2

$regfile = "attiny2313.dat"
$crystal = 1000000
Config Int0 = Falling
On Int0 Button
Enable Int0
Config Portb = Output
Portb = 255
Config Portd = Input
Portd = 255
Enable Interrupts

Dim M As Byte                           ' Режим
Dim Change As Byte
Dim Led_out As Byte
Dim Dl As Long                          ' Задержка
Dl = 300
M = 1
Change = 0
Led_out = 254

Main_program:
   Do
      If Change = 1 Then Change = 0
      If M = 1 Then
         Label1:
         ' тут управляем огоньками в 1 режиме
         Rotate Led_out , Left
         Portb = Led_out
         ' Задержка
         Waitms Dl
         If Change = 0 Then Goto Label1
      End If
      If M = 2 Then
         Label2:
         ' тут управляем огоньками во 2 режиме
         Rotate Led_out , Right
         Portb = Led_out
         ' Задержка
         Waitms Dl
         If Change = 0 Then Goto Label2
      End If
      If M = 3 Then
         Label3:
         ' тут управляем огоньками в 3 режиме
         Portb = 255
         ' Задержка
         Waitms Dl
         Portb = 0
         ' Задержка
         Waitms Dl
         If Change = 0 Then Goto Label3
      End If
   Loop Until Change = 1
Change = 0
Goto Main_program
End

Button:
   If Pind.2 = 0 Then
      Change = 1
      Incr M
      If M > 3 Then M = 1
   End If
   If Pind.3 = 0 Then
      Dl = Dl + 50
      If Dl > 2000 Then Dl = 2000
   End If
   If Pind.4 = 0 Then
      Dl = Dl - 50
      If Dl < 100 Then Dl = 100
   End If
Return

Отредактировано Gavrilov_S (2012-01-09 20:46:31)

0

25

Mrshilov ясно. Подскажите пожалуйста как это можно организовать? Что нужно переделать в схеме и в программе?

0

26

Я так понял нужно собирать схему как на посте 5 и не использовать в программе PD2?

0

27

Mrshilov поставил диоды от кнопок к PD2. Все 3 кнопки заработали. Только иногда появляется дребезг копки. Как от него можно избавиться?
Я программу немоножко переделал. Добавил эфекты

$regfile = "attiny2313.dat"
$crystal = 1000000

Config Int0 = Falling
On Int0 Button
Enable Int0

Config Portb = Output
Portb = 0

Config Portd = Input
'Portd = 255
Set Portd.2
Set Portd.3
Set Portd.4

Enable Interrupts

Dim M As Byte                                               ' Режим
Dim Change As Byte
'Dim Led_out As Byte
Dim Dl As Long
Dim I As Integer : Dim Z As Integer
Dim Efect1(8) As Byte : Dim Efect2(6) As Byte

Effect1:
Data 128 , 64 , 32 , 16 , 8 , 4 , 2 , 1

Effect2:
Data 129 , 66 , 36 , 24 , 36 , 66

Restore Effect1
For I = 1 To 8
Read Efect1(i)
Next I

Restore Effect2
For I = 1 To 6
Read Efect2(i)
Next I

Dl = 250
M = 1
Change = 0
'Led_out = 254

Main_program:
   Do
      If Change = 1 Then Change = 0
      If M = 1 Then
         Label1:
         ' тут управляем огоньками в 1 режиме
         For I = 1 To 8
         Portb = Efect1(i)
         Waitms Dl
         Next I

         If Change = 0 Then Goto Label1
      End If

      If M = 2 Then
         Label2:
         ' тут управляем огоньками во 2 режиме
         For I = 8 To 1 Step -1
         Portb = Efect1(i)
         Waitms Dl
         Next I

         If Change = 0 Then Goto Label2
      End If

      If M = 3 Then
         Label3:
         ' тут управляем огоньками в 3 режиме
         Portb = 255
         ' Задержка
         Waitms Dl
         Portb = 0
         ' Задержка
         Waitms Dl
         If Change = 0 Then Goto Label3
      End If

       If M = 4 Then
         Label4:
         ' тут управляем огоньками в 4 режиме
          For I = 1 To 6
          Portb = Efect2(i)
          Waitms Dl
          Next I
          If Change = 0 Then Goto Label4
      End If

       If M = 5 Then
         Label5:
         ' тут управляем огоньками в 3 режиме
         Portb = 240
         ' Задержка
         Waitms Dl
         Portb = 15
         ' Задержка
         Waitms Dl
         If Change = 0 Then Goto Label5
      End If

   Loop Until Change = 1
Change = 0
Goto Main_program
'End

Button:
   If Pind.5 = 0 Then
      Change = 1
      Incr M
      If M > 5 Then M = 1
   End If

   If Pind.4 = 0 Then
      Dl = Dl + 10
      If Dl > 3000 Then Dl = 3000
   End If

   If Pind.3 = 0 Then
      Dl = Dl - 10
      If Dl < 10 Then Dl = 10
   End If
Return

0

28

Mrshilov[/b] Спасибо за быстрый ответ. Понял в какой части нужно  настраивать. Попробую потом отпишусь о результатах.

Отредактировано Gavrilov_S (2012-01-11 17:16:00)

0

29

Дребезг как был так и остался :( На кнопки только начал реагировать чуть дольше. т.е. после нажития на кнопку небольшая пауза потом только программа начинает работать

Отредактировано Gavrilov_S (2012-01-12 15:48:28)

0

30

Попробуй перенести WAITMS вверх, сразу после метки BUTTON: и увеличить задержку до 60-100 мс.

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

На кнопки только начал реагировать чуть дольше.

50 мс прям заметно? Сомневаюсь.
Убрать дребезг на 100% таким методом вряд ли получится, для этого используют формирователи, но снизить эффект можно. Тут нужно выбрать оптимал. Или усложнять схему, или смириться с эффектом.

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » управление одной кнопкой