опрос кнопок MEGA8
опрос кнопок MEGA8
Здравствуйте! помогите плиз с кусочком кода на "С" (пишу в компиляторе CVAVR).
задача такова: восемь кнопок одной стороной сидят на массе а второй подключены к PORTD (PORTD настроен и включена подтяжка), как написать что если любые две из восьми кнопок выключены тогда PORTD.1=0 а если все восемь включены тогда PORTD.1=1 ?
задача такова: восемь кнопок одной стороной сидят на массе а второй подключены к PORTD (PORTD настроен и включена подтяжка), как написать что если любые две из восьми кнопок выключены тогда PORTD.1=0 а если все восемь включены тогда PORTD.1=1 ?
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: опрос кнопок MEGA8
использовать оператор с условием if
заводим переменную для каждой кнопки удобнее использовать 1 байт для 8 кнопок где 1 нажата 0 отпущена, если сумма всех значений равна 2 то ....., если 8 тогда.....
заводим переменную для каждой кнопки удобнее использовать 1 байт для 8 кнопок где 1 нажата 0 отпущена, если сумма всех значений равна 2 то ....., если 8 тогда.....
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: опрос кнопок MEGA8
А можно сдвигами и сложениями. Вспомнить, что сдвиг сохраняет не поместившийся разряд в бит С, а при сложении этот бит можно добавить к слагаемым за 1 команду. На ассемблере это будет реализовать проще и быстрее чем на Си. А потом также, сравнением с 2 и 8. Подсчет кнопок займет 16 тактов. С учетом нициализации, но без учета if'ов и ввода - 18.
А можно использовать битовую магию, у меня получилось 15 тактов на подсчет кнопок. Не считая if'ов и ввода. Вот это решение даже приведу
А можно использовать битовую магию, у меня получилось 15 тактов на подсчет кнопок. Не считая if'ов и ввода. Вот это решение даже приведу
Спойлер
Хотя и не проверялКод: Выделить всё
.def temp=r16
.def sum=r17
ANY_PROC:
push temp //на всякий случай сохраняем временные регистры
push sum
in sum,PINB //считывание состояний кнопок. Наверное, и ввод и вывод в PORTD ошибка, пусть кнопки висят на PORTB
mov temp,sum
lsr temp //сдвиг на 1 байт
andi sum,0x55 //первое волшебное число
andi temp,0x55
add sum,temp
mov temp,sum
lsr temp //сдвиг на 2 байта
lsr temp
andi sum,0x33 // второе волшебное число
andi temp,0x33
add sum,temp
mov temp,sum
swap temp //сдвиг на 4 байта, старший полубайт в данном случае неважен, он будет отрезан andi sum,0x0F
add sum,temp
andi sum,0x0F // третье волшебное число
//проверки. Поскольку предыдущая часть считает лог.1, сравнивать надо отпущенные кнопки, а не нажатые.
cpi sum,0
breq BTN_8
cpi sum,6
breq BTN_2
FUNC_END: //конец процедуры, посстанавливаем сохраненные значения
pop sum
pop temp
ret
BTN_8:
sbi PORTD,1
rjmp FUNC_END
BTN_2:
cbi PORTD,1
rjmp FUNC_END- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: опрос кнопок MEGA8
Стоять-бояться! Это как? -
Включать, выключать подтяжку?
neox писал(а):...подключены к PORTD...тогда PORTD.1=0...тогда PORTD.1=1
Включать, выключать подтяжку?
Docendo discimus
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: опрос кнопок MEGA8
а к чему такая спешка - такты считать?! у меня вот достаточно тупой, без всякой магии, вариант потребляет максимум 55 тактов на вычисление количества единиц во входном байте, причем это максимум, если ни одной единицы в байте нет - и тактов по-моему 3 всего 
зато кратко и понятно, не то, что всякая ассемблерная магия 
P.S. про 55 тактов я соврал, поспешил. Прошу простить
Код: Выделить всё
uint8_t sum=0;
// переменная data содержит анализируемый байт
for(;data;data>>=1) sum += !!(data & 1);
// в переменной sum количество единиц, которые были в dataP.S. про 55 тактов я соврал, поспешил. Прошу простить
Последний раз редактировалось ARV Ср дек 10, 2014 08:11:51, всего редактировалось 1 раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: опрос кнопок MEGA8
Когда разница в 3.5 раза, уже стоит задуматься. Для данной задачи оптимизация не нужна, можно хоть if'ами каждый бит по отдельности считать. И, кстати, это все равно быстрее, 16 тактов независимо от размера. Что-то мне кажется, что среднее время работы у такого кода лучше, чем у Вашего, хотя минимальное, конечно, хуже.
Но как же можно не поразвлекаться с побитовой магией и ассемблером!
Код: Выделить всё
char x=PINB;
char sum=0;
if(x & (1<<0))sum++;
if(x & (1<<1))sum++;
if(x & (1<<2))sum++;
if(x & (1<<3))sum++;
if(x & (1<<4))sum++;
if(x & (1<<5))sum++;
if(x & (1<<6))sum++;
if(x & (1<<7))sum++;- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: опрос кнопок MEGA8
ARV писал(а):Код: Выделить всё
!!(data & 1);
а зачем данная конструкция туть? я имею ввиду двойное отрицание.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: опрос кнопок MEGA8
Хотел было сначала ответить: чтобы любое ненулевое число превращалось в 1. Но потом понял, что в скобках вообще-то не любое число, а либо 0, либо 1. Так что да, двойное отрицание не нужно. И вполне хватит
Код: Выделить всё
for(sum = 0; data; data >>= 1) sum += (data & 1);- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: опрос кнопок MEGA8
в виде функции, которую можно вызывать по мере надобности и не влияющую на все остальное, как то так:
Спойлер
Код: Выделить всё
void button(void)
{
unsigned char a,i;
for(i=0;i<8;i++)
{
if((PIND&(1<<i))==0) //проверяем в цикле все порты D
{a++;} //считаем сколько кнопок вкл/выкл
}
if(a==6) // если 2 из 8 выключены
{
//что то делаем....
}
if(a==8) // если все включены
{
//что то делаем....
}
a=0;
}
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: опрос кнопок MEGA8
да, стоит.COKPOWEHEU писал(а):уже стоит задуматься
как раз хотел спросить: а вы этот алгоритм сами придумали или просто содрали из книжки Кнута (если не ошибаюсь)? если сами - честь вам и хвала. однако сумеете ли преобразовать свой код для 16, 32 или 64-битных чисел? согласны, что мой код сработает для любой (в разумных пределах) разрядности переменной data без какой бы то ни был модификации?
перемудрил, признаюWiseLord писал(а):чтобы любое ненулевое число превращалось в 1. Но потом понял
среднее быстродействие моего варианта можно еще повысить, если цикл записать в соответствии с условиями задачи
Код: Выделить всё
for(;(sum < 2) && data; data >>=1)если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: опрос кнопок MEGA8
COKPOWEHEU писал(а):А можно использовать битовую магию, у меня получилось 15 тактов на подсчет кнопок. Не считая if'ов и ввода. Вот это решение даже приведу
Вау! Это какой-то известный алгоритм или сам придумал ?
придумал новые детальки : оптимистор и пессимистор ...
осталось придумать для чего они нужны ))))
осталось придумать для чего они нужны ))))
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: опрос кнопок MEGA8
А еще можно предподсчет сделать, если не жалко 256 байт. Оч быстро будет )
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: опрос кнопок MEGA8
Если процессор будет считать честно - медленно будет, лучше завести для (1<<i) отдельныю переменную.if((PIND&(1<<i))==0)
Содрал, но не с Кнута, а с говнокода, там же понял принцип работы. Продолжить ряд магических чисел? 0x5555, 0x3333, 0x0F0F, 0x00FF, вроде так для двухбайтных чисел.да, стоит.
как раз хотел спросить: а вы этот алгоритм сами придумали или просто содрали из книжки Кнута (если не ошибаюсь)?
Ваш код сработает для любой разрядности, но время иногда бывает критичным, а примерно для половны чисел (у которых старший бит равен 1) оно будет максимальным.
И при sum=2 оно повиснет.ARV писал(а):среднее быстродействие моего варианта можно еще повысить, если цикл записать в соответствии с условиями задачиКод: Выделить всё
for(;(sum < 2) && data; data >>=1)
А еще можно предподсчет сделать, если не жалко 256 байт. Оч быстро будет )
Упрощенный вариант с массивом из 16 элементов.
Код: Выделить всё
unsigned char len[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
unsigned char calc(unsigned char x){
return len[x&0x0F]+len[x>>4];
}- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: опрос кнопок MEGA8
почему?!COKPOWEHEU писал(а):И при sum=2 оно повиснет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: опрос кнопок MEGA8
Условие (sum<2) будет всегда возвращать false, а false && x = false независимо от х.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: опрос кнопок MEGA8
COKPOWEHEU писал(а):Условие (sum<2) будет всегда возвращать false, а false && x = false независимо от х.
ну дык верно, условие false и цикл завершается. с чего ему виснуть?
за пределами цикла смотрим на sum - если оно 0 - значит нет ни одной 1, если не ноль - как минимум что-то есть...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- COKPOWEHEU
- Говорящий с текстолитом
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Re: опрос кнопок MEGA8
Верно, прошу прощения.