这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 串口缓冲池的遍历,恳请帮忙改正!(有源码)

共2条 1/1 1 跳转至

串口缓冲池的遍历,恳请帮忙改正!(有源码)

院士
2006-09-17 18:14:16     打赏
串口缓冲池的遍历,恳请帮忙改正!(有源码)



关键词: 串口     缓冲     遍历     恳请     帮忙     改正     源码    

院士
2006-12-22 22:43:00     打赏
2楼
问 现在做一通信程序,从串口进来数据以9600bps、500~800bytes/秒的速率进入缓冲区,然后主循环中以环形队列格式进行处理,从数据区中提取出所需的不同格式的消息。部分源码如下:
//-------------------------------------------------------------------------------------
//   队列管理标志
//-------------------------------------------------------------------------------------
bit   Overflow(void)
{
    return((r_in-r_out)>(MaxSize-1)?1:0);
}
bit  Empty(void)
{
    return((r_in-r_out)<0?1:0);
}
bit   Full(void)
{
    if (!Overflow() && !Empty())
    return(1);
    else return(0);
}

main.c

...
while(1)
{
if (Full())
        {
            
            if (GpgsaHeader(&r_buf[r_out&0x7ff]))
            {
                a_count ++;
                iLengthTemp = Ender(&r_buf[r_out&0x7ff]);
                GpgsaSol(&r_buf[r_out&0x7ff]);
                r_out += iLengthTemp;

            }
            else if (GpgsvHeader(&r_buf[r_out&0x7ff]))
                {
                    v_count ++;
                    iLengthTemp = Ender(&r_buf[r_out&0x7ff]);
                    GpgsvSol(&r_buf[r_out&0x7ff]);
                    r_out += iLengthTemp;
                }
                else if ( BinMesHead(&r_buf[r_out&0x7ff]))
                    {
                        b_count ++;
                        iLengthTemp=(r_buf[(r_out+9)&0x7ff] << 8 )+r_buf[(r_out+8)&0x7ff];
    
                        if (iLengthTemp>0 && iLengthTemp < 4096)
                        {
                            r_out +=iLengthTemp+32;
                        }
                        
                    }
             r_out ++;
        }
}

现在主要有几个问题:
1.如何控制队列的指针,不让r_out > r_in(通过仿真发现确实有超出)?
2.如何等待r_in相对r_out足够大,使得队列中已经正确存贮了一条或多条完整的消息?
3.能否帮忙分析一下以上程序的原理性错误?
4.能否提供一些相关的例程做参考?如有,请发EMAIL:nantiangumo@163.com

先谢谢各位啦!


1: 个人见解最好是使用循环队列 他的使用效率是最高的
在线形队列的基础上加上 头 尾 缓冲长度的变量即可 访问时注意地址跨界是的操作即可。 2: 这是我在用的一个环形缓冲区byte idata Uart_loop_buff[128];
byte data  Uart_read_ptr  = 0;
byte data  Uart_write_ptr = 0;
byte data  Uart_rcv_state = 0;


void  Uart_Int(void) interrupt 4
{
    if(RI)
    {
        RI = 0;
        TI = 0;
        Uart_loop_buff[Uart_write_ptr] = SBUF;
        Uart_write_ptr = (Uart_write_ptr++)&0x7F;
    }
}

void  Uart_rcv_frame(void)
{
    static byte       step = 0;
    static byte  rcv_count = 0;  /*接收计数*/
    word   data  i = 0;
    word   data  j = 0;
    word   data     crc_temp = 0;
    
    switch(step)
    case 0:
        if(Uart_read_ptr==Uart_write_ptr)
            return;
        
        if(Uart_loop_buff[Uart_read_ptr]!=Msg_head)
        {
            Uart_read_ptr = (Uart_read_ptr++)&0x7F;
            return;
        }
        Uart_rcv_buff[Uart_rcv_length] = Uart_loop_buff[Uart_read_ptr];
        Uart_read_ptr = (Uart_read_ptr++)&0x7F;
        Uart_rcv_length++;
        step++;
        rcv_count++;
        Set_Soft_Timer(0,6)
    break;
    case 1:
        while(Uart_read_ptr!=Uart_write_ptr)
        {
            Uart_rcv_buff[Uart_rcv_length] = Uart_loop_buff[Uart_read_ptr];
            Uart_read_prt++;
            Uart_rcv_length++;
            rcv_count++;
            if(!Soft_timer[0])
                break;
        }
。。。

我的建议缓冲区大小由你的数据流及单片机处理能力决定,最好大些,防止溢出 3: ding two... 4: 真搞不明白,都是库函数惹的祸找信息头的时候用函数memcmp()来比对就要掉信息,非得一个个字符地比较,基本上解决

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]