看过很多朋友写的单片机串口收发程序,每个人都不一样.通过实际开发经验,本文提出一种新颖的思路.
串口收发速度很慢,单片机内部工作速度很快,所以在这种情况下,可做两个soft fifo -- receive fifo 和 transmit fifo,接收和发送数据就可以对各自的fifo来进行操作,比如,当接收到新的数据时候,产生中断,中断中只把接收到的数据放到receive fifo里,然后将receive fifo写地址加一即可,节省了很多时间.主程序里就可以检测receive fifo的读写地址是否一样来做判断,如果一样,说明没有收到数据,否则接收到新的数据,读完后将读地址加一.注意写地址和读地址大于预定义的长度时要及时清零.发送情况和此一样不在阐述.
下面为初始化函数和接收函数:
#define LenBuf 0x20
data unsigned char *head_pt; // 接收头指针
data unsigned char *tail_pt; // 接收尾指针
data unsigned char uart_buff[LenBuf]; // 接收缓冲区
#define START_PT &uart_buff[0] // 头指针
#define END_PT &uart_buff[LenBuf] // 尾指针
//初始化接收读写地址指针
head_pt = START_PT;
tail_pt = START_PT;
//中断函数
void Uart0_ISR(void) interrupt 4 using 2
{
if(RI==1)
{
RI=0;
*head_pt=SBUF; //读入数据
head_pt++; // 地址增加
if(head_pt==END_PT) head_pt=START_PT; //防止缓 冲区益出
}
}
//接收函数
unsigned char ComGetChar() //串口0接收字符
{
unsigned char i;
i=*tail_pt; //读取数据
tail_pt++; //地址增加
if(tail_pt==END_PT) //防止益出
tail_pt=START_PT;
return i;
}
//主程序
void main (void)
{
//初始化
.....
while(1)
{
if(tail_pt != head_pt)
{
RcDat = GetChar(); //接收数据
......... 判断处理
}
}
}
可根据需要设计一个长度标志,初始化为0,接收一次加1,来判断接收到的是一桢中的第几个数.
也可以根据需要加上时间限制,比如200ms没有接收到数请求再发等等.
本文只是简单提出一个思路,发送部分大家可以自己加上去.本思路也可用于其他大数据传输中去,也可方便移植到其他型号的单片机中去.本代码已经应用于很多的实际项目中去,工作稳定可靠!
最后祝愿大家2008 发发发!
看大家的回复情况,我可以把此源代码发上来,那就赶快顶吧!
用户137991 2008-4-2 22:27