我是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上)对此进行了测试。进行一些更改后,我可以使其工作。但是它仍然可以在没有校准功能的情况下工作。我将逐项列出我的问题,如下所示。
校准振荡器时,您实际上是做什么的?
是必须的吗?
PIC微控制器中是否有类似的功能? (我对PIC编程有一定的经验。但从未听说过类似的东西)
也有一点疑问;
为什么在
USARTinit()
函数中设置时钟预分频器之前设置波特率?您不能在没有设置的情况下设置波特率
标量前(即标量= 1)
是省电还是其他?但是我尝试使用pre-scalar = 1,它似乎不起作用(仍在尝试)。是的,我已经正确计算了波特率(使用数据表中的给定方程式)。
最佳答案
如果您正在微控制器外部进行任何与时序相关的通信(串行,将spi推至极限等)或保持时间或其他任何时间,则需要更准确的时钟。
它可能与电源无关,如果说时钟稍微慢一点,那么如果您稍微快一点,那么您将使用更多的电源,那么您就可以节省一点电量。
许多但不是全部的微控制器都提供内部R / C振荡器,因此您不需要外部振荡器(额外的组件,额外的成本)。这不是一个家族相对于另一个家族(AVR,MSP430,PIC等),一个家族中的某些芯片具有内部振荡器,而有些却没有。我以前使用的PIC需要外部的,今天不了解这个家庭。校准如何发生也因家庭而异。