Перейти к содержанию

Варианты Опроса Кнопок В Avr Studio 6


Тверской

Рекомендуемые сообщения

Всем доброго времени суток и заранее спасибо за участие в данной теме :)

Суть вопроса такова:

Имею схему

post-120077-0-55852000-1405779164_thumb.jpg

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

Есть у меня книга Белова, где он (ну и я с ним заодно) шагает от чайника до профи в разработке устройств на AVR, дак там в большинстве случаев он использует коде вижион в котором можно опросить напрямую состояние любого бита в порту ( например PIND.0==1 ну и так далее) как для меня то просто и понятно.

В студии же такого нету. Полазив по инету понял что есть вариант со сдвиганием битов влево, пропуском через "или" и как то дальше, но более лёгкого пути я не нашёл. :umnik2:

Какие есть ещё способы опроса кнопок в студии??? и расскажите пожалуйста поподробнее про метод со сдвиганием битов. Бьюсь уже несколько дней та всё невыходит понять как надо, чтоб сделать как нужно) :help:

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

( например PIND.0==1 ну и так далее) как для меня то просто и понятно.

В студии же такого нету.

Разумеется, в Студии вроде используется gcc-avr, а в Си такие конструкции запрещены.
Нажатием кнопок хочу задавать двоичный код
Там же всего 4 кнопки, если уж так хочется в двоичном коде - это займет 2 бита. Какая разница, 2 бита или 4, все равно байт выделять? Как планируется обрабатывать одновременное нажатие нескольких кнопок?
PIND.0==1
На асме это выглядит просто как sbic PIND,0 / sbis PIND,0. В обычном Си - (PIND & (1<<0)).
Какие есть ещё способы опроса кнопок в студии???
В студии? Там поддержка только обычной клавиатуры для ввода исходного кода, или там горячие клавиши.
расскажите пожалуйста поподробнее про метод со сдвиганием битов
А что там рассказывать? Рисуете на бумажке любой байт, например, 0b00010000 и смотрите, как он должен себя повести при операциях сдвига на 1, 2, N. Про логические операции хотя бы знаете? AND, OR, NOT, XOR.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Чтобы задать цифру больше 8 всё равно придётся нажимать 2 или более кнопок.

Обрабатывать лучше одновременно все сразу.

Цифровую логику знаю хорошо.

Вот теперь про сдвиг в байте:кнопка не нажата---входы подтянуты резистором значит мы имеем 0b11111111, сдвигаю на 1 разряд влево, получаю 0b11111110,пропускаю через "И" с 1 (т.к. pin D подтянут на +) и получаю 0b11111110кнопка нажата --- выходит 0b11111110,сдвигаю на 1 разряд влево, получаю 0b11111100,пропускаю через "И" с 1 (т.к. pin D подтянут на +) и получаю 0b11111100

Моя логика такова хоть где-то и неверна) А дальше надо опрашивать какое значение? если не нажата 0b11111110, если нажата то 0b11111100 или как то по другому обрабатывать?

Изменено пользователем Тверской
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Для отдельной кнопки сдвиг порта вообще не нужен, я же приводил пример: if(PIND & (1<<0)) - если на PD0 лог.1, соответственно, if(!(PIND & (1<<5))) - если на PD5 лог.0. Как вообще планировалось осуществить ввод? Даже если предположить, что знаете как решить проблему синхронизации и восприятия человеком двоичного числа, комбинация из 4 кнопок даст всего 4 бита, то есть числа от 0x00 до 0x0F, то есть полбайта. Синхронизацию тоже не стоит игнорировать: допустим, хотите ввести 0x0F = 0b00001111, но нажать все кнопки за время ~1 мкс невозможно. Какие-то нажмутся раньше, какие-то позже. Может объясните, зачем все-таки именно такая схема? Может есть вариант попроще?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

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

Это только для начала,чтоб не превратить всё в кашу,как решу этот вопрос то продолжу дополнять своё устройство ещё нужными функциями, но об этом позже)

Ссылка на комментарий
Поделиться на другие сайты

Так как определите, что ввод данного числа закончился? Вот нажал пользователь на 1 и 3 кнопки. Откуда контроллеру знать, будут ли нажимать на остальные?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Опрос будет допустим раз в 0,5 сек. Кнопки не нажаты, на выходе чистая единица, нажата кнопка 1,на выходе 1 импульс,нажата кнопка 2,на выходе 2 импульса,нажата кнопка 1 и 2,на выходе 3 импульса и так далее. Кнопки с фиксацией будут.Пока нажаты,идут импульсы,не нажаты, не идут

Изменено пользователем Тверской
Ссылка на комментарий
Поделиться на другие сайты

В чем тогда проблема? Двоичный код количества импульсов есть, даже преобразований делать не надо. Разве что NOT и AND, чтобы нажатая кнопка соответствовала выставленному в 1 биту, а незначащие биты были занулены.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

