контроль нажатой кнопки с помошью case

Обсуждаем контроллеры компании Atmel.
Azizbek
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Сб мар 07, 2015 05:49:57

контроль нажатой кнопки с помошью case

Сообщение Azizbek »

Всем доброго дня, можно ли эту конструкцию переписать через оператора SWITCH CASE?

Код: Выделить всё

  if(!(PIND & (1<<PIND0))) {
      digit=0;
      )else{
	 if  if(!(PIND & (1<<PIND1))) {
            digit=1;
      )else{
	 if  if(!(PIND & (1<<PIND2))) {
            digit=2;
      )else{
	 if  if(!(PIND & (1<<PIND3))) {
            digit=3;
      )else{
	 if  if(!(PIND & (1<<PIND4))) {
            digit=4;
      )else{
	 if  if(!(PIND & (1<<PIND5))) {
            digit=5;
      )else{
	 if  if(!(PIND & (1<<PIND6))) {
            digit=6;
      )else{
	 if  if(!(PIND & (1<<PIND7))) {
            digit=7;
      )else{
	 digit=8;
      }
PS:
Будет ли работать эта конструкция?

Код: Выделить всё

switch(PINB){
	 case (1<<PINB0):digit=0;break;
	    case (1<<PINB1):digit=1;break;
	       case (1<<PINB2):digit=2;break;
		  case (1<<PINB3):digit=3;break;
		     case (1<<PINB4):digit=4;break;
			case (1<<PINB5):digit=5;break;
			   case (1<<PINB6):digit=6;break;
			      case (1<<PINB7):digit=7;break;
			       default: digit=8;break;
Последний раз редактировалось Azizbek Сб апр 18, 2020 08:45:27, всего редактировалось 1 раз.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: контроль нажатой кнопки с помошью case

Сообщение VladislavS »

1. Нельзя. Хотя бы потому что это не валидная программа ни на одном известном мне языке.
2. Почему switch? Это же не оптимально. Вот, как идея, функция поиска старшего установленного бита. Под меньшую разрядность и инверсию подправить дело 3 сек.

Код: Выделить всё

uint32_t MostSignificantBitNum(uint32_t x)
{
  uint32_t pos=0;
  if(x >= 1U<<(pos+16)) pos+=16;
  if(x >= 1U<<(pos+8)) pos+=8;
  if(x >= 1U<<(pos+4)) pos+=4;
  if(x >= 1U<<(pos+2)) pos+=2;
  if(x >= 1U<<(pos+1)) pos+=1;
  return pos;
}
Добавлено after 7 minutes 9 seconds:
[uquote="Azizbek",url="/forum/viewtopic.php?p=3829285#p3829285"]PS:
Будет ли работать эта конструкция?[/uquote]Будет, но она не тождественна первоначальному "псевдокоду" ну и не оптимальна.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: контроль нажатой кнопки с помошью case

Сообщение Ivanoff-iv »

да оба кода кривые.. что за конструкция if if в первом?
нет закрывающей скобки во втором...
кстати, эта конструкция не поймёт одновременного нажатия 2х кнопок
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Azizbek
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Сб мар 07, 2015 05:49:57

Re: контроль нажатой кнопки с помошью case

Сообщение Azizbek »

Переделал код. Действительно что то перемудрил с ифами.

Код: Выделить всё

   if(PINB>=0){
if (!(PINB&0b00000001)) { digit=0; t=0;}    
if (!(PINB&0b00000010)) { digit=1; t=10000;}	    
if (!(PINB&0b00000100)) { digit=2; t=5000;}	    
if (!(PINB&0b00001000)) { digit=3; t=1000;}
if (!(PINB&0b00010000)) { digit=4; t=500;}
if (!(PINB&0b00100000)) { digit=5; t=400;}
if (!(PINB&0b01000000)) { digit=6; t=300;}
if (!(PINB&0b10000000)){  digit=7; t=200;}}
else{
   digit=0;
   t=0;
}


Просто пытаюсь сделать генератор прямоугольных импульсов с переключением частоты.
вот весь код:

Код: Выделить всё

#include <avr/io.h>
#include <util/delay.h>

int t=1;
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80};
int digit=0;

int main(void)
{
   DDRB=0X00;
   DDRC=0XFF;
   DDRD=0xFF;  
   
   PORTB=0XFF;
   PORTC=0Xff;
   PORTD=0x00;
   
    while (1){
       if(PINB>=0){
if (!(PINB&0b00000001)) { digit=0; t=0;}    
if (!(PINB&0b00000010)) { digit=1; t=10000;}	    
if (!(PINB&0b00000100)) { digit=2; t=5000;}	    
if (!(PINB&0b00001000)) { digit=3; t=1000;}
if (!(PINB&0b00010000)) { digit=4; t=500;}
if (!(PINB&0b00100000)) { digit=5; t=400;}
if (!(PINB&0b01000000)) { digit=6; t=300;}
if (!(PINB&0b10000000)){  digit=7; t=200;}}
else{
   digit=0;
   t=0;
}

       PORTC = ~SEGMENTE[digit];
if(digit>0){

      PORTD |= (1<<(PORTD0));
_delay_ms(t/3);
      PORTD |= (1<<(PORTD1));
_delay_ms(t);
      PORTD &= ~(1<<(PORTD0));
_delay_ms(t/3);
      PORTD &= ~ (1<<(PORTD1));
_delay_ms(t);
  
   }else{
   
    PORTD=0x00;}
       }
}

Изображение
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: контроль нажатой кнопки с помошью case

Сообщение BlackKilkennyCat »

digit получается лишней. достаточно t
Меня здесь больше нет
Azizbek
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Сб мар 07, 2015 05:49:57

Re: контроль нажатой кнопки с помошью case

Сообщение Azizbek »

[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3829379#p3829379"]digit получается лишней. достаточно t[/uquote]
Не совсем понял.
через digit я вывожу индикацию на дисплей а через t задаю время задержки.
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: контроль нажатой кнопки с помошью case

Сообщение BlackKilkennyCat »

if (!(PINB&0b00000001)) { digit=0; t=0;}

заменить на

if (!(PINB&0b00000001)) {PORTC = 0xC0; t=0;}

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

Я бы еще и насчёт t/3 подумал бы...
Меня здесь больше нет
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: контроль нажатой кнопки с помошью case

Сообщение NStorm »

BlackKilkennyCat, это уже оптимизация в ущерб читаемости кода. Если уж оптимизировать, то в дефайны хотя бы эти "магические числа" сегментника запихнуть. Но вообще если ресурсов хватает, то и пофиг, пусть будут digit и SEGMENTE. 10 байт оперативки тут экономить и пару слов во флэше так себе смысл имеет.
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: контроль нажатой кнопки с помошью case

Сообщение BlackKilkennyCat »

Согласен. хотя тут такой код, что не так уж и страшно. можно и комментариями обойтись. читать, что там из массива где-то от чего-то берется, инвертируется...
в общем, я за дефайны )
Меня здесь больше нет
Sergi
Мучитель микросхем
Сообщения: 412
Зарегистрирован: Ср янв 04, 2012 11:57:40
Откуда: Алчевск

Re: контроль нажатой кнопки с помошью case

Сообщение Sergi »

А зачем в первой строке if(PINB>=0) ? Может нужно if(PINB>0) ?
technik-1017
Открыл глаза
Сообщения: 42
Зарегистрирован: Вс сен 03, 2017 19:43:57
Контактная информация:

Re: контроль нажатой кнопки с помошью case

Сообщение technik-1017 »

Можно попробовать так (лучше один раз считать значение из порта в переменную и далее с ней работать, а то возможно, что при разборе if/case состояние входов измениться и логика работы программы нарушиться).

Код: Выделить всё

key = ~PINB;
switch(key)
{
    case 1: digit=0; t=0; break;
    case 2: digit=1; t=10000; break;
    case 4: digit=2; t=5000; break;
    case 8: digit=3; t=1000; break;
    case 16: digit=4; t=500; break;
    case 32: digit=5; t=400; break;
    case 64: digit=6; t=300; break;
    case 128: digit=7; t=200; break;
    default: t=0; break;
}
но программа будет страшно глючить
Надо бы:
1) вывод на индикатор сделать через прерывание
2) формировать выходную частоту также используя прерывания
3) хорошо бы устранить дребезг контактов, хотя при вашей реализации это и не сильно требуется, но любая помеха на входах кнопок приведёт к самопроизвольному нажатию.

Если памяти в контроллере много (а пока ещё очень много), то можно создать массив из 256 элементов unsigned char и переменную key отправлять в этот массив, выходом будет код нажатой клавиши (0-7). Далее это код клавиши использовать в программе (возможно опять как номер элемента других массивов (индикации, частот,...))
Последний раз редактировалось technik-1017 Сб апр 18, 2020 15:41:48, всего редактировалось 1 раз.
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: контроль нажатой кнопки с помошью case

Сообщение BlackKilkennyCat »

в этой программе прерывания излишне, более того, можно точно сказать, когда и что выполнится. а раз это можно сказать, то будет удивительно, если что-то будет "страшно глючить"
Меня здесь больше нет
technik-1017
Открыл глаза
Сообщения: 42
Зарегистрирован: Вс сен 03, 2017 19:43:57
Контактная информация:

Re: контроль нажатой кнопки с помошью case

Сообщение technik-1017 »

Тогда дальнейшее развитие программы не получиться, придётся писать заново.
И не понятно какие частоты хочет получить ТС. Пока получаются две частоты сдвинутые друг от друга на 1/3.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: контроль нажатой кнопки с помошью case

Сообщение BOB51 »

Это удобный метод только в том случае, если сначала выполняется антидребезговый фильтр, а затем обработка с switch/case в которой используются указатели на функции.
Удобно для клавиатуры с изменяемым по ходу работы функционалом.
Хотя в принципе, можно и антидребезг там пристроить - только уж... слишком избыточно будет.
8)
Azizbek
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Сб мар 07, 2015 05:49:57

Re: контроль нажатой кнопки с помошью case

Сообщение Azizbek »

Спасибо что откликнулись.
я задача в том что б получить строго зафиксированные две, сдвинутые друг от друга на одну треть, частоты при переключении кнопок. В данное время в программе примерные значения. Сколько ни читал про прерывания и таймеры так и не разобрался (наверно уже возраст не тот или мозги совсем затвердели :) ). В интернете полно схем но в основном часы. Схему хочу собрать на AtMega8A-PU.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: контроль нажатой кнопки с помошью case

Сообщение BOB51 »

Дробим программу на две задачт - одна таймерами управляет, вторая кнопками.
Насчет 1/3 это жирновато - проще на величину, кратную двойке...
В принципе от возможностей таймеров и их конфигурации зависит.
На ассемблере это показать можно. И то предпочтительно на известных - тини2313, мега 8515...
Под Си... разве что извратом на адуринке...
8)
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: контроль нажатой кнопки с помошью case

Сообщение BlackKilkennyCat »

да можно и на 1/3 . Если некий фиксированный набор частот (как в этой программе), то можно хоть и на 1/2.95674324 сдвиг делать, поскольку t/3 (или t/2.95674324) можно либо просчитать до генерации, либо выкинуть вообще, просчитав вне и записав готовыми константами
Меня здесь больше нет
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: контроль нажатой кнопки с помошью case

Сообщение Demiurg »

Книга Вольфганг Трамперт AVR-RISC микроконтроллеры. В ней есть пример запуска таймеров. На ассемблере, но по этой книге можно понять как запускать таймеры.
Аватара пользователя
Ariadna-on-Line
Это не хвост, это антенна
Сообщения: 1479
Зарегистрирован: Вс май 13, 2012 00:01:54

Re: контроль нажатой кнопки с помошью case

Сообщение Ariadna-on-Line »

Скомпилированная конструкция на Switch Case занимает намного больше памяти чем равноценная на If Else. Проверено. Сам озадачивался этим вопросом.
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: контроль нажатой кнопки с помошью case

Сообщение NStorm »

Ariadna-on-Line, не верю без примера )
Ответить

Вернуться в «AVR»