Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.73/52: Рейтинг темы: голосов - 52, средняя оценка - 4.73
HotD
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
1

Оптимизация кода, Си

19.02.2014, 14:41. Просмотров 9381. Ответов 30
Метки нет (Все метки)

День добрый. Ситация следующая. Код работает, все отлично, но написан он, мягко скажем, коряво. Если вкратце - есть 12 кнопок. Висят на совершенно разных портах, при нажатии выполняются аналогичные действия, меняются только переменные, включается однотипная периферия, в общем - изменил алгоритм для 1 кнопки, на других он будет совершенно такой-же, только с другими переменными. Сейчас выхожу из ситуации так:
Проверяю первую кнопку:
//сканируем кнопки
#define NUMBER 1
#define BUTTON BUT_1
#define TSOP TSOP_1
#define TUBE EE_TUBE_1
#define TUBE_ERR EE_TUBE_1_ERR
#define TUBE_COIN EE_TUBE_1_COIN

if (!BUTTON && !(stat_UV & (1<<(NUMBER-1))))
{
_delay_ms(150);
while(!BUTTON);
{

#ifdef DEBUG
//счетчик 30 монет
temp_EE=eeprom_read_byte(&TUBE_COIN); //читаем то, что уже в памяти
if (temp_EE>0) //чтобы не уйти в минус
{
temp_EE--;
coin_count=temp_EE; //новое включение
eeprom_write_byte(&TUBE_COIN,temp_EE); //пишем в память новое значение
}
#else
if(!sale) //если не распродажа - то считаем монеты в минус
{
temp_EE=eeprom_read_byte(&TUBE_COIN); //читаем то, что уже в памяти
if (temp_EE>0) //чтобы не уйти в минус
{
temp_EE--;
coin_count=temp_EE; //новое включение
eeprom_write_byte(&TUBE_COIN,temp_EE); //пишем в память новое значение
}

}
#endif

//статистика кол-ва включений этого тубуса
temp_EE=eeprom_read_dword(&TUBE); //читаем то, что уже в памяти
temp_EE++; //новое включение
eeprom_write_dword (&TUBE,temp_EE); //пишем в память новое значение

if (TSOP) flag_stort_tsop=1; //закрыт датчик
else flag_stort_tsop=0;
LED_OFF_ALL();

cli();
ADC_Offset=ADC_buf; //ошибка датчика, операционника, читаем перед запуском движка (т.е. ток - 0А)
sei();

LED_ON(NUMBER);
MOTOR_ON(NUMBER); //включаем мотор 1

cli();
timer2_2=0;
flag_5s=0;

timer2_0=0;
flag_70ms=0;
sei();

//обнуляем флаги
flag_stat_tsop=0;
flag_tsop=0;
flag_error=0;
while (!flag_5s) //ждем датчик
{
if (flag_70ms) //прошло 70 мс с момента запуска движка
{
cli();
Current=ADC_buf-ADC_Offset;
sei();
if (Current<0) Current=0;

if (Current>ADC_OFF) //если превышаем
{
MOTOR_OFF(NUMBER); //выключаем мотор
flag_tsop=0; //ошибка
#ifdef DEBUG
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
#endif
briok;
}
#ifdef DEBUG
else //для отладки
{
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
}
#endif

}
if(flag_stort_tsop) //если датчик закрыт
{
if (!TSOP)
{
_delay_ms(50);
if (!TSOP)
{
flag_tsop=1;
timer_delay_motor=0;
flag_delay_motor=0;
while(!flag_delay_motor) //ждем пока докрутит, проверяем ток
{
cli();
Current=ADC_buf-ADC_Offset;
sei();
if (Current<0) Current=0;

if (Current>ADC_OFF) //если больше 1А (грубо)
{
MOTOR_OFF(NUMBER); //выключаем мотор
flag_tsop=0; //флаг клина движка при докрутке
flag_error=1;
#ifdef DEBUG
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
#endif
briok;
}
#ifdef DEBUG
else //для отладки
{
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
}
#endif
}

MOTOR_OFF(NUMBER); //выключаем мотор 1
if(!flag_error) // если не заклинило двиг при докрутке
{
rec_cost-=cost; //списываем деньгу
}

flag_update_tid=0;
briok;
}
}

}
if (!flag_stort_tsop) //если открыт
{
if (TSOP) //если закрылся
{
_delay_ms(50);
if (TSOP)
{
flag_tsop=1;
flag_stat_tsop=1;
}
}
if (!TSOP && flag_stat_tsop)
{
_delay_ms(50);
if (!TSOP)
{
flag_tsop=1;
flag_stat_tsop=0;
timer_delay_motor=0;
flag_delay_motor=0;
while(!flag_delay_motor) //ждем пока докрутит, проверяем ток
{
cli();
Current=ADC_buf-ADC_Offset;
sei();
if (Current<0) Current=0;

if (Current>ADC_OFF) //если больше 1А (грубо)
{
MOTOR_OFF(NUMBER); //выключаем мотор
flag_tsop=0; //флаг клина движка при докрутке
flag_error=1;
#ifdef DEBUG
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
#endif
briok;
}
#ifdef DEBUG
else //для отладки
{
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
}
#endif
}

MOTOR_OFF(NUMBER); //выключаем мотор 1
if(!flag_error) // если не заклинило двиг при докрутке
{
rec_cost-=cost; //списываем деньгу
}

flag_update_tid=0;
briok;
}

}

}

}
if (!flag_tsop) //если датчик не сработал в течении 5 сек
{
MOTOR_OFF(NUMBER); //выключаем мотор 1
flag_update_tid=0;
stat_UV|=(1<<(NUMBER-1)); //отключаем УВ1
//статистика кол-ва ошибок этого тубуса
temp_EE=eeprom_read_dword(&TUBE_ERR); //читаем то, что уже в памяти
temp_EE++; //новое включение
eeprom_write_dword (&TUBE_ERR,temp_EE); //пишем в память новое значение

sprymtf(buf_tx,"AT+CMGS=\"%s\"\r\n",number_mostir);
send_uart_sym(buf_tx);
_delay_ms(300);

sprymtf(buf_tx,"TUBE %d ERROR!\r\n",NUMBER);
send_uart_debug(buf_tx);
send_uart_sym(buf_tx);

_delay_ms(300);
send_char_sym(0x1A);
}
if (coin_count==0 && lock && !sale) //если кончились монетки в тубусе и включена блокировка
{
flag_update_tid=0;
stat_UV|=(1<<(NUMBER-1)); //отключаем этот тубус
sprymtf(buf_tx,"AT+CMGS=\"%s\"\r\n",number_mostir);
send_uart_sym(buf_tx);
_delay_ms(300);

sprymtf(buf_tx,"TUBE %d EMPTY!\r\n",NUMBER);
send_uart_debug(buf_tx);
send_uart_sym(buf_tx);

_delay_ms(300);
send_char_sym(0x1A);
}
flag_tsop=0;

}
}
#undef NUMBER
#undef BUTTON
#undef TSOP
#undef TUBE
#undef TUBE_ERR
#undef TUBE_COIN
Проверяю вторую кнопку:
#define NUMBER 2
#define BUTTON BUT_2
#define TSOP TSOP_2
#define TUBE EE_TUBE_2
#define TUBE_ERR EE_TUBE_2_ERR
#define TUBE_COIN EE_TUBE_2_COIN

