Timer AVR蝶形-内部振荡器校准后的计时器重复使用

Timer AVR蝶形-内部振荡器校准后的计时器重复使用,timer,avr,calibration,usart,Timer,Avr,Calibration,Usart,根据AVR提供的示例代码(见下面的代码),我正在校准AVR蝶形内部振荡器,以便能够使用USART。由于我也想使用两个定时器控制的伺服电机,我想知道在校准过程后是否可以重新使用16位定时器1-我尝试重置TCCR1A/B,但没有成功(代码也在下面)。我希望你能帮我解决这个问题 void OSCCAL_Calibrate(void){ unsigned char calibrate = 0; int temp; unsigned char tempL; CLKPR =

根据AVR提供的示例代码(见下面的代码),我正在校准AVR蝶形内部振荡器,以便能够使用USART。由于我也想使用两个定时器控制的伺服电机,我想知道在校准过程后是否可以重新使用16位定时器1-我尝试重置TCCR1A/B,但没有成功(代码也在下面)。我希望你能帮我解决这个问题

void OSCCAL_Calibrate(void){
    unsigned char calibrate = 0;
    int temp;
    unsigned char tempL;

    CLKPR = (1<<CLKPCE);        // set Clock Prescaler Change Enable
    // set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz
    CLKPR = (1<<CLKPS1) | (1<<CLKPS0);
    TIMSK2 = 0;             //disable OCIE2A and TOIE2
    ASSR = (1<<AS2);        //select asynchronous operation of timer2 (32,768kHz)    
    OCR2A = 200;            // set timer2 compare value 
    TIMSK0 = 0;             // delete any interrupt sources
    TCCR1B = (1<<CS10);     // start timer1 with no prescaling
    TCCR2A = (1<<CS20);     // start timer2 with no prescaling
    while((ASSR & 0x01) | (ASSR & 0x04));       //wait for TCN2UB and TCR2UB to be cleared

    delayMs(1000);    // wait for external crystal to stabilise

    while(!calibrate)
    {
        cli();  // disable global interrupt

        TIFR1 = 0xFF;   // delete TIFR1 flags
        TIFR2 = 0xFF;   // delete TIFR2 flags
        TCNT1H = 0;     // clear timer1 counter
        TCNT1L = 0;
        TCNT2 = 0;      // clear timer2 counter

        while ( !(TIFR2 & (1<<OCF2A)) );   // wait for timer2 compareflag

        TCCR1B = 0; // stop timer1

        sei();  // enable global interrupt

        if ( (TIFR1 & (1<<TOV1)) )
        {
            temp = 0xFFFF;      // if timer1 overflows, set the temp to 0xFFFF
        }else
        {   // read out the timer1 counter value
            tempL = TCNT1L;
            temp = TCNT1H;
            temp = (temp << 8);
            temp += tempL;
        }

        if (temp > 6250)
            OSCCAL--;   // the internRC oscillator runs to fast, decrease the OSCCAL
        else if (temp < 6120)
            OSCCAL++;   // the internRC oscillator runs to slow, increase the OSCCAL
        else
            calibrate = 1;   // the interRC is correct

        TCCR1B = (1<<CS10); // start timer1
    }
} 

void motorInit(){
    // reset timer 1
    TCCR1A = 0;
    TCCR1B = 0;

    // initialize Servo Pins
    DDRB |= (1<<PB5) | (1<<PB6);

    ICR1H = ICR_VALUE >> 8;
    ICR1L = ICR_VALUE & (TOP_VALUE);

    // reset OCRs
    setServoSpeed(0, 0);
    setServoSpeed(1, 0);

    // Set Timer mode (PWM Phase & Freq. correct, clear on compare match)
    // and prescaler (8)
    TCCR1A = ((1<<COM1A1) | (1<<COM1B1));                 
    TCCR1B = ((1<<WGM13) | (0<<CS12) | (1<<CS11) | (0<<CS10));
}
void OSCCAL\u校准(void){
无符号字符=0;
内部温度;
无符号字符模板;

CLKPR=(1也许您可以检查我刚才在项目中使用的代码,但是您应该注意,对于56700波特率,我将系统频率降低到7.3768 MHz,这可能需要调整

void OSCCAL_Calibrate(void)
{
uint8_t LoopCount = (0x7F / 2); 

ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
// Make sure all clock division is turned off (8MHz RC clock)
CLKPR = (1 << CLKPCE);
CLKPR = 0x00;

// Inital OSCCAL of half its maximum
OSCCAL = (0x7F / 2);

// Disable timer interrupts
TIMSK1 = 0;
TIMSK2 = 0;

// Set timer 2 to asyncronous mode (32.768KHz crystal)
ASSR = (1 << AS2);

// Ensure timer 1 control register A is cleared
TCCR1A = 0;

// Start both counters with no prescaling
TCCR1B = (1 << CS10);
TCCR2A = (1 << CS20);

// Wait until timer 2's external 32.768KHz crystal is stable
while (ASSR & ((1 << TCN2UB) | (1 << TCR2UB) | (1 << OCR2UB)));

// Clear the timer values
TCNT1 = 0;
TCNT2 = 0;

while (LoopCount--)
{
// Wait until timer 2 overflows
while (!(TIFR2 & (1 << TOV2)));

// Stop timer 1 so it can be read
TCCR1B = 0x00;

// Check timer value against ideal constant
if (TCNT1 > OSCCAL_TARGETCOUNT) // Clock is running too fast
OSCCAL--;
else if (TCNT1 < OSCCAL_TARGETCOUNT) // Clock is running too slow
OSCCAL++;

// Clear timer 2 overflow flag
TIFR2 |= (1 << TOV2);
void OSCCAL\u校准(void)
{
uint8_t LoopCount=(0x7F/2);
原子块(原子块)
{
//确保所有时钟划分均已关闭(8MHz RC时钟)

CLKPR=(1也许您可以检查我刚才在项目中使用的代码,但是您应该注意,对于56700波特率,我将系统频率降低到7.3768 MHz,这可能需要调整

void OSCCAL_Calibrate(void)
{
uint8_t LoopCount = (0x7F / 2); 

ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
// Make sure all clock division is turned off (8MHz RC clock)
CLKPR = (1 << CLKPCE);
CLKPR = 0x00;

// Inital OSCCAL of half its maximum
OSCCAL = (0x7F / 2);

// Disable timer interrupts
TIMSK1 = 0;
TIMSK2 = 0;

// Set timer 2 to asyncronous mode (32.768KHz crystal)
ASSR = (1 << AS2);

// Ensure timer 1 control register A is cleared
TCCR1A = 0;

// Start both counters with no prescaling
TCCR1B = (1 << CS10);
TCCR2A = (1 << CS20);

// Wait until timer 2's external 32.768KHz crystal is stable
while (ASSR & ((1 << TCN2UB) | (1 << TCR2UB) | (1 << OCR2UB)));

// Clear the timer values
TCNT1 = 0;
TCNT2 = 0;

while (LoopCount--)
{
// Wait until timer 2 overflows
while (!(TIFR2 & (1 << TOV2)));

// Stop timer 1 so it can be read
TCCR1B = 0x00;

// Check timer value against ideal constant
if (TCNT1 > OSCCAL_TARGETCOUNT) // Clock is running too fast
OSCCAL--;
else if (TCNT1 < OSCCAL_TARGETCOUNT) // Clock is running too slow
OSCCAL++;

// Clear timer 2 overflow flag
TIFR2 |= (1 << TOV2);
void OSCCAL\u校准(void)
{
uint8_t LoopCount=(0x7F/2);
原子块(原子块)
{
//确保所有时钟划分均已关闭(8MHz RC时钟)
CLKPR=(1)