分享

基于STM32芯片环形缓冲区的构建(IAR EWARM环境)

 昵称25698214 2015-06-22

除了通信协议以外,设置数据缓冲区是完善不同速率,或不同系统之间通信的解决方案之一。本文设置了一个环形缓冲区,来接收PC上位机通过串口(COM口)发往STM32下位机数据,具体代码如下:


 


//接受数据处理相关定义


 


#define RxSize 16           //接收缓冲区大小


u8 RxBuffer[RxSize];   //缓冲区定义


u8 RxPut = 0;  //接收缓冲区(环形)的当前放人位置


u8 RxGet = 0;  //接收缓冲区()的当前取出位置


u8 RxEff = 0;   //接收缓冲区(环形)中的元素总数量


 


//利用去除存入缓冲区数据的冗余信息后,将有用数据存入命令缓存


u8 command[7];  //命令缓存,用于存放收到的命令(最长命令为五个字符,其中加上起始符和结尾符,共7个字符)


u8 comm_length; //命令长度,命令解码时用


 


 


//接受缓冲区读取函数


u8 Address(u8);


void put(u8 z);


u8 get(void);


 


 


void decode(void);//解码程序


void get_command(u8 c);     //识别命令格式,并存入命令缓冲区


 


 


//函数实现


/*******************************************************************************


环形缓冲区的地址编号计算函数,,如果到达唤醒缓冲区的尾部,将绕回到头部。


环形缓冲区的有效地址编号为:0 RxSize


 


*******************************************************************************/


//接受缓冲区地址运算


u8 Address (u8 i)


{


        return (i+1)==RxSize ? 0 : i+1;


}


 


//从环形缓冲区中取一个元素


u8 get(void)


{


    u8 pos;


    if (RxEff>0)


      {


              pos = RxGet;


              RxGet = Address(RxGet);


              RxEff--;


              return RxBuffer[pos];


      }


    else


      return '~';  //标志缓冲区中的数据被读完


 


}


 


 


//向环形缓冲区中放人一个元素


void put(u8 z)


{


    if (RxEff<RxSize)


    {


               RxBuffer[RxPut]=z;


               RxPut = Address(RxPut);


               RxEff++;


    }


    //else


    //;          //若缓冲区为满,则放弃当前数据


}


 


//缓冲区的应用


/*******************************************************************************


* Function Name  : USART1_IRQHandler


* Description    : This function handles USART1 global interrupt request.


* Input          : None


* Output         : None


* Return         : None


*******************************************************************************/


void USART1_IRQHandler(void)   //利用串口中断,来填充缓冲区


{


 


  if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)//检查EXTI_Line3线路触发请求发生与否,若发生中断目前将不被执行(即保持原先各种操作)


  {


     u8 z;


    z=(u8)( USART_ReceiveData(USART1)& (u8)0xFF);


   


    if(z == '%') //单字符命令处理函数   //联机状态软件控制部分


              {


                  para_send((u8)('%'),0); //同意联机  (此处SBUF为发送缓冲器:发送确认信号)


                  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等待发送完成


                }


    else   // C为除'%',其他字符(多字符命令处理函数)---先将命令存入缓冲区


              {


                     put(z);  //字符送入缓冲区


              }


   


    /* Clear the USART_IT_RXNE pending bit */


   // USART_ClearITPendingBit(USART1,USART_IT_RXNE);   //清除EXTI线路挂起位,标志当前中断已经发生


    


  }


}


 


main函数中的while循环中,读取缓冲区数据,并做相关响应


main(void)


{


#ifdef DEBUG


     debug();


#endif


      


/* 调用各外设配置函数,使外设处于工作状态 -----------------------------------*/


 /* 写解调体统核心程序 -----------------------------------*/


   


  while(1)


  {


       c = get();   //读缓冲区


       get_command(c);     //命令解析(数码管显示相应命令,并置stopflag以便于下属语句驱动电机)


                                 //根据解析代码实现电机运行相关参数设置


        if(stopflag==1)      //根据解析参数正常运行


           {


              curPosition=GoSteps1(steps,direction,curPosition);


           


            }     //按指定方向,连续运行steps


        else if(stopflag==2)   //复位代码(向右复位)


            {


              stepfm=curPosition - Osteps;


              curPosition=GoSteps1(stepfm,RIGHT,curPosition);


            } 


        else if(stopflag==3)   //复位代码(向左复位)


            {


              stepfm= Osteps-curPosition ;


              curPosition=GoSteps1(stepfm,LEFT,curPosition);


           


            }   


        else if(stopflag==4)   //复位代码(不动)


            {


              curPosition=GoSteps1(0,RIGHT,curPosition);


            }  


        else if(stopflag==5)   //单步运行


            {


             curPosition=GoSteps1(1,direction,curPosition);


            }  


  }


}


 


附录:


void get_command(u8 c)      //识别命令格式,并存入命令缓冲区command[comm_length]


{


 


  if(c == '@')//命令字开始


       {


              comm_length = 0;


       }


  else if(c == '$')//命令字结束


       {


              decode();//执行解命令,对stopflag赋值  


       }


  else if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'))


       {


              command[comm_length] = c; //指令字符放入命令缓存


              comm_length++;   


       }    


      


  else


       {


                       //空语句


       }


}




【转自:http://bbs./BLOG_ARTICLE_269940.HTM】

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多