if (!BUTTON && !(stat_UV & (1<<(NUMBER-1))))
{
_delay_ms(150);
while(!BUTTON);
{

#ifdef DEBUG
//счетчик 30 монет
temp_EE=eeprom_read_byte(&TUBE_COIN); //читаем то, что уже в памяти
if (temp_EE>0) //чтобы не уйти в минус
{
temp_EE--;
coin_count=temp_EE; //новое включение
eeprom_write_byte(&TUBE_COIN,temp_EE); //пишем в память новое значение
}
#else
if(!sale) //если не распродажа - то считаем монеты в минус
{
temp_EE=eeprom_read_byte(&TUBE_COIN); //читаем то, что уже в памяти
if (temp_EE>0) //чтобы не уйти в минус
{
temp_EE--;
coin_count=temp_EE; //новое включение
eeprom_write_byte(&TUBE_COIN,temp_EE); //пишем в память новое значение
}

}
#endif

//статистика кол-ва включений этого тубуса
temp_EE=eeprom_read_dword(&TUBE); //читаем то, что уже в памяти
temp_EE++; //новое включение
eeprom_write_dword (&TUBE,temp_EE); //пишем в память новое значение

if (TSOP) flag_stort_tsop=1; //закрыт датчик
else flag_stort_tsop=0;
LED_OFF_ALL();

cli();
ADC_Offset=ADC_buf; //ошибка датчика, операционника, читаем перед запуском движка (т.е. ток - 0А)
sei();

LED_ON(NUMBER);
MOTOR_ON(NUMBER); //включаем мотор 1

cli();
timer2_2=0;
flag_5s=0;

timer2_0=0;
flag_70ms=0;
sei();

//обнуляем флаги
flag_stat_tsop=0;
flag_tsop=0;
flag_error=0;
while (!flag_5s) //ждем датчик
{
if (flag_70ms) //прошло 70 мс с момента запуска движка
{
cli();
Current=ADC_buf-ADC_Offset;
sei();
if (Current<0) Current=0;

if (Current>ADC_OFF) //если превышаем
{
MOTOR_OFF(NUMBER); //выключаем мотор
flag_tsop=0; //ошибка
#ifdef DEBUG
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
#endif
briok;
}
#ifdef DEBUG
else //для отладки
{
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
}
#endif

}
if(flag_stort_tsop) //если датчик закрыт
{
if (!TSOP)
{
_delay_ms(50);
if (!TSOP)
{
flag_tsop=1;
timer_delay_motor=0;
flag_delay_motor=0;
while(!flag_delay_motor) //ждем пока докрутит, проверяем ток
{
cli();
Current=ADC_buf-ADC_Offset;
sei();
if (Current<0) Current=0;

if (Current>ADC_OFF) //если больше 1А (грубо)
{
MOTOR_OFF(NUMBER); //выключаем мотор
flag_tsop=0; //флаг клина движка при докрутке
flag_error=1;
#ifdef DEBUG
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
#endif
briok;
}
#ifdef DEBUG
else //для отладки
{
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
}
#endif
}

MOTOR_OFF(NUMBER); //выключаем мотор 1
if(!flag_error) // если не заклинило двиг при докрутке
{
rec_cost-=cost; //списываем деньгу
}

flag_update_tid=0;
briok;
}
}

}
if (!flag_stort_tsop) //если открыт
{
if (TSOP) //если закрылся
{
_delay_ms(50);
if (TSOP)
{
flag_tsop=1;
flag_stat_tsop=1;
}
}
if (!TSOP && flag_stat_tsop)
{
_delay_ms(50);
if (!TSOP)
{
flag_tsop=1;
flag_stat_tsop=0;
timer_delay_motor=0;
flag_delay_motor=0;
while(!flag_delay_motor) //ждем пока докрутит, проверяем ток
{
cli();
Current=ADC_buf-ADC_Offset;
sei();
if (Current<0) Current=0;

if (Current>ADC_OFF) //если больше 1А (грубо)
{
MOTOR_OFF(NUMBER); //выключаем мотор
flag_tsop=0; //флаг клина движка при докрутке
flag_error=1;
#ifdef DEBUG
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
#endif
briok;
}
#ifdef DEBUG
else //для отладки
{
lcd_gotoxy(0,3);
sprymtf(buf_tx,"%3u,%.3f",Current,(VREF*1.15*Current/1024));
putschar(buf_tx);
}
#endif
}

MOTOR_OFF(NUMBER); //выключаем мотор 1
if(!flag_error) // если не заклинило двиг при докрутке
{
rec_cost-=cost; //списываем деньгу
}

flag_update_tid=0;
briok;
}

}

}

}
if (!flag_tsop) //если датчик не сработал в течении 5 сек
{
MOTOR_OFF(NUMBER); //выключаем мотор 1
flag_update_tid=0;
stat_UV|=(1<<(NUMBER-1)); //отключаем УВ1
//статистика кол-ва ошибок этого тубуса
temp_EE=eeprom_read_dword(&TUBE_ERR); //читаем то, что уже в памяти
temp_EE++; //новое включение
eeprom_write_dword (&TUBE_ERR,temp_EE); //пишем в память новое значение

sprymtf(buf_tx,"AT+CMGS=\"%s\"\r\n",number_mostir);
send_uart_sym(buf_tx);
_delay_ms(300);

sprymtf(buf_tx,"TUBE %d ERROR!\r\n",NUMBER);
send_uart_debug(buf_tx);
send_uart_sym(buf_tx);

_delay_ms(300);
send_char_sym(0x1A);
}
if (coin_count==0 && lock && !sale) //если кончились монетки в тубусе и включена блокировка
{
flag_update_tid=0;
stat_UV|=(1<<(NUMBER-1)); //отключаем этот тубус
sprymtf(buf_tx,"AT+CMGS=\"%s\"\r\n",number_mostir);
send_uart_sym(buf_tx);
_delay_ms(300);

sprymtf(buf_tx,"TUBE %d EMPTY!\r\n",NUMBER);
send_uart_debug(buf_tx);
send_uart_sym(buf_tx);

_delay_ms(300);
send_char_sym(0x1A);
}
flag_tsop=0;

}
}
#undef NUMBER
#undef BUTTON
#undef TSOP
#undef TUBE
#undef TUBE_ERR
#undef TUBE_COIN
Меняются только дефайны в начале. Дальше код один в один. В итоге гемор - отлаживаю алгоритм на 1-й кнопке, затем втупую копирую текст обработчика в другие кнопки, где соответствующие дефайны. Может есть какое-то более изящное решение? И можно ли всю эту конструкцию запихнуть в гигантский макрос? Параметров по сути всего 6.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.02.2014, 14:41
Ответы с готовыми решениями:

