我是 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,它似乎不起作用(仍在尝试)。是的,我已经正确计算了波特率(使用数据表中的给定方程)。