как всё это в коде собрать не пойму(

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

А вот как опросить кнопки и получить итоговую цифру чтоб присвоить значение переменной ещё не разобрался

Изменено пользователем Тверской
Ссылка на комментарий
Поделиться на другие сайты

Считать PIND, вот и число

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

В общем пока я надумал только такой код

#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
unsigned char i;

void preset() {
DDRB = 0xFF; //порт B работает на выход
PORTB = 0xFF; //на выходе порта B везде 1
DDRD= 0x00; //порт D работает на вход
PORTD = 0xFF; // подтяжка резисторами
}

int main(void)
{
preset();


while (1)
{
if (PIND = ((0b11111110)|(0b11111101)|(0b11111011)|(0b11110111)))
{
PORTB = 0x00; // отключаем сигнал
_delay_ms(16); //формируем импульс сброса (16мc)
PORTB = 0xff; // подключаем сигнал
_delay_ms(1000); //формируем полку питания
}
else
{
if (PIND == 0b11111110)
{i=13;}
if (PIND == 0b11111101)
{i=12;}
if (PIND == 0b11111011)
{i=10;}
if (PIND == 0b11110111)
{i=6;};
}

// 1 извещатель
for (i=i; i<15; i+=1)
{
PORTB = 0xff; // подключаем сигнал
_delay_ms(16); // время работы извещателя
PORTB = 0x00; // конец работы извещателя
_delay_us(250); //формируем адресную задержку на 250мкс
}
}
}

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

Изменено пользователем Alex
тег [CODE]
Ссылка на комментарий
Поделиться на другие сайты

Вот же Вам ответ сказали :

Считать PIND, вот и число

Просто прочитайте порт, игнорируйте старшие биты (начиная с 4-ого), и будет Вам код нажатых кнопок (0x00 - 0x0F).

Ссылка на комментарий
Поделиться на другие сайты

а инвертировать не придётся? и вообще правильно ли я считаю что

0b11111110 будет при нажатии первой кнопки;

потом отпустили её и так везде

0b11111101 при нажатии 2-ой;

0b11111011 при нажатии 3-ей

0b11110111 при нажатии 4-ой

я с логикой работаю в микросхемах, там с ней по проще, а вот с программами не сталкивался)

Изменено пользователем Тверской
Ссылка на комментарий
Поделиться на другие сайты

а инвертировать не придётся?

Ну судя по активному нулю - придётся. Но это, думаю, не проблема.
и вообще правильно ли я считаю что

0b11111110 будет при нажатии первой кнопки;

0b11111101 при нажатии 2-ой;

0b11111011 при нажатии 3-ей

0b11110111 при нажатии 4-ой

Да, правильно.

я с логикой работаю в микросхемах, там с ней по проще, а вот с программами не сталкивался)

Для сброса битов в переменной нужно использовать операцию AND.

Например :

var = var&0x0F;

оставит младшие 4 бита в переменной var нетронутыми, а остальные сбросит в ноль.

В итоге, считывание ПИНов, в Вашем случае, сведётся к паре строк.

var = PIND & 0x0F; // Читаем порт и сбрасываем 4 старших бита
var = 0x0F-var; // Инверсия битов

Ссылка на комментарий
Поделиться на другие сайты

допустим я нажал кнопки 1 и 3, значит я должен сложить 0b11111110 и 0b11111011, сложение это функция "ИЛИ", складываю и получаю везде единицы, как быть?

Ссылка на комментарий
Поделиться на другие сайты

нажав эти кнопки я получу на порту D 0b11111010, далее инвертирую,получаю 0b00000101 и могу эту цифру закинуть в переменную.

правильно я мыслю?

Изменено пользователем Тверской
Ссылка на комментарий
Поделиться на другие сайты

Не совсем правильно. На порте D Вы получите не 0b11111010, а 0bxxxx1010, где x - неизвестное состояние. По этому, нужно их сначала сбросить (ну или наоборот установить, как будет удобнее), а затем уже инвертировать.

Я показал пример, попробуйте в нём разобраться.

Ссылка на комментарий
Поделиться на другие сайты

По вашему примеру

var = PIND & 0x0F; // Читаем порт и сбрасываем 4 старших бита

var = 0x0F-var; // Инверсия битов

кнопки не нажаты, значит в строке 0b11111111 & 0x0F (0x0F=0b00001111) = 0b00001111 --- присваиваем это значение переменной

а во второй строке 0x0F минус переменная?

Ссылка на комментарий
Поделиться на другие сайты

in r16,PIND
com r16
andi r16,0x0F
;в r16 - число

Учите уже ассемблер!

char temp=PIND;
temp=(~temp)&0x0F;
;в temp - число

Учите уже Си!

переменная temp
temp <- not(PIND) AND 0x0F;
в temp - число

Учите уже логику!

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Ассемблер только после того как с СИ буду знаком)

temp=(~temp)&0x0F;

кнопки ненажаты- значит инвертирую 0b11111111, получаю 0b00000000, пропускаю через И с 0b00001111и получаю также 0b00000000 потом записалось в переменную

нажал кнопки 1 и 2 - теперь инвертирую 0b00000011,пропускаю через И также с с 0b00001111 и в итоге 0b00000011 записываю в переменную.

Изменено пользователем Тверской
Ссылка на комментарий
Поделиться на другие сайты

Так в чем вопрос?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

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

В итоге мой код свёлся к такому

#define F_CPU 8000000

#include <avr/io.h>

#include <util/delay.h>

void preset() {

DDRB = 0xFF; //порт B работает на выход

PORTB = 0xFF; //на выходе порта B везде 1

DDRD= 0x00; //порт D работает на вход

PORTD = 0xFF; // подтяжка резисторами

}

char i;

int main(void)

{

preset();

char i=PIND;// читаем portD

i=(~i)&0x0F;// в i - число заданное нажатыми кнопками

while (1)

{

if (PIND==0xff)

{

PORTB = 0x00; // отключаем сигнал

_delay_ms(16); //формируем импульс сброса

PORTB = 0xff; // подключаем сигнал

_delay_ms(1264); // рабочее питание

}

else

{

// 1 извещатель

for (i=i; i<15; i+=1)

{

PORTB = 0xff; // подключаем сигнал

_delay_ms(16); // время работы извещателя

PORTB = 0x00; // конец работы извещателя

_delay_us(250); //формируем адресную задержку на 250мкс

}

}

PORTB = 0xff; // подключаем сигнал

_delay_ms(1264); // рабочее питание

}

}

}

Вот в протеусе симулирую, та что-то на кнопки не реагирует)

схема ниже

shema.rar

Изменено пользователем Тверской
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...