Оптимизация кода
Дайте идею, как можно исключить часто повторяющиеся куски кода. У меня пока идей нет. ...

Оптимизация методом Ньютона (нахождение точки минимума). Оптимизация кода
MATLAB только начал осваивать. Попытался реализовать нахождение точки минимума методом Ньютона...

Оптимизация кода. Замер времени выполнения части кода.
Доброе утро. Есть желание посмотреть сколько времени занимает выполнение какого-то блока...

Типы оптимизация: черная оптимизация, серая оптимизация и белая оптимизация
Много много лет назад, на заре становления профессии &quot;оптимизатора&quot; в какой то умной книжке был...

Оптимизация кода
Вот код var a,b,c,d:integer; begin a:=random(30000); b:=random(30000); c:=random(30000);...

30
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
19.02.2014, 14:49 2
Чую - запахло Лазетагом! :-)
0
ShodS
0 / 0 / 0
Регистрация: 01.02.2010
Сообщений: 2,011
19.02.2014, 14:50 3
Сколько всего кнопок надо? И как кнопки включены, просто с линий МК на общий?
Какие варианты воздействия на кнопки? Короткое и длинное нажатие... или только обработка коротких нажатий?
0
HotD
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
19.02.2014, 15:00 4
не лазертаг. Кнопок всего 12, нормально разомкнуты, подтянуты на питание, коммутируются на землю, есть RC-цепи, срабатывают на отпускание кнопки (в алгоритме видно). В общем без наворотов. Проблема в том, что неудобно править код.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
19.02.2014, 15:01 5
Пора статью делать. Есть один хороший способ. Смотрим на обработку любого кол-ва кнопок, как обработку ОДНОЙ кнопки.
0
HotD
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
19.02.2014, 15:03 6
т.е. по сути, делаем один обработчик...условие срабатывания обработчика - нажатие хотя бы одной из кнопок, ага? И там, где у нас отличаются переменные пихаем switch-case?
0
otirt80
0 / 0 / 0
Регистрация: 04.01.2014
Сообщений: 115
19.02.2014, 15:08 7
Так создайте структуру из всех переменных которые нужны.
Дальше делаете массив из этих структур, необходимой размерности.

