Jump to content
tifaso

Программирование кнопок в ATMEGA8 на С

Recommended Posts

Как сделать кнопку с фиксацией программно. То есть есть простая кнопка без фиксации. Но как сделать её с фиксацией программно иногда очень нужно, но пока ещё не разобрался. Пока ещё только начинаю осваивать программирование микросхем поэтому пожалуйста попроще объясните всё это дело. Уроков может кто подкинет буду благодарен.


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

Спасибо за ссылочки на уроки посмотрел. Но про такую кнопку там нету.


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

Металл-композит как альтернатива ферриту: дроссели Panasonic семейства ETQP

Современные электронные устройства требуют все более компактных и эффективных компонентов. Новые металл-композитные дроссели обладают рядом преимуществ перед дросселями с ферритовым сердечником. Они не имеют ярко выраженного насыщения, обладают отличными частотными свойствами и способны работать при температурах до 150°C и выше. Все это делает их альтернативой стандартным дросселям с ферритовым сердечником в широком спектре автомобильных и промышленных приложений.

Подробнее

Обрабатывать событие "Нажатие кнопки" умеете?

P.S. зачем делать программно кнопку с фиксацией? и что вы под этим подразумеваете?

Share this post


Link to post
Share on other sites
3 часа назад, tifaso сказал:

Как сделать кнопку с фиксацией программно

А как вы делаете без фиксации? Проверяете бит? Ну вот проверяйте и переключайте в другой переменной бит если этот выставлен.

Допустим вы проверяете так 

if (BTN_PIN & BTN) {
  // нажата
}

 просто переделайте так

uint8_t btns;
#define BTN1 0x01

...

if (BTN_PIN & BTN) {
  if (btns & BTN1) {
	btns |= BTN1;
  } else {
	btns &= ~BTN1;
  }
}

если прерывание используете то то же самое.

Ну и естественно антидребезг не забываем программный или хардварный.

А то что нужно делать по нажатию кнопку будет уже 

if (btns & BTN1) {
  // кнопка с фиксацией ВКЛ
} else {
  // ВЫКЛ
}

 

Share this post


Link to post
Share on other sites
                     

Новые литиевые ХИТы Fanso работают даже при +150ºС!

Когда приходится учитывать работу в экстремальных условиях, к выбору электронных компонентов подходишь с особой тщательностью. Высокие температуры, большие перепады давления, труднодоступность – все это требует специальной продукции. Склад КОМПЭЛ пополнился новыми литиевыми ХИТами Fanso, стабильно работающими даже при температуре до 150 ºС. Батарейки имеют номинальное напряжение 3,6 В, обладают ёмкостью от 700 до 14000 мАч, работоспособны в широком температурном диапазоне -20…150ºС и имеют низкий саморазряд (не более 3% в год в нормальных условиях хранения).

Подробнее о высокотемпературной линейке

@DrobyshevAlex Вот так у меня выполнена кнопка без фиксации

         if (PINB == 0b11111110)
         {
			 PORTD = 0b11111111;
			 _delay_ms(500);
			 PORTD = 0b00000000;
			 _delay_ms(500);
         } 
         else
         {
			 PORTD = 0b00000000;
         }

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


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

В вашем случае видимо так

if (PINB == 0b11111110)
{
  if (PORTD) {
    PORTD = 0b00000000;
  } else {
  	PORTD = 0b11111111;
  }
} 

только если нет антидребезга я б добавил задержку

if (PINB == 0b11111110)
{
  _delay_ms(1);
  if (PINB == 0b11111110) {
    if (PORTD) {
      PORTD = 0b00000000;
    } else {
      PORTD = 0b11111111;
    }
  }
} 

 

Share this post


Link to post
Share on other sites
5 minutes ago, DrobyshevAlex said:

видимо так

@DrobyshevAlex Кнопка с "фиксацией" означает, что один раз нажали и отпустили - включилось, второй раз нажали и отпустили - выключилось.

