#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#define F_CPU 8000000UL
#define VFG_TIMER_MAX 65535
float fG = 100;
unsigned char nG;
unsigned int N[] = {1, 8, 64, 256, 1024};
void Tim1Init(void)
{
DDRB |= (1 << PB0); // Set pin as OUTPUT
TCCR1A = (1 << COM1A0); // Toggle on compare
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // Set timer CTC mode
TIMSK = (1 << OCIE1A);
SetUpTim1A(fG);
sei(); // Enable global interrupts
}
void SetUpTim1A(float Foc) // Set value OCR1A register
{
float TimDiv, OCRnx_calc = 0;
unsigned int ret_OCRnx = 0;
unsigned char ClockSelect = 0;
unsigned char i = 0;
for (i = 0; i < 5; i++) {
TimDiv = (F_CPU / (2 * Foc * N[i]) - 1);
OCRnx_calc = ceil((TimDiv / Foc) - 1);
if (OCRnx_calc >= 0 && OCRnx_calc < VFG_TIMER_MAX) {
ClockSelect = i + 1;
break;
}
ret_OCRnx = (unsigned int)OCRnx_calc;
OCR1A = ret_OCRnx;
TCCR1B = (1 << WGM12) | ClockSelect;
}
}
ISR(TIMER1_COMPA_vect)
{
PORTB ^= (1 << PB0);
}
int main(void)
{
Tim1Init();
while (1) {
// Ваш код здесь
// Измените значение переменной fG и nG в соответствии с вашими требованиями
// Затем вызовите SetUpTim1A(fG) снова, чтобы обновить частоту
fG = 200; // Пример изменения значения переменной fG
SetUpTim1A(fG); // Обновление частоты
nG = 1; // Пример изменения значения переменной nG
// Используйте значение переменной nG для настройки соответствующего порта
// Ваш дополнительный код здесь
// Пример задержки между изменениями частоты
_delay_ms(1000);
}
return 0;
}