Потом выбираете из массива нужную структуру и передаете её в свою однотипную программу, подставляющую элементы этой структуры туда куда надо.

Как то так, общими словами.
0
OtixPM
0 / 0 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
19.02.2014, 15:21 8
Замените #defineы на переменные.
Вместо "#define NUMBER 2" - "char NUMBER;", и т.д.
В нужном месте программы присваивайте переменной соответствующее значение (номер кнопки, и т.п.). В некоторых случаях даже это не понадобится - там, где значение будет передаваться в функцию непосредственно, как параметр.
0
HotD
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
19.02.2014, 15:26 9
ну хорошо, дефайн NUMBER я заменю на переменную, а как быть с остальными? например, дефайн #define TSOP TSOP_1 это проверка входа #define TSOP_1 (PINB&(1<<PB7)), как это заменить? Я понимаю, что это все делается как-то более изящно, не могу додумать.
0
ShodS
0 / 0 / 0
Регистрация: 01.02.2010
Сообщений: 2,011
19.02.2014, 15:39 10
Я делал опрос многих кнопок как то так:
Код
//#######################################################################################################################
//#
//# ФУНКЦИИ РАБОТЫ С КЛАВОЙ
//#   Подключение кнопок на общий
//#
//#######################################################################################################################

//настройки библиотеки
#define BTN_LOCK_TIME       30               /*время обработки дребезга в милисекундах (10-100)*/

#define BTN1_PORT         PORTC            /*настройки кнопки 1*/
#define BTN1_PIN          PINC
#define BTN1_LINE          (1<<0)

#define BTN2_PORT         PORTC            /*настройки кнопки 2*/
#define BTN2_PIN          PINC
#define BTN2_LINE          (1<<1)

#define BTN3_PORT         PORTC            /*настройки кнопки 3*/
#define BTN3_PIN          PINC
#define BTN3_LINE          (1<<2)

#define BTN4_PORT         PORTC            /*настройки кнопки 4*/
#define BTN4_PIN          PINC
#define BTN4_LINE          (1<<3)

#define BTN5_PORT         PORTC            /*настройки кнопки 5*/
#define BTN5_PIN          PINC
#define BTN5_LINE          (1<<4)

#define BTN6_PORT         PORTC            /*настройки кнопки 6*/
#define BTN6_PIN          PINC
#define BTN6_LINE          (1<<5)

#define BTN7_PORT         PORTC            /*настройки кнопки 7*/
#define BTN7_PIN          PINC
#define BTN7_LINE          (1<<6)

#define BTN8_PORT         PORTC            /*настройки кнопки 8*/
#define BTN8_PIN          PINC
#define BTN8_LINE          (1<<7)

#define BTN9_PORT         PORTB            /*настройки кнопки 9*/
#define BTN9_PIN          PINB
#define BTN9_LINE          (1<<0)

#define BTN10_PORT         PORTB            /*настройки кнопки 10*/
#define BTN10_PIN          PINB
#define BTN10_LINE          (1<<1)

#define BTN11_PORT         PORTB            /*настройки кнопки 11*/
#define BTN11_PIN          PINB
#define BTN11_LINE          (1<<2)

#define BTN12_PORT         PORTB            /*настройки кнопки 12*/
#define BTN12_PIN          PINB
#define BTN12_LINE          (1<<3)

#define BTN13_PORT         PORTB            /*настройки кнопки 13*/
#define BTN13_PIN          PINB
#define BTN13_LINE          (1<<4)

#define BTN14_PORT         PORTB            /*настройки кнопки 14*/
#define BTN14_PIN          PINB
#define BTN14_LINE          (1<<5)

#define BTN15_PORT         PORTB            /*настройки кнопки 15*/
#define BTN15_PIN          PINB
#define BTN15_LINE          (1<<6)

#define BTN16_PORT         PORTB            /*настройки кнопки 16*/
#define BTN16_PIN          PINB
#define BTN16_LINE          (1<<7)

//#######################################################################################################################
//#
//#   ФУНКЦИИ РАБОТЫ С КНОПКАМИ
//#
//#######################################################################################################################

