Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

Re: Вопросы по С/С++ (СИ)

Сообщение Vlad0o »

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

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

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

unsigned int button1(void)
{
unsigned int Bb1;

P3MDOUT = 0; //Настраиваем на вход
P3 = 0xFF;
DB4 = 1; //это одновременно шина данных ЛСД и кнопки. если в один порт поставить 1, то именно эта кнопка будет работать
DB5 = 0;
DB6 = 0;
DB7 = 0;

if (B0 == 1)
{Delay(10000); //проверка на дребезг
Delay(5000);
}
if (B0 == 1)

{currentButton1 = 1;}
if (lastButton1 == 0 && currentButton1 == 1)
{//LED2 = !LED2;
//LED1 = !LED1;
//LED3 = !LED3; //предположим что то делается тут.
//LED4 = !LED4;
Bb1 = 1;
//T = T-1;
}
else {Bb1 = 0;}

lastButton1 = currentButton1;
return Bb1;
}



Схема подключения кнопок: http://i023.radikal.ru/1111/b8/80306427b39b.jpg

B0 - это Р3.0 - c его помощью и проверяем нажата кнопка или нет


Заранее спасибо

ЗЫ я серьезно буду благодарен и без всякой иронии, поскольку Си для меня пока на 1/10 (а может и 4/100) понятен
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Мастер Ломастер »

работа с кнопками проще всего ведется по следующему алгоритму:
1. делается функция, которая возвращает состояние порта, к которому подключены кнопки. эта функция может привести это состояние к нормальному виду, когда нажатой кнопке соответствует не ноль на порту, а единичка.
2. делается функция, которая вызывает первую дважды: первый раз результат запоминается, затем делается пауза для защиты от дребезка в 10-15 мс, а потом вызывается второй раз и сравнивается с предыдущим результатом. если оба раза получено ОДНО И ТО ЖЕ - надо этот результат вернуть, это и будет состояние кнопок. если первый и второй раз разное - надо вернуть 0 (не нажата ни одна кнопка).
3. в том месте, где надо отреагировать на кнопку, вызывается функция 2 и по возвращенному ею значению определяется, какая кнопка нажата, и соответственно, делается то или иное действие.

получается очень лаконично и надежно. если нужны всякие фичи типа автоповтора при удержании и т.п., то все это делается ВНУТРИ функции 2, а для основной части программы все будет совершенно прозрачно.

как-то так:

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

static unsigned char get_pins(void){ // это функция 1
   return ~PIND & KEY_MASK;
}

static unsigned char get_key(void){ // это функция 2
   unsigned char key = get_pins();
   delay_ms(10);
   if(key == get_pins())
      return key;
   else
      return 0;
}

//где-то в нужном месте программы реагируем на кнопки
unsigned char key = get_key();
switch(key){
case KEY_1 :
   ...
   break;
case KEY_2:
   ...
   break;
   // и так далее все варианты нажатых кнопок
}
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

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

Я не понимаю что такое P3MDOUT и P3 и B0 - я не знаю что у тебя за компилятор и проц - но привыкай такие специфичные вещи либо не использовать либо прятать в дефайнах. Хотя может это у тебя дефайны к чему-то более понятному )

Я так понимаю что кнопок четыре?
DB4 = 1; //это одновременно шина данных ЛСД и кнопки. если в один порт поставить 1, то именно эта кнопка будет работать
DB5 = 0;
DB6 = 0;
DB7 = 0; это дефайны каких то пинов порта или это непосредственный доступ к порту?

ЗЫ могу канеш тебе код написать но лучше давай со всем разберемся и сам сделаешь в итоге
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

Re: Вопросы по С/С++ (СИ)

Сообщение Vlad0o »

У меня стоит KEIL проц силабс 8051f314. Силабс не так распространен у радиолюбителей интернетах, поэтому я долго вникал, благо здесь подсказывали.
Ситуация такая:

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

P3MDOUT = 0; //Настраиваем на вход
P3 = 0xFF;
это специфичная штука инициализации. чтоб порты работали на вход.

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

DB4 = 1;
DB5 = 0;
DB6 = 0;
DB7 = 0;
все правильно, это шина лсд и одновременно порты на которые посадили кнопки (P3.1 P3.2 P3.3 P3.4)

В0 - контрольный ПИН (Р3.0) когда мы выставляем к примеру на DB4 1 и нажимаем эту кнопку на "девелопментборде" (самодельном) то на вход В0 приходит 1 и так регистрируется нажатие.
Про дребезг я знаю и вроде как учел. проверил - нажимается.
Попробую сделать как посоветовал Мастер Ломастер.
А то я написал по урок от ардуина на ютубе))) я алгоритм позаимствовал, там то конечно сразу все кнопки проверяются, а у меня конкретная кнопка и все это из-за танцев с "контрольным ПИНом"

А вообще собираюсь меню приделать - кнопки есть, лсд есть, датчики температуры есть, реле есть. Пытался на switch case собрать, но почему то превысил лимит памяти в 8кб. даже не знаю куда она делась.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Мастер Ломастер »

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

если вы решите проблему конфиликта, то предложенный мной алгоритм полностью сохраняется: вы изменяете функцию 1 под свои нужды и далее все по плану.
битва с дураками проиграна, победители торжествуют. слава победителям!
Vlad0o
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

Re: Вопросы по С/С++ (СИ)

Сообщение Vlad0o »

