Я только начинаю программировать AVR , поэтому сильео не пинайте. МК ATMega 16. К 5-му биту регистра А подключена кнопка. В ненажатом состоянии на ножку подается высокий уровень. Для отсеживания нажатий на кнопку я хочу использовать флаг, который устанавливается в обработчике прерываний от таймера и сбрасывается в основном цикле программы после выполнения нужных мне действий. Вся проблема в том, что будучи сброшенным один раз этот флаг уже в 1 не устанавливается. Точнее говоря устанавливается, но только в теле функции обработки прерывания, а в ф-ию main передается ноль. Где косяк? Уже всю голову сломал.
Собственно программа
#include <avr/io.h> #include <string.h> #include <stdio.h> #include <util/delay.h> #include <stdlib.h> #include <avr/interrupt.h>
unsigned char temp; extern int key_pressed=0; extern int i_Regim=0;
extern void Timer_init (void) { // инициализация таймера опроса кнопок
TCCR1A = 0x00; TCCR1B = (0 << CS12)|(1 << CS11)|(0 << CS10)|(1 << WGM12); //предделитель clk/8, режим таймера СТС TCNT1=0x00; OCR1A=780*3; // выбор коэффициента деления TIMSK = (1 << OCIE1A); // разрешение прерывания по совпадению
temp = 0b00000000; // Присвоение начального значения
asm ("sei"); // Разрешение прерываний
}
ISR (TIMER1_COMPA_vect) { // обработка прерывания от таймера 1
// обработка нажатия кнопки "Режим" if (!bit_is_set(PINA,5)) temp++; //начало антидребезг else if (!(temp==0)) temp--; if (temp > 10) { temp=0; // конец антидребезга key_pressed=1; i_Regim++; // переходим к следующему режиму }
}
int main( void ){
PORTA = 0x00; // сброс порта А DDRA= 0x00; // все выводы порта - входы PORTD = 0x00; // сброс порта D DDRD= 0xFF; // все выводы порта D - выходы
i_Regim=0; // устанавливаем режим номер 0 - "работа"
Timer_init (); // инициализация таймера для работы с кнопками
key_pressed=1; // для первоначального отображения информации
while( 1 ){ // основной цикл
if (key_pressed) { PORTD=i_Regim; // ЭТА СТРОЧКА НЕ ВЫПОЛНЯЕТСЯ !!! key_pressed=0; } } // конец основного цикла
return 0; } // конец main
|