Здравствуйте, форумчане! Такой вопрос: Есть Atmega128, отладочная плата STK500/501 и Atmel studio 7.0 Написана скромная программка, в которой мигают светодиоды с определенной частотой (Частота схемы 8МГц). При нажатии на определенные кнопки должна изменяться частота мигания. Так вот проблема в том, что светодиоды меняют частоту мерцания лишь при удержании этой кнопки, а не нажатия. В последних редакциях кода при изменении предделителя вообще не хочет мигать. Итак, в чём странность - при выставлении в фьюзах бита включения режима соответствия с atmega103(установка 0 бита) код работает адекватно! Но оставлять так не могу, ибо нацелен на разрешение вопроса без последующих возможных еще больших несуразицах. В чем может быть дело?
Выложите код "скромной программки" и попытайтесь изложить проблему более ясным языком.... а то пока у меня возникло бредовое предположение. что вы частоту мигания светодиода пытаетесь изменять с помощью фьюзов
Проблема в том, что при включении режима совместимости с С103 на атмеге128 программа начинает нормально работать, в то время как должна это делать без включения данного фьюза Собственно, вот: #define F_CPU 8000000UL //Объявление частоты мк #include <avr/io.h> //библиотека мк #include <avr/interrupt.h> //библиотека прерываний #include <util/delay.h> //подключение задержек unsigned char count=0; //предполагаемое время (в мс) int Sch=250; //для начала частота 250 мс static void ti_in(void) //функция инициализации таймера { TCCR1A|=0; //регистр управления таймером/счетчиком TCNT1|=0; //Регистр таймера/счетчика OCR1A=125; //значение сравнения для появления сравнения на 1 мс TIMSK|=(1<<OCIE1A); TCCR1B|=(1<<CS12)|(1<<WGM12); //установка делителя, режима работы таймера } ISR(TIMER1_COMPA_vect) //функция, выполняемая при совпадении чисел { count++; //увеличение кол-ва мс if (count == Sch) { PORTC=~PORTC; //инвертирование порта светодиодов count=0; } } int main(void) { cli(); DDRC=0xFF; //порт со светодиодами настроен на вывод PORTC=0xFF; //стартовое значение - горящие светодиоды PORTE = (1<<PE0) | (1<<PE1); ti_in(); sei(); while (1) { if (!(PINE & (1<<PE1))) { Sch=3000; _delay_ms(100); } if (!(PINE & (1<<PE0))) { Sch=5000; } } }
Во-первых, у вас грубая ошибка - переменная count меняется в прерывании, значит она должна быть описана как volatile. Поправьте, может именно в этом дело. Если уверены в настройках таймера (лень лезть искать даташит на Атмегу 128) - других явных ошибок не вижу.
Вы абсолютно правы, но что с volatile, что без него программа работает одинаково Таймер сам уже перелопачивал сотню раз, и по осциллографу сейчас показывает всё верно Вот в том-то и дело, что совершенно непонятно, в чем может быть зарыта @
кстати, переменную Sch тоже попробуйте обьявить волатильной. Хоть она явно в прерывании не меняется, но меняется между вызовами - мало ли что накрутит компилятор в рамках "оптимизации"