Share this post


Link to post
Share on other sites

@Yurkin2015 Именно так оно и есть. Да вот именно это мне и нужно.


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites
14 минут назад, Yurkin2015 сказал:

Кнопка с "фиксацией" означает, что один раз нажали и отпустили - включилось, второй раз нажали и отпустили - выключилось.

а я что то не так сделал? я догадался как бы... 

if (PINB == 0b11111110) // кнопка нажата?
{
  _delay_ms(1);// чуть подождем для антидребезга
  if (PINB == 0b11111110) {// кнопка все еще нажата?
    if (PORTD) { // если на порте есть единица хоть одна значит это выключение 
      PORTD = 0b00000000;// выключаем
    } else {// если все нули
      PORTD = 0b11111111; // включаем
    }
  }
} 

единственное что я авр не юзаю, возможно там нужно проверить не if (PORTD) а if (PIND)

и вот это

if (PINB == 0b11111110)

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

if (!(PINB & 0b1))

 

Edited by DrobyshevAlex

Share this post


Link to post
Share on other sites
3 minutes ago, DrobyshevAlex said:

что то не так сделал?

Опрос кнопки в бесконечном цикле происходит? Если кнопку при нажатии удерживать дольше 1мс, то будет чередование вкл-выкл-вкл-выкл с частотой цикла опроса кнопки.

Share this post


Link to post
Share on other sites
5 минут назад, Yurkin2015 сказал:

Опрос кнопки в бесконечном цикле происходит? Если кнопку при нажатии удерживать дольше 1мс, то будет чередование вкл-выкл-вкл-выкл с частотой цикла опроса кнопки.

согласен

тогда все таки бит как я предлагал изначально 

или же, если не нужно процессорное время, можно так

if (!(PINB & 0b1)) // кнопка нажата?
{
  _delay_ms(1);// чуть подождем для антидребезга
  if (!(PINB & 0b1)) {// кнопка все еще нажата?
	while(!(PINB & 0b1)); // ждем отпускания кнпоки
    if (PORTD) { // если на порте есть единица хоть одна значит это выключение 
      PORTD = 0b00000000;// выключаем
    } else {// если все нули
      PORTD = 0b11111111; // включаем
    }
  }
}

Share this post


Link to post
Share on other sites
7 minutes ago, DrobyshevAlex said:

как я предлагал изначально 

Ну, там я тоже подрихтовал бы.

Вот, в условии проверяем

if (btns & BTN1) {
    btns |= BTN1;

если бит BTN1 установлен в btns, то зачем его опять устанавливать? Видимо надо поменять местами с btns &= ~BTN1;

И, потом, опять же при удержании кнопки, этот бит будет снова скакать в переменной btns с частотой цикла опроса?

Share this post


Link to post
Share on other sites

@DrobyshevAlex

if (PINB == 0b11111101)
{
	_delay_ms(1);
	if (PINB == 0b11111101) {
		if (PORTD) {
			PORTD = 0b00000000;
			} else {
			PORTD = 0b11111111;
		}
	}
}	 

Опробовал этот код. Он работает, только ситуация то у меня как раз таки какая кнопка без фиксации, но программно нужно сделать с фиксацией при первом нажатии допустим светодиоды на порте D включаются кнопку отпускаем, но включенное положение должно оставаться до повторного нажатия. При повторном нажатии отключаем. Вот то что мне и нужно, а это что сейчас есть получается опять же простая кнопка без фиксации.

Edited by tifaso

Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

то что я писал изначально там была просто суть)) я думаю люди пишущие под мк должны хотя бы значит что такое бит) как его поставить и как снять)

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

4 минуты назад, tifaso сказал:

Опробовал этот код

ну там же ниже код есть другой, его опробуйте)

Share this post


Link to post
Share on other sites

