📄 uart.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 + -