/*
-----------------------------------------------------------------------------------------
工程:
Test系列工程
环境:
AVR Studio4.17 + WinAVR2010
设备:
Atmega16
作者:
遥远的海
日期:
2015-07-11
说明:
异步串行通信 (115200 8 N 1)
-----------------------------------------------------------------------------------------
*/
#include
//---------------------------
//宏定义
//---------------------------
#define TRUE (U8)1
#define FALSE (U8)0
//---------------------------
//数据类型
//---------------------------
typedef unsigned char U8;
typedef signed char S8;
typedef unsigned int U16;
typedef signed int S16;
typedef unsigned long U32;
typedef signed long S32;
//---------------------------
//空指令
//---------------------------
#define NOP() __asm("nop")
//---------------------------
//总中断
//---------------------------
#define EN_INT() sei() //开中断
#define DS_INT() cli() //关中断
/*
-----------------------------------------------------------------------------------------
USART
-----------------------------------------------------------------------------------------
*/
#define UART_BUF_LEN 32 //串口收发缓冲区长度
#define UART_TIME_OUT 500 //超时控制
//串口发送缓存
static U8 m_SndBuf[UART_BUF_LEN];
static U8 *pSnd;
static U8 *pSnE; //发送缓存尾部
//串口接收缓存
static U8 m_RcvBuf[UART_BUF_LEN];
static U8 *m_pE; //接收缓冲尾部
static U8 *m_pW; //缓冲区写指针
//数据接收完标志
volatile static U8 m_ucFlag;
/*
-----------------------------------------------------------------------------------------
USART接收中断,每收到一个字符产生一个中断
-----------------------------------------------------------------------------------------
*/
ISR(SIG_UART_RECV)
{
volatile U8 ucTmp;
//帧错误、溢出错误、奇偶校验错误
if((UCSRA & ( (1<0 )
ucTmp=UDR; //读取并丢弃数据
else
{
*m_pW++=UDR; //读取串口数据并写入到串口缓存
//写指针到接收缓存尾部
if(m_pW>=m_pE)
{
m_pW=m_RcvBuf; //写指针指向接收缓存头
m_ucFlag=TRUE; //UART_BUF_LEN 个数据接收完
}
}
}
/*
-----------------------------------------------------------------------------------------
USART发送完中断,每发送完一个字符产生一次中断
-----------------------------------------------------------------------------------------
*/
ISR(SIG_UART_TRANS)
{
if(pSnd
{
UDR=*pSnd++;
}
else
pSnd=m_SndBuf;
}
/*
-----------------------------------------------------------------------------------------
串口初始化
进行通信之前首先要对USART 进行初始化。初始化过程通常包括波特率的设定,帧结构
的设定,以及根据需要使能接收器或发送器。对于中断驱动的USART 操作,在初始化时
首先要清零全局中断标志位( 全局中断被屏蔽)。
-----------------------------------------------------------------------------------------
*/
void UART_Init(void)
{
int i=0;
m_ucFlag=FALSE;
m_pW=m_RcvBuf;
m_pE=m_RcvBuf+UART_BUF_LEN;
//初始化发送缓存
for(i=0;i
m_SndBuf=i;
pSnd=m_SndBuf;
pSnE=pSnd+UART_BUF_LEN;
DDRD|=(1<
//先关闭串口所有收发功能
UCSRB=0x00;
UCSRA=0x00;
//UCSRC寄存器与UBRRH寄存器共用相同的I/O地址,Bit 7 – URSEL=1时访问UCSRC
//Bit 6 – UMSEL: USART 模式选择,0 异步操作
//Bit 3 – USBS=0 设置1位停止位
//Bit 2:1 – UCSZ1:0: 字符长度,1:1 选择 8 位数据
//Bit 0 – UCPOL: 时钟极性,这一位仅用于同步工作模式。使用异步模式时,将这一位清零
UCSRC= (1<
//波特率设置 fosc = 16.0000 MHz,115200 ,UBRR=8
UBRRH=0x00; //UBRRH 保存波特率系数高 4 位
UBRRL=0x08; //UBRRL 保存波特率系数低 8 位
//Bit 7 – RXCIE: 接收结束中断使能
//Bit 4 – RXEN: 接收使能,置位后将启动USART 接收器。
// RxD 引脚的通用端口功能被USART 功能所取代
//Bit 3 – TXEN: 发送使能,置位后将启动将启动USART 发送器。
// TxD 引脚的通用端口功能被USART 功能所取代
//Bit 2 – UCSZ2: 字符长度,UCSRC寄存器的UCSZ1:0
// 结合在一起可以设置数据帧所包含的数据位数
//接收与发送器(管脚功能)使能,中断等
UCSRB=(1<
}
/*
-----------------------------------------------------------------------------------------
发送数据
-----------------------------------------------------------------------------------------
*/
U8 UART_Write(U8 ucData)
{
U16 timeOut=UART_TIME_OUT;
while(!(UCSRA&(1<
{
if(--timeOut==0) //超时控制
return FALSE;
}
UDR=ucData; //将数据发送出去
return TRUE;
}
/*
-----------------------------------------------------------------------------------------
查询方式读数据
-----------------------------------------------------------------------------------------
*/
U8 UART_Read(void)
{
while(!(UCSRA&(1<
return UDR;
}
/*
-----------------------------------------------------------------------------------------
函数:
main
功能:
C 语言主函数
入口:
void
出口:
int
备注:
无
-----------------------------------------------------------------------------------------
*/
int main(void)
{
UART_Init();
//开总中断
EN_INT();
//启动一次发送,m_SndBuf中的32个数据将全部在中断中自动发送
UART_Write(*pSnd++);
while(1)
{
//接收数据在中断中完成
if(m_ucFlag)
{
//拷贝接收到的数据到发送缓存
memcpy(m_SndBuf,m_RcvBuf,UART_BUF_LEN);
//重置发送指针到发送缓存头
pSnd=m_SndBuf;
//启动一次发送,将接收到的32个数据发送到串口
UART_Write(*pSnd++);
m_ucFlag=FALSE;
}
}
return 0;
}
程序一开始向上位机发送32个预定义数据,之后接收上位机发来的数据。当接收缓存满(32字节),程序会将接收到的32个数据重新发给上位机。
“勿在浮沙筑高台”
遥远的海
(待续)