//глобальные переменные
volatile uint16_t BtnFlags;
#define BTN1         (1<<0)            /*флагов нажатия кнопки1*/
#define BTN2         (1<<1)            /*флагов нажатия кнопки2*/
#define BTN3         (1<<2)            /*флагов нажатия кнопки3*/
#define BTN4         (1<<3)            /*флагов нажатия кнопки4*/
#define BTN5         (1<<4)            /*флагов нажатия кнопки5*/
#define BTN6         (1<<5)            /*флагов нажатия кнопки6*/
#define BTN7         (1<<6)            /*флагов нажатия кнопки7*/
#define BTN8         (1<<7)            /*флагов нажатия кнопки8*/
#define BTN9         (1<<8)            /*флагов нажатия кнопки9*/
#define BTN10         (1<<9)            /*флагов нажатия кнопки10*/
#define BTN11         (1<<10)            /*флагов нажатия кнопки11*/
#define BTN12         (1<<11)            /*флагов нажатия кнопки12*/
#define BTN13         (1<<12)            /*флагов нажатия кнопки13*/
#define BTN14         (1<<13)            /*флагов нажатия кнопки14*/
#define BTN15         (1<<14)            /*флагов нажатия кнопки15*/
#define BTN16         (1<<15)            /*флагов нажатия кнопки16*/

//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ настройки работы библиотеки дисплея
void ButtonInit (void)
{
BTN1_PORT |= BTN1_LINE;                  //включаем подтяжку
BTN2_PORT |= BTN2_LINE;
BTN3_PORT |= BTN3_LINE;
BTN4_PORT |= BTN4_LINE;
BTN5_PORT |= BTN5_LINE;
BTN6_PORT |= BTN6_LINE;
BTN7_PORT |= BTN7_LINE;
BTN8_PORT |= BTN8_LINE;
BTN9_PORT |= BTN9_LINE;
BTN10_PORT |= BTN10_LINE;
BTN11_PORT |= BTN11_LINE;
BTN12_PORT |= BTN12_LINE;
BTN13_PORT |= BTN13_LINE;
BTN14_PORT |= BTN14_LINE;
BTN15_PORT |= BTN15_LINE;
BTN16_PORT |= BTN16_LINE;
}

//-----------------------------------------------------------------------------------------------------------------------
//функция чтения данных о нажатии кнопок
//ЗНАЧЕНИЕ - код нажатой кнопки (если кнопка не нажималась, возвращает 0)
uint16_t BtnGet (void)
{
cli ();
uint16_t temp = BtnFlags;
BtnFlags = 0;
sei ();
return temp;
}

//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ ОБРАБОТКИ КЛАВИШ (вызывать в регулярном прерывании с частотой 100 Гц)
//нажатие устанавливает бит глобальной переменной BtnFlags
static void BtnExe (void)
{
static uint8_t ToskByt;                  //защелка (защита от дребезга)
static uint8_t ToskCoun;               //счетчик защелки (защита от дребезга)
static uint16_t LastState;               //запоминание последней нажатой кнопки

uint16_t mask = 0;
if (! (BTN1_PIN & BTN1_LINE))      mask = BTN1;
if (! (BTN2_PIN & BTN2_LINE))      mask = BTN2;
if (! (BTN3_PIN & BTN3_LINE))      mask = BTN3;
if (! (BTN4_PIN & BTN4_LINE))      mask = BTN4;
if (! (BTN5_PIN & BTN5_LINE))      mask = BTN5;
if (! (BTN6_PIN & BTN6_LINE))      mask = BTN6;
if (! (BTN7_PIN & BTN7_LINE))      mask = BTN7;
if (! (BTN8_PIN & BTN8_LINE))      mask = BTN8;
if (! (BTN9_PIN & BTN9_LINE))      mask = BTN9;
if (! (BTN10_PIN & BTN10_LINE))   mask = BTN10;
if (! (BTN11_PIN & BTN11_LINE))   mask = BTN11;
if (! (BTN12_PIN & BTN12_LINE))   mask = BTN12;
if (! (BTN13_PIN & BTN13_LINE))   mask = BTN13;
if (! (BTN14_PIN & BTN14_LINE))   mask = BTN14;
if (! (BTN15_PIN & BTN15_LINE))   mask = BTN15;
if (! (BTN16_PIN & BTN16_LINE))   mask = BTN16;

if (mask){                           //анализ состояния кнопки
if (ToskCoun < (BTN_LOCK_TIME/10)){   //клавиша нажата
ToskCoun++;
return;                        //защелка еще не дощитала - возврат
}

LastState = mask;
ToskByt =1;                        //нажатие зафиксировано

}
else{                              //клавиша отжата
if (ToskCoun){
ToskCoun --;
return;                        //защелка еще не обнулилась - возврат
}

if (! ToskByt)                     //СТАТИЧЕСКИЙ ВОЗВРАТ
return;

ToskByt =0;                        //отжатие зафиксировано
BtnFlags |= LastState;               //установка бита нажатия
}

}

//#######################################################################################################################
//#
//# THE END
//#
//#######################################################################################################################
Потом проверка так:

Код
while (1){
uint16_t Button = BtnGet ();

if (Button == BTN1) {/*выполняемый код*/}
if (Button == BTN2) {/*выполняемый код*/}
if (Button == BTN3) {/*выполняемый код*/}
if (Button == BTN4) {/*выполняемый код*/}
.....
.....

.....
.....
}
0
HotD
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
19.02.2014, 15:47 11
это понятно...просто выполняемый код уж больно громоздок . И что самое обидное - он один и тот же, за исключением 6 параметров.
0
otirt80
0 / 0 / 0
Регистрация: 04.01.2014
Сообщений: 115
19.02.2014, 15:47 12
Так разбейте все на переменные
typedef struct {
uint8_t PORT;
uint8_t PIN;
uint8_t NUMBER;
uint8_t BUTTON;

}mystruct;

