📄 uart.c
字号:
/************************************************************************
;* 公 司: xx
;* 模 块: serial.c
;* 功 能: 串口中断服务程序,仅需做简单调用即可完成串口输入输出的处理;
;* 出入均设有缓冲区,大小可任意设置
;* 芯 片: AMEGA16
;* 说 明: 未利用串口发送硬件BUFF
;* 设 计: 李耀峰
;* 时 间: 2005-11-24
;* 版 本: V1.0
;* 记 录:
;************************************************************************/
/************************************************************************
可供使用的函数名:
extern void PutByte(U8 c); //放入一个字节到发送缓冲区
extern void PutString(U8 *puts); //发送一个定义在程序存储区的字符串到串口
extern void PutBytes(U8 *outplace,U8 j); //发送一串数据
extern void PutHEX(U8 c); //发送一个字节的hex码,分成两个字节发
extern U8 GetByte (void); //从接收缓冲区取一个byte
extern void SerialInit (U16 baud); //串口初始化
extern U8 inbufsign; //接收缓冲区数据,有数据=1。
#define CR PutString("\r\n") //发送一个回车换行
#define NUL putstring("\0") //发送一个空格
*************************************************************************/
#include <avr \io.h>
//#include <macros.h>
#include "interrupt.h"
#include "avr\signal.h"
#include "Uart.h"
#define U8 unsigned char
#define U16 unsigned int
U8 outbuf[OLEN]; //发送缓冲
U8 inbuf[ILEN]; //接收数据缓冲
U8 *outlast = outbuf; //最后由中断传输出去的字节位置
U8 *putlast = outbuf; //最后放入发送缓冲区的字节位置
U8 *inlast = inbuf; //最后接收到接收缓冲区的字节位置
U8 *getlast = inbuf; //最后从发送缓冲区取走的字节位置
//#define inbufsign bit_flag.bit3 //接收缓冲区非空标志 有=1
//U8 outbufsign0; //缓冲区数据发完标志 发完=0
//U8 outbufsign; //发送缓冲区非空标志 有=1
//U8 inbufful; //接收缓冲区满标志 满=1
U8 inbufsign; //接收缓冲区非空标志 有=1
struct data bit_flag;
//**********************************************************************
//函 数 名: void PutByte(U8 c)
//功 能: 放入一个字节到发送缓冲区
//说 明:
//参 数:
//返 回 值:
//示 范: PutByte(0x00);
//***********************************************************************
void PutByte(U8 c)
{
cli(); //暂停串行中断,以免数据比较时出错
while
(
(((outlast - putlast) == 2) && (outlast > putlast)) ||
((outlast < putlast) && (OLEN - (putlast - outlast) == 2))
)
{
sei();
c++;
c--;
cli();
}
*putlast = c; //放字节进入缓冲区
putlast++; //发送缓冲区指针加1
if(putlast == outbuf + OLEN)
putlast = outbuf; //指针到了顶部换到底部
outbufsign = 1;
if(!outbufsign0) //缓冲区无数据
{
outbufsign0 = 1;
UDR = *outlast; //未发送完继续发送
outlast++; //最后传出去的字节位置加1
if(outlast == outbuf + OLEN)
outlast = outbuf; //地址到顶部回到底部
if(putlast == outlast)
outbufsign = 0; //数据发送完置发送缓冲区空标志
} //缓冲区开始为空置为有,启动发送
sei();
}
//**********************************************************************
//函 数 名: void PutString(U8 *puts)
//功 能: 发送字符串到串口
//说 明:
//参 数: 发送的字符串
//返 回 值:
//示 范: putstring("\r\n")
//***********************************************************************
void PutString(U8 *puts)
{
for(; *puts != 0; puts++) //遇到停止符0结束
PutByte(*puts);
}
//**********************************************************************
//函 数 名: void PutBytes(U8 *outplace,U8 j)
//功 能: 放一串数据到发送缓冲区,需要定义发送的字节数
//说 明:
//参 数: *outplace:发送的字节数据首地址指针 j:发送的字节数量
//返 回 值:
//***********************************************************************
void PutBytes(U8 *outplace, U8 j)
{
int i;
for(i = 0; i < j; i++)
{
PutByte(*outplace);
outplace++;
}
}
//**********************************************************************
//函 数 名: PutHEX(unsigned char c)
//功 能: 发送一个字节的hex码,分成两个字节发。
//说 明: 发送ASSIC码
//参 数: 发送的数据
//返 回 值: 无
//示 范: PutHEX(i);
//***********************************************************************
const U8 hex_[] = { "0123456789ABCDEF" };
void PutHEX(U8 c)
{
U16 ch;
ch = (c >> 4) & 0x0f;
PutByte(hex_[ch]);
ch = c & 0x0f;
PutByte(hex_[ch]);
// SPACE;
}
//**********************************************************************
//函 数 名: U8 GetByte (void)
//功 能: 从接收缓冲区取一个U8
//说 明: 如不想等待则在调用前检测inbufsign是否为1
//参 数: 无
//返 回 值: 接收到的数据
//示 范: i=GetByte();
//***********************************************************************
U8 GetByte(void)
{
char c;
while(!inbufsign);
//缓冲区空等待
cli();
c = *getlast; //取数据
getlast++; //最后取走的数据位置加1
inbufful = 0; //输入缓冲区的满标志清零
if(getlast == inbuf + ILEN)
getlast = inbuf; //地址到顶部回到底部
if(getlast == inlast)
inbufsign = 0; //地址相等置接收缓冲区空空标志,再取数前要检该标志
sei();
return (c); //取回数据
}
//**********************************************************************
//函 数 名: void SerialSend_handler (void)
//功 能: 串口发送中断处理
//说 明:
//参 数:
//返 回 值:
//***********************************************************************
SIGNAL(SIG_UART_TRANS)
{
UCSRA |= (1 << TXC); //清发送中断标志
if(outbufsign)
{
UDR = *outlast; //未发送完继续发送
outlast++; //最后传出去的字节位置加1
if(outlast == outbuf + OLEN)
outlast = outbuf; //地址到顶部回到底部
if(putlast == outlast)
outbufsign = 0; //数据发送完置发送缓冲区空标志
} else
{
outbufsign0 = 0;
}
}
//**********************************************************************
//函 数 名: void SerialIncept_handler (void)
//功 能: 串口接收中断处理
//说 明:
//参 数:
//返 回 值:
//***********************************************************************
SIGNAL(SIG_UART_RECV)
//void SerialIncept_handler (void)
{
if(!inbufful) //接收缓冲区未满
{
*inlast = UDR; //放入数据
inlast++; //最后放入的位置加1
inbufsign = 1;
if(inlast == inbuf + ILEN)
inlast = inbuf; //地址到顶部回到底部
if(inlast == getlast)
inbufful = 1; //接收缓冲区满置满标志
}
}
/**********************************************************************
函 数 名: void SerialInit (unsigned long)
功 能: 串口初始化
说 明: 串口初始化成指定波特率,开接收,发送并开相应中断
参 数: 需要初始化的波特率
返 回 值: 无
示 范: SerialInit (38400);
***********************************************************************/
void SerialInit(void)
{
cli();
UCSRC &= (~(1 << URSEL));
// UBRRH=(U8)(baud>>8);
UBRRH = 0x00;
// UBRRL=(U8)baud;
UBRRL = 0x5; // 115200 @ 11.0592M
UCSRB = (1 << RXCIE) | (1 << TXCIE) | (1 << RXEN) | (1 << TXEN);
//接收中断使能,发送中断使能,接收器与发送器使能
UCSRC = (1 << URSEL) | (3 << UCSZ0); //设置帧格式: 8 个数据位, 1 个停止位*/
sei(); //开全局中断
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -