jianplx 发表于 2014-8-28 09:25:42

最近在玩广彩的串口屏,改了接收协议,好像还可以。

本帖最后由 jianplx 于 2014-8-28 09:34 编辑



栈尾que._tail永远指向帧头EE,指令取走后会自动指向下一条指令的帧头,找指令时可以直接用que._tail做基指
#define QUEUE_MAX_SIZE 32

typedef struct _QUEUE
{
    unsigned char _head;                                        //数据栈头指针
    unsigned char _tail;                                        //数据栈尾指针
    unsigned char _data;       
} QUEUE;//串口数据接收队列结构体

static QUEUE que = {0,0,};                                        // 串口数据接收列队

/**********************************************
串口接收队列(FIFO)复位
**********************************************/
void QueueReset(void)
{
        que._head = 0;
        que._tail = 0;
}
/**********************************************
存入一个数据到串口接收队列(FIFO)中
**********************************************/
void QueuePush(unsigned char _data)
{
    unsigned char pos;
        pos = (que._head+1) %QUEUE_MAX_SIZE;
       
    if(pos != que._tail)                                //非满状态
    {
      que._data = _data;        //数据压栈
      que._head = pos;                                //移动栈头
    }
}
/**********************************************
搜寻帧头
**********************************************/
static void FindFrameHead(void)
{
        while(que._data != 0xEE && que._head != que._tail)
                que._tail = (que._tail+1) %QUEUE_MAX_SIZE;        //栈尾指向下一个指令头部       
}
/******************************************************************
获取串口接收队列(FIFO)中一个完整的帧
一个完整的帧是以EE开头,FF FC FF FF 结尾的一个数据帧
EE xx xx xx xx ee xx xx ff fc FF FC FF FF
********************************************************************/
unsigned char QueueFindCMD(void)
{       
        unsigned char cmd_tail;        //影子栈尾
        unsigned char cmd_state;       
       
        if(que._head == que._tail)        //是空栈
        {
                return 2;                                // 空栈       
        }
               
        if(que._data != 0xEE)        //栈尾不是指令的头部        
        {
                FindFrameHead();        //搜寻下一个指令头部
                return 3;                        //指令头部错误       
        }
       
        cmd_tail = que._tail;        //映射栈尾
        cmd_state = 0;                       
           while(que._head != cmd_tail && cmd_state != 4)        //查找帧尾 从栈尾查到栈头
           {       
                cmd_tail = (cmd_tail+1) %QUEUE_MAX_SIZE;

                switch(que._data)                //查找帧尾
                {
                        case 0xFF:
                        switch (cmd_state)
                        {
                                case 2: cmd_state = 3;break;//FF FC FF ?? (找到第三个FF)
                                case 3: cmd_state = 4;break;//FF FC FF FF 正确的帧尾
                                default:cmd_state = 1;break;//FF ?? ?? ??(找到第一个FF)
                        }break;

                        case 0xFC:
                        switch (cmd_state)
                        {
                                case 1: cmd_state = 2;break;//FF FC ?? ??(找到第二个FC)
                                case 3: cmd_state = 2;break;//ff fc FF FC ?? ??(找到第二个FC)
                                default:cmd_state = 0;break;//?? ?? ?? ??(全部字节不对)
                        }break;

                        default: cmd_state = 0;
                        break;
                }
        }

       
        if(cmd_state == 4)        // 没有找到指令帧尾       
        {
                FindCMD();//取走指令
                que._tail = (cmd_tail+1)%QUEUE_MAX_SIZE;//指向下一条指令
                //que._tail = que._head;
                return 0;                       
        }
       
        return 1;        //没有接收完成               
}

anyanggcmy 发表于 2014-8-29 16:14:20

牛人啊,学习了

你是否还记的 发表于 2014-8-29 16:31:10

喜欢看程序,

真的好多巧合 发表于 2014-12-18 09:47:34

正要弄串口屏,浏览下资料{:smile:}
页: [1]
查看完整版本: 最近在玩广彩的串口屏,改了接收协议,好像还可以。