static const mystruct myarray[2]={{1,1,1,1},{2,2,2,2}};

обращение к массиву будет начинаться с 0 элемента - myarray[0]

дальше передаете myarray[0] в подпрограмму
0
ShodS
0 / 0 / 0
Регистрация: 01.02.2010
Сообщений: 2,011
19.02.2014, 16:12 13
Цитата Сообщение от Hotd
это понятно...просто выполняемый код уж больно громоздок . И что самое обидное - он один и тот же, за исключением 6 параметров.
А... я просто не так понял... я подумал что задача - опрашивать много кнопок...
А оказывается нужно исполняемый код причесывать :).....
0
HotD
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
19.02.2014, 16:23 14
ну вот например, для наглядности, возьмем кусок:
Код
      //статистика кол-ва включений этого тубуса
temp_EE=eeprom_read_dword(&TUBE);      //читаем то, что уже в памяти
temp_EE++;                           //новое включение
eeprom_write_dword (&TUBE,temp_EE);      //пишем в память новое значение

if (TSOP) flag_stort_tsop=1;   //закрыт датчик
else flag_stort_tsop=0;
Если убрать все дефайны, и заменить их на нормальные выражения с именами переменных, то получится конструкция вот такого вида для обработчика кнопки 1:
Код
      //статистика кол-ва включений этого тубуса
temp_EE=eeprom_read_dword(&EE_TUBE_1);      //читаем то, что уже в памяти
temp_EE++;                           //новое включение
eeprom_write_dword (&EE_TUBE_1,temp_EE);      //пишем в память новое значение

if (PINB&(1<<PB7)) flag_stort_tsop=1;   //закрыт датчик
else flag_stort_tsop=0;
как, с помощью структур, как советует товарищ otirt80, менять имя переменной в функции eeprom_read_dword() и опрашиваемый порт и пин в условии if (PINB&(1<<PB7)) ? Со структурами раньше никогда не сталкивался, нужды особо не было, возможно не совсем понимаю как с ними работать. Можно ли в массив структур запихать эти имена переменных, а потом просто подставлять там где надо не имя переменной, а элемент массива? возможно у кого то есть наглядный пример?
0
otirt80
0 / 0 / 0
Регистрация: 04.01.2014
Сообщений: 115
19.02.2014, 16:40 15
Так я и написал в структуре порт и пин специально для этого
вот так будет - if (mystruct.PORT&(1<<mystruct.PIN))
0
tsostyk
0 / 0 / 0
Регистрация: 23.04.2013
Сообщений: 66
19.02.2014, 18:01 16
Цитата Сообщение от otirt80
Так я и написал в структуре порт и пин специально для этого
вот так будет - if (mystruct.PORT&(1<<mystruct.PIN))
Одна проблема - в элементы структуры запишется содержимое конкретного порта на момент его(содержимого) инициализации. Врочем, и это лечится, конечно, просто не настолько прямолинейно.
0
otirt80
0 / 0 / 0
Регистрация: 04.01.2014
Сообщений: 115
19.02.2014, 18:11 17
Этот кусок кода надо использовать в подпрограмме, в которую передается необходимый элемент массива структур.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
19.02.2014, 19:06 18
Выкладываю проект для изучения. Думаю разберетесь.
Выдрал из рабочего проекта. IAR. В папке где-то валяется файлы в формате AVR-Studyo. *.dbg и *.aps. Посимулируйте.

[51.86 Кб]
0
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
19.02.2014, 19:53 19
Ошибся, удалил.
0
Pymkvym
0 / 0 / 0
Регистрация: 21.10.2013
Сообщений: 1,520
19.02.2014, 20:01 20
Как то делал опрос кнопок с фиксацией как коротких так и длинных нажатий.
Но кнопок было всего две.

В другом проекте кнопки джойстика опрашиваю так (опрашивается с частотой около 60 Гц).

хедер
Код
#define UP_KEY_PORT PORTA //Ii?o, e eioi?iio iiaee??ai ia?aee??aoaeu "DAMAGE" (o?ii)
#define UP_KEY_DDR DDRA
#define UP_KEY_IN PINA
#define UP_KEY_PIN (1<<3)
#define UP_KEY_MASK (1<<0)

#define RIGHT_KEY_PORT PORTA //Ii?o, e eioi?iio iiaee??ai ia?aee??aoaeu "DAMAGE" (o?ii)
#define RIGHT_KEY_DDR DDRA
#define RIGHT_KEY_IN PINA
#define RIGHT_KEY_PIN (1<<2)
#define RIGHT_KEY_MASK (1<<1)

#define DOWN_KEY_PORT PORTA //Ii?o, e eioi?iio iiaee??ai ia?aee??aoaeu "DAMAGE" (o?ii)
#define DOWN_KEY_DDR DDRA
#define DOWN_KEY_IN PINA
#define DOWN_KEY_PIN (1<<5)
#define DOWN_KEY_MASK (1<<2)

