Оптимизация кода С++
May. 6th, 2015 01:11 pm----------------------------------------------------------------
unsigned long old_time = 0; // переменная для измерения времени удержания кнопки
boolean Button = 1; // флаг состояния кнопки
void setup() {
DDRD |= (3 << 3); // переключаем выводы PD3 и PD4 в режим "выход"
}
void loop() {
boolean butt = PIND & (1 << 5); // проверяем состояние кнопки
if ((butt == 0) && (Button == 1)) { // если кнопка нажата и до этого была не нажата
Button = 0; // устанавливаем флаг нажатия кнопки
old_time = millis(); // фиксируем время нажатия кнопки
}
if ((butt != 0) && (Button == 0)) { // если кнопка не нажата, а раньше была нажата, то
old_time = millis() - old_time; // вычисляем время, сколько была нажата кнопка
if ((old_time >10) && (old_time < 300)) { // если время нажатия было менее 300 миллисекунд, то
butt = PIND & (1 << 3); // проверяем состояние светодиода на выводе PD3
switch (butt) {
case 0: // если PD3 выключен, то
PORTD &= ~(1 << 4); // устанавливаем низкий уровень на выводе PD4
PORTD |= (1 << 3); // устанавливаем высокий уровень на выводе PD3
break;
case 1: // если PD3 включен, то
PORTD &= ~(1 << 3); // устанавливаем низкий уровень на выводе PD3
PORTD |= (1 << 4); // устанавливаем высокий уровень на выводе PD4
break;
}
}
else if (old_time > 300) { // если время нажатия было более 300 миллисекунд, то
butt = PIND & (3 << 3); // проверяем состояние PD3 и PD4, если
switch (butt) {
case 0: // оба выключены, то
PORTD |= (3 << 3); // устанавливаем высокий уровень на выводе PD3,4
break;
case 1: // любой из них включен, то
PORTD &= ~(3 << 3); // устанавливаем низкий уровень на выводе PD3,4
break;
}
}
Button = 1; // устанавливаем флаг ненажатой кнопки
}
}
----------------------------------------------------------------
Это, в принципе, уже влезает в микроконтроллер ATTiny13a и можно было бы остановиться на достигнутом, но нет предела совершенству. Хочется "красивый" код. Если избавиться от void setup() и void loop(), то получается 464 байт, но .... перестаёт работать (функция millis() и delay() это "фишка" Arduino) :-(
Реализовывать их через таймеры не хочется на этом этапе, видимо придётся остановиться на первом варианте.
Как подключить стандартную библиотеку Arduino для реализации этих функций - я так и не нашёл :-(
----------------------------------------------------------------
unsigned long old_time = 0; // переменная для измерения времени удержания кнопки
boolean Button = 1; // флаг состояния кнопки
void setup() {
DDRB |= (3 << 3); // переключаем выводы PB3 и PB4 в режим "выход"
}
void loop() {
boolean butt = PINB & (1 << 2); // проверяем состояние кнопки
if ((butt == 0) && (Button == 1)) { // если кнопка нажата и до этого была не нажата
Button = 0; // устанавливаем флаг нажатия кнопки
old_time = millis(); // фиксируем время нажатия кнопки
}
if ((butt != 0) && (Button == 0)) { // если кнопка не нажата, а раньше была нажата, то
old_time = millis() - old_time; // вычисляем время, сколько была нажата кнопка
if ((old_time >10) && (old_time < 300)) { // если время нажатия было менее 300 миллисекунд, то
butt = PINB & (1 << 3); // проверяем состояние светодиода на выводе PB3
switch (butt) {
case 0: // если PB3 выключен, то
PORTB &= ~(1 << 4); // устанавливаем низкий уровень на выводе PB4
PORTB |= (1 << 3); // устанавливаем высокий уровень на выводе PB3
break;
case 1: // если PB3 включен, то
PORTB &= ~(1 << 3); // устанавливаем низкий уровень на выводе PB3
PORTB |= (1 << 4); // устанавливаем высокий уровень на выводе PB4
break;
}
}
else if (old_time > 300) { // если время нажатия было более 300 миллисекунд, то
butt = PINB & (3 << 3); // проверяем состояние PB3 и PB4, если
switch (butt) {
case 0: // оба выключены, то
PORTB |= (3 << 3); // устанавливаем высокий уровень на выводе PB3,4
break;
case 1: // любой из них включен, то
PORTB &= ~(3 << 3); // устанавливаем низкий уровень на выводе PB3,4
break;
}
}
Button = 1; // устанавливаем флаг ненажатой кнопки
}
}
----------------------------------------------------------------
При компиляции в Attiny13a получилось 486 байт. Загрузилось с 25-й попытки и почему заработало так и не понял. С повторяемостью этого эксперимента, возможно будут сложности. В качестве программатора использовалась сама же Arduno. Схема подключения и настройки здесь.
Фотки:

fullsize photo http://b6.icdn.ru/s/slava_68/2/42921082aMX.jpg ............... http://b6.icdn.ru/s/slava_68/3/42921083NVU.jpg