@DrobyshevAlex Какой другой код. Тот что ниже я пробовал, но он вообще не работает и ошибок не бьет. Так что не понятно где там что искать и какой код вообще должен быть.

Edited by tifaso

Нарушение правил форума II.24

Share this post


Link to post
Share on other sites
25 минут назад, tifaso сказал:

Какой другой код.

Ну вот этот

if (!(PINB & 0b1)) // кнопка нажата?
{
  _delay_ms(1);// чуть подождем для антидребезга
  if (!(PINB & 0b1)) {// кнопка все еще нажата?
    while(!(PINB & 0b1)); // ждем отпускания кнпоки
    if (PORTD) { // если на порте есть единица хоть одна значит это выключение 
      PORTD = 0b00000000;// выключаем
    } else {// если все нули
      PORTD = 0b11111111; // включаем
    }
  }
}

если не работает то попробуйте if (PORTD) заменить на if (PIND)

1 час назад, tifaso сказал:

PINB == 0b11111101

а почему у вас изменилась кнопка? вы переставили?

тогда так

if (!(PINB & 0b10)) // кнопка нажата?
{
  _delay_ms(1);// чуть подождем для антидребезга
  if (!(PINB & 0b10)) {// кнопка все еще нажата?
    while(!(PINB & 0b10)); // ждем отпускания кнпоки
    if (PORTD) { // если на порте есть единица хоть одна значит это выключение 
      PORTD = 0b00000000;// выключаем
    } else {// если все нули
      PORTD = 0b11111111; // включаем
    }
  }
}

 

Share this post


Link to post
Share on other sites
1 час назад, tifaso сказал:

но включенное положение должно оставаться до повторного нажатия

Да в чем проблема?

1. Опрашиваете порт на котором висит кнопка

2. Если кнопка нажата... delay для борьбы с дребезгом контактов... Кнопка все еще нажата, тогда выполняем пункт 3

3. Если порт( либо порты) на котором весит светодиод имеет высокий(низкий уровень)  - инвертируем его.

Вот пример кода... должен работать:

DDRB = 0b00000001;  // 1-й пин порта В на выход - на этом порте висит светодиод
   PORTB = 0b0000000; // устанавливаем низкий уровень
   DDRD = 0b00000000; // 1-й пин порта D на вход - на этом порте висит кнопка
   PORTD = 0b00000001; // устанавливаем высокий уровень
    
   while (1){
   if (PIND == 0x00){ // если 1-й пин порта D в низком уровне
      _delay_ms(100); // защита от дребезга
      if (PIND == 0x00){ // если 1-й пин порта D ВСЕ еще в низком уровне
	 PORTB = ~PORTB; // инвертируем состояние порта В
	 }
   }
   }

 

Edited by MadLor

Share this post


Link to post
Share on other sites

ну или можете, если вам так понятней, написать как  у вас было)

if (PINB == 0b11111101) // кнопка нажата?
{
  _delay_ms(1);// чуть подождем для антидребезга
  if (PINB == 0b11111101) {// кнопка все еще нажата?
    while(PINB == 0b11111101); // ждем отпускания кнпоки
    if (PORTD) { // если на порте есть единица хоть одна значит это выключение 
      PORTD = 0b00000000;// выключаем
    } else {// если все нули
      PORTD = 0b11111111; // включаем
    }
  }
}

Этой строкой

if (PINB == 0b11111101)

вы проверяете на PB2 чтобы был 0. Но вы проверяете еще что бы на остальных PB была 1. Я думаю это не верное и переписал вам на PINB & 0b10 - будет истина если там единица, вам нужен ноль, знаичт добавим !

получилось if (!(PINB & 0b10)) если кнопку меняете бит тоже меняйте

3 минуты назад, MadLor сказал:

if (PIND == 0x00)

не будет это работать 

судя по коду TC у него все ноги подтянуты к 1

Ну и кнопка не на D а на B

Share this post


Link to post
Share on other sites