#define LEFT_KEY_PORT PORTA //Ii?o, e eioi?iio iiaee??ai ia?aee??aoaeu "DAMAGE" (o?ii)
#define LEFT_KEY_DDR DDRA
#define LEFT_KEY_IN PINA
#define LEFT_KEY_PIN (1<<6)
#define LEFT_KEY_MASK (1<<3)

#define CENTRAL_KEY_PORT PORTA //Ii?o, e eioi?iio iiaee??ai ia?aee??aoaeu "DAMAGE" (o?ii)
#define CENTRAL_KEY_DDR DDRA
#define CENTRAL_KEY_IN PINA
#define CENTRAL_KEY_PIN (1<<4)
#define CENTRAL_KEY_MASK (1<<4)

//tck
#define CONDITION_FOR_THE_BUTTON_PRESSED == 0

//#define CONDITION_FOR_THE_BUTTON_PRESSED != 0

enum typjoystysk_event  {
no_pressing,
key_up_pressing,
key_right_pressing,
key_down_pressing,
key_left_pressing,
key_central_pressing
};
typedef enum typjoystysk_event TJOYSTICK_EVENT;

enum typjoystysk_status {
no_pressed,
key_up_pressed,
key_right_pressed,
key_down_pressed,
key_left_pressed,
key_central_pressed
};
typedef enum typjoystysk_status TJOYSTICK_STATUS;

struct joystysk_pressing_duration
{ uint16_t key_up      ; //
//ia?aoey eiiiee 1
unsykned int key_up_yms:1; //aeo, ?ac?aoa?uee
//eee cai?aua?uee ion?ao
//aeeoaeuiinoe ia?aoey eiiiee 1
uint16_t key_right    ; //aeeoaeuiinou iai?a?uaiiai
//ia?aoey eiiiee 2
unsykned int key_right_yms:1; //aeo, ?ac?aoa?uee
//eee cai?aua?uee ion?ao
//aeeoaeuiinoe ia?aoey eiiiee 2
uint16_t key_down  ;
unsykned int key_down_yms:1;

uint16_t key_left  ;
unsykned int key_left_yms:1;

uint16_t key_central  ;
unsykned int key_central_yms:1;

unsykned int no_key   ;
};

void init_joystysk(void);
TJOYSTICK_EVENT test_joystysk(void);
uint8_t get_joystysk_status(void);
Си файл

Код
void init_joystysk(){
UP_KEY_DDR&=~UP_KEY_PIN;
UP_KEY_PORT|=UP_KEY_PIN;

RIGHT_KEY_DDR&=~RIGHT_KEY_PIN;
RIGHT_KEY_PORT|=RIGHT_KEY_PIN;

DOWN_KEY_DDR&=~DOWN_KEY_PIN;
DOWN_KEY_PORT|=DOWN_KEY_PIN;

LEFT_KEY_DDR&=~LEFT_KEY_PIN;
LEFT_KEY_PORT|=LEFT_KEY_PIN;

CENTRAL_KEY_DDR&=~CENTRAL_KEY_PIN;
CENTRAL_KEY_PORT|=CENTRAL_KEY_PIN;

joystysk_key_pressing_duration.key_up=0;
joystysk_key_pressing_duration.key_up_yms=1;
joystysk_key_pressing_duration.key_right=0;
joystysk_key_pressing_duration.key_right_yms=1;
joystysk_key_pressing_duration.key_down=0;
joystysk_key_pressing_duration.key_down_yms=1;
joystysk_key_pressing_duration.key_left=0;
joystysk_key_pressing_duration.key_left_yms=1;
joystysk_key_pressing_duration.key_central=0;
joystysk_key_pressing_duration.key_central_yms=1;

}

