为啥要在 AVR 编程中校准振荡器
Posted
技术标签:
【中文标题】为啥要在 AVR 编程中校准振荡器【英文标题】:Why should I calibrate the oscillator in AVR programming为什么要在 AVR 编程中校准振荡器 【发布时间】:2012-11-24 03:52:29 【问题描述】:我是 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;
As-s-r = (1<<AS2);
OCR2A = 200;
TIMSK0 = 0;
TCCR1B = (1<<CS10);
TCCR2A = (1<<CS20);
while((As-s-r & 0x01) | (As-s-r & 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)。经过一些改变,我可以让它工作。但是没有校准功能它仍然可以工作..
我将逐项列出我的问题如下。
在校准振荡器时,您真正做了什么? 这是必须的吗? PIC单片机有类似的功能吗? (我在 PIC 编程方面有点经验。但从来不知道这样的事情)
也有点疑惑;
为什么之前在
USARTinit()
函数中设置了时钟预标量 设置波特率?你不能在没有a的情况下设置波特率吗 预标量(即预标量 = 1)
是为了省电还是什么?但我尝试使用 pre-scalar=1,它似乎不起作用(仍在尝试)。是的,我已经正确计算了波特率(使用数据表中给定的公式)。
【问题讨论】:
【参考方案1】:我对这个特殊的硬件一无所知,但很快 Google 出现了 this datasheet
引用:
目前的大多数 AVR 微控制器都提供了从 内部 RC 振荡器。在大多数 AVR 中,内部 RC 振荡器频率可以是 校准到器件数据表中指定频率的 +/-1% 范围内。 与使用 一个外部振荡器。 在 Atmel 工厂进行的校准是在固定的工作电压下进行的 和温度(25°C,通常为 5V)。作为内部 RC 振荡器的频率 受工作电压和温度的影响,可能需要执行 与特定应用环境相匹配的二次校准。这 可以进行二次校准以获得比标准更高的精度 校准提供,以匹配特定的工作电压或温度,甚至 将振荡器调到不同的频率。
【讨论】:
【参考方案2】:如果您在微控制器之外进行任何与时间相关的通信(串行、将 spi 推到极限等)或保持时间或其他任何事情,那么您需要更准确的时钟。
这实际上与功率无关,也许稍微有点,如果时钟有点慢,那么你会使用更多的功率,如果有点快,那么你会节省一点功率。
许多但并非所有微控制器都提供内部 R/C 振荡器,因此您不需要外部振荡器(额外组件,额外成本)。这不是一个系列与另一个系列(avr、msp430、pic 等)的对比,一个系列中的某些芯片具有内部振荡器,有些则没有。我以前使用的 PIC 需要一个外部的,今天不知道这个家庭的细节。校准的方式也因家庭而异。
【讨论】:
【参考方案3】:是否需要校准取决于您的实际硬件:
如果您的微控制器使用 Xtal 生成时钟,您无需校准任何东西,只需根据您的 Xtal 振荡频率选择好的分频器。
如果您只使用 RC 振荡器,那么由于它可能具有更重要的容差值,您可能需要校准频率,尤其是在使用较高波特率(如 19200 或更高)时。
李>您必须根据您的振荡器频率设置预分频器,有关详细信息,请参阅数据表。
【讨论】:
以上是关于为啥要在 AVR 编程中校准振荡器的主要内容,如果未能解决你的问题,请参考以下文章