查看:5044|回复:2
AVR单片机ATmega8/16内部晶振校准,本例程适用于内部8M 波特率38400。使用方法:
下载到单片机后打开串口(波特率38400)自动发送十六进制55,成功时串口收到OK指令。
单片机源程序如下:
复制代码
下载到单片机后打开串口(波特率38400)自动发送十六进制55,成功时串口收到OK指令。
单片机源程序如下:
- #define F_CPU 4000000UL
- #include< avr/io.h>
- #include< string.h>
- #include< util/delay.h>
- #include< avr/interrupt.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- INT8U flag=0,flag1=0;
- INT8U DataBuf;
- //初始化
- void Init_USART()
- {
-
UCSRB=_BV(RXEN)|_BV(TXEN)|_BV(RXCIE);
-
UCSRC=_BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0);
-
UBRRL=(F_CPU/38400/8-1)%256;
-
UBRRH=(F_CPU/38400/8-1)/256;
- UCSRA|=_BV(U2X);
- }
- //发送一个字符
- void PutChar(char c)
- {
- UDR=c;
-
while(!(UCSRA&_BV(UDRE)));
- }
- void tx(char *s) //发送一个字符串
- {
- INT8U i=0;
- while(s[i]!='\0') PutChar(s[i++]);
- }
- void EepromWrite(INT16U uiAddress,INT8U ucData)
- {
- while(EECR&(1<<EEWE));
- EEAR=uiAddress;
- EEDR=ucData;
- EECR|=(1<<EEMWE);
- EECR|=(1<<EEWE);
- }
-
/******************************************/
-
/******************************************/
- INT8U EepromRead(INT16U uiAddress)
- {
- while(EECR&(1<<EEWE));
- EEAR=uiAddress;
- EECR|=(1<<EERE);
- return (EEDR);
- }
- int main()
- {
- DDRC=0xFF;// 输出低
- PORTC=0x00;//气阀,测试开关
-
- DDRB=0x00;//下载输入弱上拉
- PORTB=0xFF;//传感器
-
- DDRD=0x02;// D0输入上拉D1输出高
- PORTD=0xFF;//按键 检测
- Init_USART();
- sei();
- OSCCAL=0x00;
-
/**************** 晶振修正 **************************
- DataBuf=EepromRead(0x0F);
- PutChar(DataBuf);
- if(DataBuf!=0xFF)
- OSCCAL=DataBuf;
- _delay_ms(500);
-
***************************************************/
- while (1)
- {
-
- }
- }
- ISR (USART_RXC_vect)
- {
- static INT8U i=0;
- INT8U a;
- a=UDR;
-
- if(a==0x55)
- {
- //PutChar(a);
- i++;
- if (i==50)
- {
- UCSRB&=0x7F;
- EepromWrite(0x0F,OSCCAL);
- tx("OK");
- }
- }
- else
- OSCCAL++;
- }
- /*串口接受中断
- ISR (USART_RXC_vect)
- {
- static INT8U i=0;
- INT8U a;
- a=UDR;
- PutChar(a);
- if(a=0x55)
- {
- PutChar('0');
- i++;
- if (i==50)
- {
- UCSRB&=0x7F;
- EepromWrite(0x03,a);
- tx("OK");
- }
- }
- else
- OSCCAL++;
- }*/
-