@WARPTRED

Как получить нужную частоту на выходе микроконтроллера?

Проблема заключается в том, что меняя переменную fG частота на ножке PB0 остается одной и той же(244Гц), хотя я и меняю значение переменной, участвующей в расчете значения регистра сравнения OCR1A. Формула расчета тоже довольно простая, взята из даташита. На данный момент я бы хотел решить 2 проблемы:
1) Возможность задания частоты переменной fG.
2) Возможность задания выхода частоты с МК переменной nG.
UPD: значение переменных nG и fG будут менятся по SPI(код еще не написал), интересен сам принцип подобной организации задержек.
#include <tiny2313.h>
#include <math.h>
#include <io.h>
#include <delay.h>

#define F_CPU (8000000)
#define	VFG_TIMER_MAX		(65535)
#define	VFG_PIN0	PORTB0
#define	VFG_PIN1	PORTB1
#define	VFG_PIN2	PORTB2
#define	VFG_DDR		DDRB
#define	VFG_PORT	PORTB

float fG=100;
unsigned char nG;
unsigned int N[]={1,8,64,256,1024};

//void Tim1Init(void);
//void SetUpTim1A(double Foc);

void Tim1Init(void)
{
    VFG_DDR = (1<<VFG_PIN0); // 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(0);
    #asm("sei")	
}

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;
    }
}

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
    VFG_PORT ^= (1<<VFG_PIN0);
}

void main(void)
{
 unsigned char nG;
 Tim1Init();
 SetUpTim1A(fG);
    
#asm("sei")
while(1){}
}
  • Вопрос задан
  • 291 просмотр
Пригласить эксперта
Ответы на вопрос 1
i229194964
@i229194964
Веб разработчик
#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;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы