⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 AVR mega16/mega32的UART FIFO发送.超时接收,广泛应用于工业控制.这是原创作品.
💻 C
字号:
//--------------------------------------------------------------------
//
//							FIFO 发		超时收
//
//
//--------------------------------------------------------------------
#include "system.h"


volatile unsigned char UartSendBuffer[OutLEN];			//发送缓冲 
volatile unsigned char UartReceiveBuffer[InLEN];		//接收数据缓冲 
volatile unsigned char *outlast=UartSendBuffer;			//最后由中断传输出去的字节位置 
volatile unsigned char *putlast=UartSendBuffer;			//最后放入发送缓冲区的字节位置 
volatile unsigned char UartSendBufferemptyFlag=1;		//缓冲区数据发完标志   发完=1
volatile unsigned char UartSendBufferHaveDataFlag=0;	//发送缓冲区非空标志   有=1 

volatile unsigned char UartReceiveCounter=0;			//接收计数器
volatile unsigned char UartTimeoutFlag=0;				//接收超时计数器启动标志
volatile unsigned char WaitForUartCounter=0;			//接收超时计数器
volatile unsigned char UartDataReadyFlag=0;				//接收完成标志

void UartInit(void) 		//串口初始化 
{ 
    UCSRC&=(~(1<<URSEL)); 
    UBRRH=(unsigned char)(UBRR>>8); 
    UBRRL=(unsigned char)UBRR; 
    UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN); //接收中断使能,发送中断使能,接收器与发送器使能                                  
    UCSRC=(1<<URSEL)|(3<<UCSZ0);	//设置帧格式: 8 个数据位, 1 个停止位
}

void UartSendchar(unsigned char data)	//放入一个字节到发送缓冲区 
{ 
	unsigned int i=0;
	UCSRB&=~(1<<TXCIE); 					//暂停串行中断,以免数据比较时出错 
    //////////////////////////////////////////////////////////////////////////////

    while(abs(outlast-putlast)==2)
    { 
		_delay_ms(2);//根据波特率调整此处的延时大小
		break;
    } 

	/////////////////////////////////////////////////////////////////////////////
    *putlast=data;			//放字节进入缓冲区 
    putlast++;          	//发送缓冲区指针加1 
    if (putlast==UartSendBuffer+OutLEN) putlast=UartSendBuffer;  //指针到了顶部换到底部 
    UartSendBufferHaveDataFlag=1; 
    if (UartSendBufferemptyFlag) 		//缓冲区无数据 
    { 
        UartSendBufferemptyFlag =0; 
        UDR=*outlast;    	//未发送完继续发送 
        outlast++;        	//最后传出去的字节位置加1 
        if (outlast==UartSendBuffer+OutLEN) outlast=UartSendBuffer;//地址到顶部回到底部 
        if (putlast==outlast) UartSendBufferHaveDataFlag=0;     //数据发送完置发送缓冲区空标志 
    }//缓冲区开始为空,置为有,启动发送 
	UCSRB|=(1<<TXCIE);
} 

void UartSendString(unsigned char *str) //发送字符串到串口 
{ 
	while(*str)				//遇到停止符0结束 
	{
		UartSendchar(*str++);   
	}
} 

void UartSendByte(unsigned char *Startaddr,unsigned char SendByte) //发送一串数据
{   
	while(SendByte--)
	{
		UartSendchar(*Startaddr++); 
	}
} 

ISR(USART_TXC_vect)			//串口发送中断处理 
{ 
	UCSRA|=(1<<TXC); 		//清发送中断标志 
	if (UartSendBufferHaveDataFlag) 
	{ 
		UDR=*outlast; 		//未发送完继续发送 
		outlast++; 			//最后传出去的字节位置加1 
		if (outlast==UartSendBuffer+OutLEN) outlast=UartSendBuffer;	//地址到顶部回到底部 
		if (putlast==outlast) UartSendBufferHaveDataFlag=0;		//数据发送完置发送缓冲区空标志 
	} 
	else UartSendBufferemptyFlag =1; 
} 

ISR(USART_RXC_vect)			//串口接收中断处理 
{ 
	UartReceiveBuffer[UartReceiveCounter]=UDR;	//存入数据
	UartTimeoutFlag=1;							//启动超时计数器
	WaitForUartCounter=0;						//清超时计数器	//5ms
	UartReceiveCounter++;
	if(UartReceiveCounter>=InLEN) 
	{
		UartDataReadyFlag=1;
		UCSRB&=~(1<<RXCIE);						//禁止接收
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -