/*********************************************
File name : usart.c
Chip type : ATmega16
Program type : Application
Clock frequency : 11.0592MHz
Memory model : Small
注意:发送采用查询方式,接收采用中断方式,在初始化程序中,需要将TXD设置成输出方式,RXD设置成输入方式,并使RXD的内部上拉有效
*********************************************/
#include <mega16.h>
#include <delay.h>
#define BAUD 9600 //波特率采用9600bps
#define CRYSTAL 11059200 //外部晶振11.0592MHZ
unsigned int data, flag=0; //标志位
//计算和定义波特率设置参数
#define BAUD_SETTING (unsigned int)((unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1)
#define BAUD_H (unsigned char)(BAUD_SETTING>>8) //高8位
#define BAUD_L (unsigned char)(BAUD_SETTING) //低8位
// USART控制和状态寄存器的标志位定义
// UCSRA位定义 复位值(0010 0000)
#define RXC 7 //USART接收完成
#define TXC 6 //USART发送完成
#define UDRE 5 //USART数据寄存器空(置1会发生数据寄存器空的中断请求)
#define FE 4 //接收帧出错(出错置1)
#define DOR 3 //接收数据溢出出错
#define PE 2 //校验错误
#define U2X 1 //USART传输速率倍速
#define MPCM 0 //多机通信模式允许
// UCSRB位定义 复位值(0000 0000)
#define RXCIE 7 //RX接收完成中断允许
#define TXCIE 6 //TX发送完成中断允许
#define UDRIE 5 //USART数据寄存器空中断允许
#define RXEN 4 //数据接收允许
#define TXEN 3 //数据发送允许
#define UCSZ2 2 //数据字位数大小,与 UCSZ1,UCSZ0同用
#define RXB8 1 //接收数据的第8位
#define TXB8 0 //发送数据的第8位
// UCSRC位定义 复位值(1000 0110)
#define URSEL 7 //寄存器选择
#define UMSEL 6 //USART工作模式选择(0:异步模式;1:同步模式)
#define UPM1 5 // UPM【1:0】校验方式(00:无校验;01:保留;10:使能偶校验;11:使能奇校验)
#define UPM0 4 //
#define USBS 3 // 停止位选择(0:1位停止位;1:2位停止位)
#define UCSZ1 2 // UCSZ【1:0】传送或接收字符长度,UCSZ[2:0](000:5;001:6;010:7;011:8;100:保留;101:保留;110:保留;111:9)
#define UCSZ0 1 //
#define UCPOL 0 //时钟极性选择(同步模式下使用,异步模式下为0)
#define DATA_REGISTER_EMPTY (1<<UDRE)
interrupt [USART_RXC] void usart_rx_isr(void) // USART接收中断服务
{
UCSRB&=~(1<<RXCIE); //关接收中断
data=UDR; //读取UDR得到接收的数据
flag=1; //标志位置1
UCSRB|=(1<<RXCIE); //开接收中断
}
//发送数据
void USART_Transmit(unsigned char data)
{
while (!(UCSRA & DATA_REGISTER_EMPTY)); // 等待发送寄存器空
UDR = data; // 发送数据
}
void main( void )
{
PORTD = 0x03; // TXD(PD1)输出
DDRD = 0x02; // RXD(PD0)输入,上拉有效
UCSRA = 0x00; // USART初始化
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); // 允许RXC中断,接收允许,发送允许
//UCSRB = 0x98;
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // 8 Data, 1 Stop, No Parity
//UCSRC = 0x86;
UBRRH = BAUD_H; // 设置波特率
UBRRL = BAUD_L;
#asm("sei") // 开中断
while(1)
{
if(flag==1) //接收到数据
{
USART_Transmit(data); //发送数据
flag=0;
}
}
}