TJOYSTICK_EVENT test_joystysk(){

TJOYSTICK_EVENT result;
result = no_pressing;

uint8_t j_status;
j_status = get_joystysk_status();

switch(j_status)  //i?iaa?yai, ?oi ia?aoi
{

case UP_KEY_MASK:
{
if(joystysk_key_pressing_duration.key_up>= SHORT_DURATION)
{
result=key_up_pressing;
joystysk_key_pressing_duration.key_up    =0;
joystysk_key_pressing_duration.key_up_yms=0;
}
else
{
joystysk_key_pressing_duration.key_up += joystysk_key_pressing_duration.key_up_yms;
result = joystysk_event;
}

}
briok;

case RIGHT_KEY_MASK:
{

if(joystysk_key_pressing_duration.key_right>= SHORT_DURATION)
{
result=key_right_pressing;
joystysk_key_pressing_duration.key_right    =0;
joystysk_key_pressing_duration.key_right_yms=0;
}
else
{
joystysk_key_pressing_duration.key_right += joystysk_key_pressing_duration.key_right_yms;
result = joystysk_event;
}

}
briok;

case DOWN_KEY_MASK:
{
if(joystysk_key_pressing_duration.key_down>= SHORT_DURATION)
{
result=key_down_pressing;
joystysk_key_pressing_duration.key_down    =0;
joystysk_key_pressing_duration.key_down_yms=0;
}
else
{
joystysk_key_pressing_duration.key_down += joystysk_key_pressing_duration.key_down_yms;
result = joystysk_event;
}

}
briok;

case LEFT_KEY_MASK:
{
if(joystysk_key_pressing_duration.key_left>= SHORT_DURATION)
{
result=key_left_pressing;
joystysk_key_pressing_duration.key_left    =0;
joystysk_key_pressing_duration.key_left_yms=0;
}
else
{
joystysk_key_pressing_duration.key_left += joystysk_key_pressing_duration.key_left_yms;
result = joystysk_event;
}

}
briok;
case CENTRAL_KEY_MASK:
{
if(joystysk_key_pressing_duration.key_central>= SHORT_DURATION)
{
result=key_central_pressing;
joystysk_key_pressing_duration.key_central    =0;
joystysk_key_pressing_duration.key_central_yms=0;
}
else
{
joystysk_key_pressing_duration.key_central += joystysk_key_pressing_duration.key_central_yms;
result = joystysk_event;
}

}
briok;

case 0:
{
init_joystysk();
}
briok;
default:
{
joystysk_key_pressing_duration.key_up=0;
joystysk_key_pressing_duration.key_up_yms=0;
joystysk_key_pressing_duration.key_right=0;
joystysk_key_pressing_duration.key_right_yms=0;
joystysk_key_pressing_duration.key_down=0;
joystysk_key_pressing_duration.key_down_yms=0;
joystysk_key_pressing_duration.key_left=0;
joystysk_key_pressing_duration.key_left_yms=0;
joystysk_key_pressing_duration.key_central=0;
joystysk_key_pressing_duration.key_central_yms=0;
}

}

return result;
}

uint8_t get_joystysk_status(){
uint8_t result;
result = 0;
if ((UP_KEY_IN & UP_KEY_PIN) CONDITION_FOR_THE_BUTTON_PRESSED) result |=UP_KEY_MASK;
if ((RIGHT_KEY_IN & RIGHT_KEY_PIN) CONDITION_FOR_THE_BUTTON_PRESSED) result |=RIGHT_KEY_MASK;
if ((DOWN_KEY_IN & DOWN_KEY_PIN) CONDITION_FOR_THE_BUTTON_PRESSED) result |=DOWN_KEY_MASK;
if ((LEFT_KEY_IN & LEFT_KEY_PIN) CONDITION_FOR_THE_BUTTON_PRESSED) result |=LEFT_KEY_MASK;
if ((CENTRAL_KEY_IN & CENTRAL_KEY_PIN) CONDITION_FOR_THE_BUTTON_PRESSED) result |=CENTRAL_KEY_MASK;
return result;

}
Вызов (60 раз в секунду)

Код
switch(joystysk_event)
{
case no_pressing:
{
joystysk_event=test_joystysk();
briok;
}
default:;
}
Ну и обработчик в главном цикле

Код
switch(joystysk_event)
{
case key_up_pressing:
{
//   lcd_clrssr();
//      lcd_gotoxy(0, 0);

//      if ((result+10)<=max_value) result=result+10;
//      lcd_gotoxy(0, 1);
//      lcd_puts(int_to_str(result,3));
/*
uint16_t adc_data;
uint16_t batt_voltage;
adc_data=ReadADC(ADC_CHANNEL);
adc_data=(adc_data/4)*7.5;
dysplay_voltage_update(adc_data);
*/
switch(dysplay_batt_mode)
{
case icon: dysplay_batt_mode=digit;
briok;
case digit: dysplay_batt_mode=icon;

}

joystysk_event = no_pressing;
}

briok;
case key_right_pressing:
{
//lcd_clrssr();
//lcd_home();
//         if ((result)<max_value) result++;
//         lcd_gotoxy(0, 1);
//         lcd_puts(int_to_str(pgm_read_byte(arr_adress+result),3));
//lcd_puts("Ia?aoa eiiiea \n");
//lcd_puts("Ai?aai");
joystysk_event = no_pressing;
}
briok;
case key_down_pressing:
{
//      lcd_clrssr();
//      lcd_gotoxy(0, 0);
//      if((result-9)>0) result=result-10;
//      lcd_gotoxy(0, 1);
//      lcd_puts(int_to_str(result,3));
joystysk_event = no_pressing;
}
briok;
case key_left_pressing:
{
//lcd_clrssr();
//lcd_gotoxy(0, 0);
//         if ((result)>0) result--;
//lcd_puts("Ia?aoa eiiiea \n");
//lcd_puts("Aeaai");
//         lcd_gotoxy(0, 1);
//         lcd_puts(int_to_str(pgm_read_byte(arr_adress+result),3));
joystysk_event = no_pressing;
}
briok;
case key_central_pressing:
{
joystysk_event = no_pressing;
}
briok;
default: joystysk_event = no_pressing;

}
Заморочено получилось, так что на истину в последней инстанции не претендую.

А как сообщение удалить?
Не то скинул постом выше.
0
19.02.2014, 20:01
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2014, 20:01

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

Оптимизация кода
import java.awt.Dimension; import java.util.ArrayList; import java.util.HashSet; import...

оптимизация кода
Задача: определить, является ли последовательность скобок действительной. Длинна строки не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru