Цитата(Zloy_Paulik @ Apr 1 2011, 10:22)

Ну так это же подфорум для начинающих, и я в самом начале ветки написал, что я новичек и слезно просил не пинать ногами. А если Вы такой гуру - помогли бы лучше советом.
1. Забыть Протеус. Отлаживать в железе. Вы можете не покупать фирменный JTAGICE или Dragon, а изготовить своими руками, например такой
http://www.scienceprog.com/avrjtag-clone-in-action/2. Не объявляйте переменные как int, без необходимости. Объявляйте их как unsigned char (я обычно пишу uint8_t, так и короче, и понятней). Дело в том, что int, по умолчанию, занимает 2 байта - а это совершенно неоправданный (в Вашем примере) расход ресурсов процессора. Кроме того в случае вывода в порт, чтоб результат был предсказуемым, необходимо сделать приведение типов:
PORTD = (uint8_t ) i_Regim;
Хотя выпихивание 16-битной, к тому же еще и знаковой, переменной в 8-битный порт, обычно не делается, или делается не так. Вот так рождаются трудноуловимые баги

3. Правило: Все глобальные переменные, которые изменяются в обработчиках прерываний, объявлять как volatile:
volatile uint8_t key_pressed=0; это заставит компилятор генерировать загрузку переменных в регистры из памяти внутри циклов, в противном случае хитрый оптимизатор сделает это перед запуском цикла, что мы и имеем.
Вот как это выглядит на практике (в Вашем случае):
CODE
61: Timer_init ();
+00000079: 940E003E CALL 0x0000003E Call subroutine
63: key_pressed=1;
+0000007B: E081 LDI R24,0x01 Load immediate
+0000007C: 93800060 STS 0x0060,R24 Store direct to data space
71: PORTD=i_Regim;
+0000007E: 91800061 LDS R24,0x0061 Load direct from data space
+00000080: BB82 OUT 0x12,R24 Out to I/O location
+00000081: CFFF RJMP PC-0x0000 Relative jump
Кроме того, как мы видим, оптимизатор посчитал, что в цикле ничего не происходит и выбросил его вовсе (какой маладэц

)
И после объявления volatile uint8_t key_pressed. Обратите внимание на строку, помеченную !!!!!!!!! И цикл наш появился

CODE
61: Timer_init ();
+00000079: 940E003E CALL 0x0000003E Call subroutine
63: key_pressed=1;
+0000007B: E081 LDI R24,0x01 Load immediate
+0000007C: 93800060 STS 0x0060,R24 Store direct to data space
71: PORTD=i_Regim;
+0000007E: 91900061 LDS R25,0x0061 Load direct from data space
69: if (key_pressed==1)
+00000080: 91800060 LDS R24,0x0060 Load direct from data space !!!!!!!!!!!!! Появилась инструкция загрузки регистра из SRAM
+00000082: 3081 CPI R24,0x01 Compare with immediate
+00000083: F7E1 BRNE PC-0x03 Branch if not equal
71: PORTD=i_Regim;
+00000084: BB92 OUT 0x12,R25 Out to I/O location
72: key_pressed=0;
+00000085: 92100060 STS 0x0060,R1 Store direct to data space
+00000087: CFF8 RJMP PC-0x0007 Relative jump !!!!!!!!!!! И цикл тоже теперь есть
72: key_pressed=0;
Как вариант, можно отключить оптимизацию (-O0), но это не наш метод

Вот так выглядят грабли, на которые Вы наступили.
4. Ключевое слово extern используютя для объявления переменных, которые уже ранее объявлены в другом файле проекта, при этом инициализация переменной не происходит, и Вашем случае переменные i_Regim и key_pressed имеют неопределенные значения (key_pressed получает потом значение в функции main(), а i_Regim - нет). Компилятор на это делает предупреждение (Warning), но это не является фатальной ошибкой. Хотя это - ошибка: у Вас переменная i_Regim изначально имеет неопределенное значение и результат будет непредсказуем.
Вроде все... Если есть еще вопросы, или что-то я непонятно изложил, пишите, обсудим
Сообщение отредактировал nk@ - Apr 2 2011, 11:59