1 Star 1 Fork 2

过期可乐 / 自定义串口协议

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ustate_machine.c.c 5.12 KB
一键复制 编辑 原始数据 按行查看 历史
过期可乐 提交于 2022-04-05 21:44 . con't find bug
#include "ustate_machinie.h"
/*有限状态机初始化*/
void Create_ComUsart(Usart_Trm *Me,uint8_t set_h,uint8_t set_t)
{
static struct Usart_vtable vtable;
my_memset(Me,0,sizeof(Usart_Trm));
vtable.rx_buff=&Com_rxUsart_data;
vtable.fram_deal=&Deal_com;
vtable.fram_num=&Get_fram_num;
Me->c_vptr=&vtable;
Me->head=set_h;
Me->teal=set_t;
Me->usart_status=STATUS_IDEL;
}
/*有限状态机读入缓存函数*/
void Com_rxUsart_data(Cir_queue * const QMe,Usart_Trm *const Me,uint8_t bydata)
{
switch (Me->usart_status)
{
case STATUS_IDEL:
if(bydata==Me->head)
{
Me->usart_status=STATUS_HEAD;
Me->last_pos++;
}
else Me->usart_status=STATUS_END;
break;
case STATUS_HEAD:
if(bydata!=Me->teal)
{
Me->usart_status=STATUS_DATA;
Me->last_pos++;
}
else Me->usart_status=STATUS_END;
break;
case STATUS_DATA:
if(bydata!=Me->teal&&!QMe->c_vptr->full(QMe))
{
Me->usart_status=STATUS_DATA;
Me->last_pos++;
}
else if(bydata==Me->teal)
{
Me->last_pos=0;/*成功接收到头和尾,没有错误数据*/
Me->Uartx_frame++; /*队列中有效帧+1*/
Me->usart_status=STATUS_IDEL;
}
else Me->usart_status=STATUS_END;
break;
case STATUS_END: break;
default:Me->usart_status=STATUS_END;break;
}
if(Me->usart_status==STATUS_END)
{
QUEUE_TYPE temp;
/*把出错数据取出,从尾取出*/
while(Me->last_pos)
{
QMe->c_vptr->tail_pop(QMe,&temp);
Me->last_pos--;
}
Me->usart_status=STATUS_IDEL;
}
else
{
QMe->c_vptr->push(QMe,bydata);/*数据入队列*/
}
}
/*实现两种命令方式,自定义根据有没有'='号自行判断命令类型*/
/*判断命令类型*/
static int Com_type(const char * const str)
{
char *buf_ptr=(char *)str;
int count = 0;
/*内容为空*/
if(*(buf_ptr+count)=='\0') return 0;
while (*(buf_ptr+count)!='='&&*(buf_ptr+count)!='\0')//'='是判断的位置,也是命令停止标志
{
count++;
}
if(*(buf_ptr+count)=='=')
{
return count;
}
else
{
return 0;
}
}
/*读取取出1帧的内容,保存帧头和帧尾,返回读取到的内容*/
static char * Get_fram_data(Cir_queue *QMe,Usart_Trm *Me)
{
static char buff[50],get_char;
int i=0;
my_memset(buff,0,sizeof(buff));
while(Me->Uartx_frame!=0&&QMe->c_vptr->pop(QMe,&get_char))
{
if(get_char==')')
{
Me->Uartx_frame--;
break;
}
buff[i++]=get_char;
}
buff[i++]=')';
return buff;
}
/*将命令放在尾部*/
void Com_tailpush(Cir_queue *QMe,Usart_Trm *Me,char const *get_str)
{
Me->usart_status==STATUS_END;
/*解决传入命令不完成的问题,比如原来数据:(111,还未接收完成(标记为错误,重新接收),插入就会变成(111(112)*/
if(Me->last_pos!=0)
{
QUEUE_TYPE temp;
for(int i=Me->last_pos;i>0;i--) QMe->c_vptr->tail_pop(QMe,&temp);
Me->usart_status=STATUS_IDEL;
Me->last_pos=0;
}
/*把当前数据的帧头和帧尾放进列表尾部*/
while(*get_str!='\0')
{
Me->c_vptr->rx_buff(QMe,Me,*get_str);/*存入数据进入缓冲区*/
get_str++;
}
Me->c_vptr->rx_buff(QMe,Me,*get_str);/*将帧尾存入*/
}
/*返回缓存区的帧数*/
int Get_fram_num(Usart_Trm *Me)
{
return Me->Uartx_frame;
}
/*返回0则为命令假,返回其他则为真,数据默认扩大1000倍,返回1则为命令模式*/
long Deal_com(Cir_queue *QMe,Usart_Trm *Me,const char *sdata)
{
char com_buf[COMMAND_LEN_MAX]={0};//临时保存内容数据
int eque_pos=0,back_data;
float temp=0;
char *get_string;
int i=0;
/*遍历队列中所有命令,找到符合命令的*/
while (i<=Me->c_vptr->fram_num(Me))
{
i++;
get_string=Get_fram_data(QMe,Me); /*获取帧内容*/
#ifdef CIRDEBUG
printf("Get string is %s \n",get_string);
#endif
/*遍历一遍找到了,则返回*/
if(strncmp((const char *)get_string+1,sdata,strlen(sdata))==0) break;
Com_tailpush(QMe,Me,get_string);
}
/*遍历完都没有找到,丢弃当前帧,当前为最先插入的帧*/
if(i==Me->c_vptr->fram_num(Me)+1) return 0;
eque_pos=Com_type(++get_string);
/*返回输入命令中的数字*/
if(eque_pos!=0&&*get_string!='\0')
{
/*把尾帧去掉*/
for(int i=0;i<strlen(get_string)-(eque_pos+1);i++)
{
com_buf[i]=*(get_string+eque_pos+i+1);/*把等于号后面的全部数字保存*/
}
temp=atof(com_buf);/*字符串转换成为浮点型数字*/
back_data=temp*1000;/*扩大100倍*/
return back_data;
}
/*符合命令,不反回参数*/
else if(eque_pos==0&&*get_string!='\0') return 1;
/*其他情况*/
else return 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/liang-zequan/custom-serial-protocol.git
git@gitee.com:liang-zequan/custom-serial-protocol.git
liang-zequan
custom-serial-protocol
自定义串口协议
master

搜索帮助