@DrobyshevAlex, я ему уже пошагово все расписал. Если он не способен поменять порты / кнопки / светодиоды местами... то тогда как говорится - "Медицина бессильна". И видимо тогда надо все таки просмотреть видео уроки... Тем более ссылку я давал. 

Share this post


Link to post
Share on other sites

@MadLor Эти видеоуроки я пересмотрел уже раза три там подобного я не нашёл. Потому собственно я и здесь решаю этот вопрос. Брал твой код пробовал, но результат совсем не тот что мне нужен. При нажатии заметно слабое еле заметное свечение светодиода, а при отпускании всё гаснет. Всё проверяю и тестирую на реальной ATMEGA8. Собран специальный тестовый стенд для отладки.


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

Фьюзы? Частота контроллера?... Я эту программку за 3-и минуты накидал в протеусе и она там работала. Т.е. я нажимаю на кнопку  и диод загорается... нажимаю повторно - гаснет. + в этом коде нет защиты от того что кнопка постоянно зажата. Попробуй программы симулировать в Proteus - если первый раз шьеш МК, то возможны различные сюрпризы.

P.S. Надеюсь ты диод к порту МК подключал через резистор? ;)

Share this post


Link to post
Share on other sites
57 минут назад, MadLor сказал:

я ему уже пошагово все расписал.

то есть выше пошагово не расписано было? но что то не помогло, даже с расписыванием антидребезга и защитой от удержания)

24 минуты назад, tifaso сказал:

Брал твой код пробовал

мой вам совет, не просто брать код, а думать что происходит, и писать под себя :) ибо когда нужно будет перенести кнопку или led вы пойдете опять на форум...

тут 5 строк кода, и нет ничего сложно. даже убрал вам работу с битами лишнюю максимально под ваш код переделав.

Share this post


Link to post
Share on other sites
2 минуты назад, DrobyshevAlex сказал:

не расписано было

@DrobyshevAlex, извиняюсь, но сильно в код не вчитывался. 

3 минуты назад, DrobyshevAlex сказал:

то то не помогло

время покажет :)

Share this post


Link to post
Share on other sites

@MadLor Фьюзы не трогал всё по умолчанию. Частота указана ниже

#define F_CPU 1000000UL

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


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • К 23 февраля объявляется скидка на неделю... В честь праздника ценник на комплект -6000 рублей. По окончании ровно недели- ценник верну
    • У многих китайцев, которые работают в экономических зонах РФ (ТОР), уже имеется наше гражданство и их невозможно ограничить в пропуске границы. И таких уже дофига.
    • Объявляется праздничная скидка на неделю, дальше цену возвращаем. Цена в течение недели будет 5700.
    • Предпраздничная цена )))600+пересыл.
    • Не только эта причина, есть и другая - отечественные мастерские еще с прошлого века прославились кидаловом. Поэтому Витюше верят больше.  Опять же, если Витюша и кинет, то ему, в отличие от мастерской, можно запросто морду набить.   
    • @malenich , это для вас рашка, а для меня Россия. Это моя Родина, я гражданин этой страны и проживаю в ней с рождения. И меня, как гражданина России, волнуют в первую очередь наши российские проблемы, по крайней мере гораздо больше внутриукраинских, особенно таких, которые характерны для многих стран, включая и мою. Поведение наших пропагандистских СМИ понятно - им за это бешеные бабки платят, но Вы-то  на кой ляд тащите сюда их пропаганду? Кто Вас до детей допустил, у Вас же начисто отключено критическое мышление! Чему Вы их научите? Кричать хайль?   @Pont 007 , протесты против размещения с подозрением на заражение понятны, но вот официальный запрет на въезд в страну  граждан страны пахнет совсем по другому: Россия прекратит пропуск граждан Китая через свою границу с нуля часов 20 февраля по местному времени — распоряжение об этом накануне подписал премьер Михаил Мишустин.
×
×
  • Create New...