Здравствуйте, уважаемые форумчане!
Видел уже здесь похожий вопрос с не совсем верным ответом на него.
Пардон за незнание очевидных вещей - буду крайне признателен тому, кто ткнет меня носом в ошибку.
Ситуация - имеется avr studio 7, МК Atmega128 и STK500, программа с генерацией прерываний для таймера с счетчиком по совпадению (СТС).
Отладочная плата при запуске просто начинает мигать светодиодами и пока примитивно ставится цель изменения частоты мигания при нажатия на определенные кнопки.
Так вот, если выделять команды задания таймера в отдельную функцию, то реакция на кнопки вообще пропадает. При добавлении в общий main появляется, но это меня не устраивает. Функция, меняющая частоту в свою очередь меняет её только один раз и то по непонятной мне логике.
Вопрос - как исправить код, сделать адекватной реакцию на кнопки с объявлением таймера в отдельной функции и изменять частоту при нажатии, код:
Код: Выделить всё
#define F_CPU 8000000UL //obyavleniye chastoty CPU mk
#include <avr/io.h> //podklucheniye biblioteki mk
#include <avr/interrupt.h> //podklucheniye biblioteki zaderjek
#include <util/delay.h> //podklucheniye zaderjek
#include <stdio.h>
volatile unsigned char static count=0;
volatile unsigned int static Sch=0;
volatile unsigned int vv=0;
volatile unsigned int i=0;
volatile unsigned char static sreg=0;
volatile void ti_ini (void)
{
Sch=1000; //в реале период / 2
TCCR1B|=(1<<WGM12); //бит режима работы таймера - по совпадению
TIMSK|=(1<<OCIE1A); //TIMSK - Регистр масок прерываний таймеров/счетчиков, OCIE1A: Разрешение прерывания по совпадению для канала
TCCR1A|=0; //регистр управления таймером/счетчиком
TCNT1|=0; //Регистр таймера/счетчика
OCR1A=Sch; //значение сравнения, до 16 бит
TCCR1B|=(1<<CS12); //установка делителя (=64, стр. 145)
}
ISR(TIMER1_COMPA_vect) //функция, выполняемая автоматически, при совпадении числел - счетчика и установленного значения
{
PORTC=~PORTC;
count++;
}
volatile void TIM16_Write(unsigned int i)
{
// Запоминание состояния общего флага прерываний
sreg = SREG;
// Запрет прерываний
cli();
// Копирование TCNTn в i
TCNT1 = 0;
OCR1A = i;
//TCCR1B &=~(1<<CS12);
//TCCR1B|=(1<<CS12);
// Восстановление состояния общего флага прерываний
SREG = sreg;
}
int main(void)
{
sei();
DDRC=0xFF;
ti_ini(); //инициализация таймера
while (1)
{
if (!(PINE &= (1<<PE4)))
{
cli();
PORTC=~PORTC;
}
if (!(PINE &= (1<<PE3)))
sei();
if (!(PINE &= (1<<PE2)))
TIM16_Write(Sch/2);
cli();
// Копирование TCNTn в i
Sch=10000;
TCNT1 = 0;
OCR1A = Sch;
// Восстановление состояния общего флага прерываний
sei();
}
}
}