"совмещение кнопок с шиной данных дисплея - штука хитрая" - это Вы верно сказали. с этим пришлось повозиться.
А схему я очень схематично нарисовал) там проблема с выжиганием была решена на аппаратном уровне, но не мной.
Конфликт с ЛСДшником вроде как решен. лсд инициализирую в начале главного цикла рядом с инициализацией остальной периферии. поскольку порт один и он должен работать и на вход и на выход. то на выход его я инициализирую в функциях ЛСД, а на выход в функциях "кнопок". благо лсдшник надо инициализировать только один раз. поэтому все сводится к поочередному опрашиванию нужной кнопки и выводу на экран текста. Теоретически если держать кнопку на экране должны появляться непонятные символы или еще какая нибудь фигня или вообще ничего не выводиться. и так кстати бывало. Но я делал так что при нажатии и удержании кнопки на экране цифры поочередно сменяли друг друга.
inkHunter
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб авг 21, 2010 20:44:27
Откуда: Ростов
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение inkHunter »

Не могу понять
#define USB_EVT_SETUP 1

if (USB_P_EP[n]) {
USB_P_EP[n] (USB_EVT_SETUP); ?????
}

массив а дальше (1) что это такое ?
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

Массив указателей на функции, собсно вызывает функцию USB_P_EP[n](1) с аргументом 1.
inkHunter
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб авг 21, 2010 20:44:27
Откуда: Ростов
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение inkHunter »

как записать в массиве функции ?

знаю что можно так
int (*pf[2])(int)={f1,f2};
но с указателем, а как без него ?

вот фун. для примера:
int f1 (int i)
{
return i;
}

int f2 (int i)
{
return i;
}

int mf[5]={f1(),f2()}; так не можно.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

int mf[0]=&f1;
int mf[1]=&f2;

Это ж массив УКАЗАТЕЛЕЙ все же )
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Мастер Ломастер »

BCluster писал(а):int mf[0]=&f1;
int mf[1]=&f2;
Это ж массив УКАЗАТЕЛЕЙ все же )

для функций наличие амперсенда необязательно, т.к. имя функции - уже адрес ее тела :)
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

Да, но так нагляднее имхо)
inkHunter
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб авг 21, 2010 20:44:27
Откуда: Ростов
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение inkHunter »

BCluster писал(а):int mf[0]=&f1;
int mf[1]=&f2;

Это ж массив УКАЗАТЕЛЕЙ все же )


int (*pf[2])(int);
int a=0;

int main(void)
{
pf[0]=f1;
a=pf[0](2);

}

1.да это все работает с указателем, а как без УКАЗАТЕЛЯ можна записать в массив функции типа такого m[2]={f1(),f2()}.
2. Не пойму можно что так a=pf[0](2); и так a=(*pf[0])(2);

понимаю так в pf[0] адрес на фун. f1 и f1 возращает значения которое мы присваиваем переменной а.
А когда a=(*pf[0])(2); ????!!!! зачем использовать оператор разыменования у нас же не адрес, мы же не можем написать а=(*с) где с переменная ???!!!!
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

int (*pf[2])()={test1,test2}; например так можно заинициализировать...
Victor Gordienko писал(а):зачем использовать оператор разыменования у нас же не адрес

Мастер Ломастер писал(а):для функций наличие амперсенда необязательно, т.к. имя функции - уже адрес ее тела
inkHunter
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб авг 21, 2010 20:44:27
Откуда: Ростов
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение inkHunter »

BCluster писал(а):int (*pf[2])()={test1,test2}; например так можно заинициализировать...


Уже второй раз пишу КАК БЕЗ УКАЗАТЕЛЯ ?! а Вы одно и тоже ....
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Мастер Ломастер »

Victor Gordienko писал(а):
BCluster писал(а):int (*pf[2])()={test1,test2}; например так можно заинициализировать...


Уже второй раз пишу КАК БЕЗ УКАЗАТЕЛЯ ?! а Вы одно и тоже ....
вы что хотите записать в массив? адреса своих функций или результат, ими возвращаемый?

если первое, то без указателей никак, потому что адрес - это указатель. можно, конечно, привести тип к другому, но НАФИГА?!

а если второе, то это на этапе компиляции сделать невозможно, только на этапе исполнения поочередно записать в массив нужные числа.
битва с дураками проиграна, победители торжествуют. слава победителям!
inkHunter
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб авг 21, 2010 20:44:27
Откуда: Ростов
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение inkHunter »

результат фун. все спасибо большое понял ...
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

мдя :)
Аватара пользователя
МитяРа
Модератор
Сообщения: 11492
Зарегистрирован: Чт дек 11, 2008 14:52:26
Откуда: град Нижний

Re: Вопросы по С/С++ (СИ)

Сообщение МитяРа »

Вопрос к зантокам СИ, применительно к AVR-ам:

Можно-ли портировать приложенную программу с AT90S2313 на что-то более щас распространённое, типа ТиниХХХ ?
Вложения
c2avr.c
(9.1 КБ) 301 скачивание
[img]http://radiokot.ru/forum/download/file.php?id=93376[/img][i][color=#000080][size=85]Между людьми возникает напряжение, если у них разный потенциал...[/size][/color][/i]
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Мастер Ломастер »

МитяРа писал(а):Вопрос к зантокам СИ, применительно к AVR-ам:
Можно-ли портировать приложенную программу с AT90S2313 на что-то более щас распространённое, типа ТиниХХХ ?
думаю, это элементарно. на тини2313 вообще должно лечь почти без усилий. программа написана аккуратно, хотя и не все идеально. сдается мне, что ее несложно портировать вообще на любой МК.

P.S. судя по всему, программа написана для какой-то старой версии avr-gcc, поэтому при помощи WinAVR с ней будет проще всего работать...
битва с дураками проиграна, победители торжествуют. слава победителям!
Ответить

Вернуться в «Разные вопросы по МК»