3

我是 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. PIC微控制器中是否有类似的功能?(我在 PIC 编程方面有点经验。但从来不知道这样的事情)

也有一点疑问;

为什么USARTinit()在设置波特率之前在函数中设置时钟预标量?你不能在没有预标量的情况下设置波特率(这意味着预标量 = 1)

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

4

3 回答 3

3

我对这个特殊的硬件一无所知,但谷歌很快就显示了这个数据表

去引用:

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

于 2012-11-24T04:06:28.880 回答
1

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

这实际上与功率无关,也许,如果时钟有点慢,那么你会使用更多的功率,如果有点快,那么你会节省一点功率。

许多但并非所有微控制器都提供内部 R/C 振荡器,因此您不需要外部振荡器(额外组件,额外成本)。这不是一个家族与另一个家族(avr、msp430、pic 等)的对比,一个家族中的某些芯片具有内部振荡器,有些则没有。我以前使用的 PIC 需要一个外部的,今天不知道这个家庭的细节。校准的方式也因家庭而异。

于 2012-11-24T15:39:23.030 回答
1

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

  1. 如果您的微控制器使用 Xtal 生成其时钟,则您无需校准任何东西,只需根据您的 Xtal 振荡频率选择好的分频器。

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

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

于 2012-12-11T22:04:11.233 回答