https://mp.csdn.net/mp_blog/creation/editor/136912188
在博主的前篇文章中很多大神私信博主说,在接收数据时只能等接收完毕才能进行发送,在发送时不能进行接收。这与单片机的串口是全双工而相矛盾。
下面博主将对程序进行优化,以达成全双工,接收发送同步的目的。
在下面程序中,我们继续以C8051F410单片机为例。
#include "C8051F410.h"
#define tbuf_size 32//定义发送缓存区大小
#define rbuf_size 32//定义接收缓存区大小
static TBUF_SPACE unsigned char tbuf [TBUF_SIZE];//定义发送缓存数组
static RBUF_SPACE unsigned char rbuf [RBUF_SIZE];//定义接收缓存数组
static CTRL_SPACE unsigned char t_in = 0;//发送缓存区进入指针
static CTRL_SPACE unsigned char t_out = 0;
static CTRL_SPACE unsigned char r_in = 0;//接收缓存区进入指针
static CTRL_SPACE unsigned char r_out = 0;
static bit ti_restart = 0;//发送标志位
void Com0_Init (void)//串口初始化函数
{
t_in = 0;
t_out = 0;
r_in = 0;
r_out = 0;
RI0 = 0;
TI0 = 0;
ti_restart = 1;
}
static void Com0_ISR (void) interrupt 4//串口中断函数
{
if (RI0 != 0)
{
RI0 = 0;
if (((r_in - r_out) & ~(RBUF_SIZE-1)) == 0)
{
rbuf [r_in & (RBUF_SIZE-1)] = SBUF0;
r_in++;
}
}
if (TI0 != 0)
{
TI0 = 0;
if (t_in != t_out)
{
SBUF0 = tbuf [t_out & (TBUF_SIZE-1)];
t_out++;
ti_restart = 0;
}
else
{
ti_restart = 1;
}
}
}
unsigned char Com0_getRBufLen (void)//获取接收缓存区长度
{
return (r_in - r_out);
}
static unsigned char Com0_getTBufLen (void)//获取发送缓存区长度
{
return (t_in - t_out);
}
static char Com0_putByteToBuf ( unsigned char b)//将字符放入缓存区
{
if (Com0_getTBufLen () >= TBUF_SIZE)
{
return (-1);
}
tbuf [t_in & (TBUF_SIZE - 1)] = b;
t_in++;
if (ti_restart)
{
ti_restart = 0;
TI0 = 1;
}
return (0);
}
static int Com0_getByteFromBuf (void)//从缓存区读取字节
{
if (Com0_getRBufLen () == 0)
{
return (-1);
}
unsigned char Com0_getByte (void)//获取一个字节数据
{
int k;
do
{
Idle();
k = Com0_getByteFromBuf ();
}
while (k == -1);
return ((unsigned char) k);
}
return (rbuf [(r_out++) & (RBUF_SIZE - 1)]);
}
void Com0_sendByte (unsigned char b)//发送字节
{
volatile unsigned int i;
while (Com0_putByteToBuf (b) != 0) //UART0
{
for (i=0; i<1000; i++)
{
Idle();
}
}
}
以上是博主所写的串口全双工同步函数,所需主程序(main)需要根据需求进行编写。
如果各位大神看出博主有错误,可以在博文下评论或者私信博主,博主会积极回复,进行更改。
感谢各位大神的阅读,点赞,评论。