为什么要在AVR编程中校准振荡器

时间:2012-11-24 03:52:29

标签: microcontroller avr atmel atmega avr-studio5

我是AVR编程的新手。我在网上找到了一个示例代码;用于与PC进行简单的USART通信。我有点怀疑。

主循环就像这样开始;

void main(){
  OSCCAL_calibration(); 
  USARTinit();
  //start communicating with PC
}

我无法理解使用OSCCAL_calibration();功能校准振荡器的原因。


功能

OSCCAL_calibration()功能

void OSCCAL_calibration(void){
    unsigned char calibrate = 0;
    int temp;
    unsigned char tempL;
    CLKPR = (1<<CLKPCE);
    CLKPR = (1<<CLKPS1) | (1<<CLKPS0);
    TIMSK2 = 0;
    ASSR = (1<<AS2);
    OCR2A = 200;
    TIMSK0 = 0;
    TCCR1B = (1<<CS10);
    TCCR2A = (1<<CS20);
    while((ASSR & 0x01) | (ASSR & 0x04));
    for(int i = 0; i < 10; i++)
    _delay_loop_2(30000);
    while(!calibrate){
        cli();
        TIFR1 = 0xFF;
        TIFR2 = 0xFF;
        TCNT1H = 0;
        TCNT1L = 0;
        TCNT2 = 0;
        while ( ! (TIFR2 && (1<<OCF2A)) );
        TCCR1B = 0; // stop timer1
        sei();
        if ( (TIFR1 && (1<<TOV1)) ){
            temp = 0xFFFF;
        }else{
            tempL = TCNT1L;
            temp = TCNT1H;
            temp = (temp << 8);
            temp += tempL;
        }
        if (temp > 6250){
            OSCCAL--;
        } else if (temp < 6120){
            OSCCAL++;
        }else
        calibrate = 1;
        TCCR1B = (1<<CS10);
    }
}

USARTinit()功能

void USARTinit(){
    CLKPR = (1<<CLKPCE);
    CLKPR = (1<<CLKPS1);
    UBRR0H = 0;
    UBRR0L = 12;
    UCSR0A = (1<<U2X0);
    UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<UDRIE0);
    UCSR0C = (0<<UMSEL00)|(0<<UPM00)|(0<<USBS0)|(3<<UCSZ00)|(0<<UCPOL0);
}

我正在使用Atmel Studio 6并使用atmega2560(实际上,使用我的Arduino Mega)对此进行了测试。经过一些改变后,我可以让它发挥作用。但它仍然可以在没有校准功能的情况下工作..

我将逐条列出我的问题。

  
      
  1. 你在校准振荡器方面做了什么?
  2.   
  3. 是必须的吗?
  4.   
  5. PIC微控制器中是否有类似的功能? (我是PIC编程经验丰富的。但从来不知道类似的东西)
  6.   

也有点怀疑;

  

为什么之前在USARTinit()函数中设置时钟预标量   设置波特率?没有a,你不能设置波特率   pre-scalar(意思是,标量前= 1)

是省电还是什么?但我尝试使用pre-scalar = 1,它似乎无法正常工作(仍在尝试)。是的,我已经正确计算了波特率(使用数据表中的给定公式)。

3 个答案:

答案 0 :(得分:3)

我对这个特定的硬件一无所知,但快速的Google出现了this datasheet

引用:

  

目前大多数AVR微控制器提供从一个运行的可能性   内部RC振荡器。内部RC振荡器频率在大多数AVR中都可以   校准到设备数据表中指定频率的+/- 1%以内。   与使用相比,此功能具有极大的灵活性和显着的成本节省   外部振荡器。   在Atmel工厂进行的校准是在固定的工作电压下进行的   和温度(25°C,通常为5V)。作为内部RC振荡器的频率   受操作电压和温度影响,可能需要执行   二次校准,与特定应用环境相匹配。这个   可以执行二次校准以获得比标准更高的精度   校准提供,以匹配特定的工作电压或温度,甚至   将振荡器调到不同的频率。

答案 1 :(得分:1)

如果您正在微控制器外进行任何与时序相关的通信(串行,将spi推到极限等)或保持时间或其他任何时间,那么您需要更精确的时钟。

实际上并不是关于功率,或许,如果时钟稍微慢一点,那么如果快一点你就会使用更多功率然后节省一点功率。

许多但并非所有微控制器都提供内部R / C振荡器,因此您不需要外部振荡器(额外组件,额外成本)。这不是一个家庭与另一个家庭(avr,msp430,pic等)家庭中的一些芯片有一些内部振荡器。我在当天用过的PIC需要一个外部的,今天不了解这个细节的家庭。校准的发生方式也因家庭而异。

答案 2 :(得分:1)

校准的需要取决于您的实际硬件:

  1. 如果您的微控制器使用Xtal生成其时钟,则无需校准任何内容,只需选择好的分频器,具体取决于您的Xtal振荡频率。

  2. 如果您只使用RC振荡器,那么因为它可以具有更重要的值容差,您可能需要校准频率,尤其是在使用更高的波特率(如19200或更高)时。

  3. 您必须根据振荡器频率设置预置标尺,有关详细信息,请参阅数据表。