ну вот вариант, как я сделал аналог вашей программы по функциональности, но, как мне кажется, гораздо качественнее:
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#ifndef _BV(x)
#define _BV(x) (1<<(x))
#endif
/// порт, к которому подключена кнопка
#define BUTTON _BV(PB3)
/// порт, к которому подключен первый светодиод
#define LED1 _BV(PB1)
/// порт, к которому подключен второй светодиод
#define LED2 _BV(PB2)
/// количество вспышек светодида
#define BLINK_CNT 2
/// длительность полупериода вспышки
#define BLINK_DELAY 100
/// флаг, разрешающий работу мигалки
volatile uint8_t work = 0;
/// обработчик прерывания по изменению уровня пина
ISR(PCINT0_vect){
// изменяем состояние флага только если кнопка отжата
if(PINB & BUTTON) work = !work;
// на всякий случай сбрасываем флаг запроса прерывания
GIFR = _BV(PCIF);
}
/// функция мерцания светодиодом
static blink(uint8_t LED){
// мерцаем светодиодом, пока установлен флаг разрешения
for(uint8_t i=0; (i<(2*BLINK_CNT)) && work; i++){
PORTB ^= LED;
_delay_ms(BLINK_DELAY);
}
}
int main(void){
// настройки периферии
DDRB = LED1 | LED2; // выходные порты
PORTB = BUTTON; // порт кнопки с подтяжкой
GIMSK = _BV(PCIF); // разрешаем прерывания по изменению уровня пина
PCMSK = _BV(PCINT3); // разрешаем "чувствовать" только пин с кнопкой
sei(); // разрешаем прерывания глобально
while(1){
// принудительно гасим оба светодиода
PORTB &= ~(LED1 | LED2);
// мерцаем первым светодиодом
blink(LED1);
// мерцаем вторым светодиодом
blink(LED2);
}
}
код для
WinAVR, но переделать под CVAVR совсем несложно - надо только инклюды переделать и продефайнить символы
PB1,
PB2 и т.д. - как описано в даташите на микроконтроллер, вместо
uint8_t написать
unsigned char, ну и в функции задержки убрать подчеркивание

ах, да, вот еще: CVAVR не поймет определение локальной переменной внутри цикла, поэтому придется цикл
for чуток переделать - вынести описание переменной изнутри наружу.
почему я считаю, что ваш код ужасен, а мой нет? вот почему:
1. сравните внешний вид и объем исходника программы
2. обратите внимание на комментарии (я перестарался, писал их много, но я расчитывал именно на начинающих)
3. ответьте на следующие вопросы:
3.1 как в вашей программе изменить количество вспышек светодиодов? сколько потребуется переделывать строк в программе? и сравните с моим вариантом.
3.2 сколько переделок надо сделать у вас, чтобы использовать светодиоды и кнопку, подключенные к другим пинам? и сравните с моим вариантом.
3.3 аналогично сравните усилия для изменения скорости мерцания.
3.4 в каком варианте более нагляден алгоритм работы программы?
3.5 насколько сложно будет, например, добавить третий светодиод в вашу программу и в мою? или убрать кнопку и сделать 4 светодиода? или даже 5?
3.6 легко ли заставить вашу программу мигать одновременно двумя светодиодами? а мою?
мой вариант занимает
200 байт памяти программ. ваш -
446 байт. кроме всего прочего, я намеренно старался сделать код максимально похожим на ваш, а ведь можно его и видоизменить кардинально, но тогда действительно, понять его будет сложнее.
мой код, возможно, и не идеален, и по нему можно сделать ряд замечаний... это лишь попытка показать более-менее правильный подход к написанию программы.