Страница 1 из 2
контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 08:30:33
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;
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 08:51:09
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]Будет, но она не тождественна первоначальному "псевдокоду" ну и не оптимальна.
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 10:11:30
Ivanoff-iv
да оба кода кривые.. что за конструкция if if в первом?
нет закрывающей скобки во втором...
кстати, эта конструкция не поймёт одновременного нажатия 2х кнопок
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 10:54:54
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;}
}
}

Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 11:13:30
BlackKilkennyCat
digit получается лишней. достаточно t
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 11:35:02
Azizbek
[uquote="BlackKilkennyCat",url="/forum/viewtopic.php?p=3829379#p3829379"]digit получается лишней. достаточно t[/uquote]
Не совсем понял.
через digit я вывожу индикацию на дисплей а через t задаю время задержки.
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 11:44:00
BlackKilkennyCat
if (!(PINB&0b00000001)) { digit=0; t=0;}
заменить на
if (!(PINB&0b00000001)) {PORTC = 0xC0; t=0;}
и т.д.
Если нигде больше массив SEGMENTE и его индекс использоваться не будут, то они не нужны
Я бы еще и насчёт t/3 подумал бы...
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 13:11:48
NStorm
BlackKilkennyCat, это уже оптимизация в ущерб читаемости кода. Если уж оптимизировать, то в дефайны хотя бы эти "магические числа" сегментника запихнуть. Но вообще если ресурсов хватает, то и пофиг, пусть будут digit и SEGMENTE. 10 байт оперативки тут экономить и пару слов во флэше так себе смысл имеет.
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 13:18:20
BlackKilkennyCat
Согласен. хотя тут такой код, что не так уж и страшно. можно и комментариями обойтись. читать, что там из массива где-то от чего-то берется, инвертируется...
в общем, я за дефайны )
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 13:25:03
Sergi
А зачем в первой строке if(PINB>=0) ? Может нужно if(PINB>0) ?
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 14:08:58
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). Далее это код клавиши использовать в программе (возможно опять как номер элемента других массивов (индикации, частот,...))
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 14:25:22
BlackKilkennyCat
в этой программе прерывания излишне, более того, можно точно сказать, когда и что выполнится. а раз это можно сказать, то будет удивительно, если что-то будет "страшно глючить"
Re: контроль нажатой кнопки с помошью case
Добавлено: Сб апр 18, 2020 14:50:00
technik-1017
Тогда дальнейшее развитие программы не получиться, придётся писать заново.
И не понятно какие частоты хочет получить ТС. Пока получаются две частоты сдвинутые друг от друга на 1/3.
Re: контроль нажатой кнопки с помошью case
Добавлено: Вс апр 19, 2020 04:18:50
BOB51
Это удобный метод только в том случае, если сначала выполняется антидребезговый фильтр, а затем обработка с switch/case в которой используются указатели на функции.
Удобно для клавиатуры с изменяемым по ходу работы функционалом.
Хотя в принципе, можно и антидребезг там пристроить - только уж... слишком избыточно будет.

Re: контроль нажатой кнопки с помошью case
Добавлено: Вс апр 19, 2020 06:40:17
Azizbek
Спасибо что откликнулись.
я задача в том что б получить строго зафиксированные две, сдвинутые друг от друга на одну треть, частоты при переключении кнопок. В данное время в программе примерные значения. Сколько ни читал про прерывания и таймеры так и не разобрался (наверно уже возраст не тот или мозги совсем затвердели

). В интернете полно схем но в основном часы. Схему хочу собрать на AtMega8A-PU.
Re: контроль нажатой кнопки с помошью case
Добавлено: Вс апр 19, 2020 12:59:44
BOB51
Дробим программу на две задачт - одна таймерами управляет, вторая кнопками.
Насчет 1/3 это жирновато - проще на величину, кратную двойке...
В принципе от возможностей таймеров и их конфигурации зависит.
На ассемблере это показать можно. И то предпочтительно на известных - тини2313, мега 8515...
Под Си... разве что извратом на адуринке...

Re: контроль нажатой кнопки с помошью case
Добавлено: Вс апр 19, 2020 13:13:09
BlackKilkennyCat
да можно и на 1/3 . Если некий фиксированный набор частот (как в этой программе), то можно хоть и на 1/2.95674324 сдвиг делать, поскольку t/3 (или t/2.95674324) можно либо просчитать до генерации, либо выкинуть вообще, просчитав вне и записав готовыми константами
Re: контроль нажатой кнопки с помошью case
Добавлено: Вт апр 21, 2020 04:48:03
Demiurg
Книга Вольфганг Трамперт AVR-RISC микроконтроллеры. В ней есть пример запуска таймеров. На ассемблере, но по этой книге можно понять как запускать таймеры.
Re: контроль нажатой кнопки с помошью case
Добавлено: Чт май 14, 2020 22:44:29
Ariadna-on-Line
Скомпилированная конструкция на Switch Case занимает намного больше памяти чем равноценная на If Else. Проверено. Сам озадачивался этим вопросом.
Re: контроль нажатой кнопки с помошью case
Добавлено: Чт май 14, 2020 23:54:14
NStorm
Ariadna-on-Line, не верю без примера )