搜索
bottom↓
回复: 20

请教大侠,单片机解复杂的通讯协议(UART)用什么写法比较好,直观,高效?

[复制链接]

出0入0汤圆

发表于 2008-5-8 20:35:09 | 显示全部楼层 |阅读模式
比如接收命令有100条,对应不同的处理.命令格式相同,但长度不一样,内容也是多变.要是用100个if或者switch的话估计头都大了.

好象有种写法是用结构或者数组的,大侠指点啊.

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2008-5-8 22:56:24 | 显示全部楼层
我觉得用switch比较直观!
关键在于你有100条命令,对应100种处理,只要这些处理不能合并,就没办法简单!

出0入0汤圆

发表于 2008-5-8 23:09:14 | 显示全部楼层
用函数指针数组,对应的命令做数组下标。

出0入0汤圆

 楼主| 发表于 2008-5-8 23:09:41 | 显示全部楼层
基本格式是:
msg_start + msg_sn + data_size + msg_key + cmd + msg_id + data1 to data n + check + msg_end

cmd是命令,决定要干什么等(27条),然后msg_id决定是什么具体内容(几乎每条cmd都对应好几个分支),最后才能是协议内容.

可不可以做一个数组,用它来扫描分析协议的具体内容.?

出0入0汤圆

 楼主| 发表于 2008-5-8 23:13:57 | 显示全部楼层
有点懂"【2楼】 luan3703"的意思.

是不是协议分析时先从1个cmd结构中找到对应的cmd,然后取出结构的另一成员

(因为cmd的排列不是连续的,这样可以得到一个连续编号).

用这个成员做涵数指针的偏移量转到相应涵数?

出0入0汤圆

 楼主| 发表于 2008-5-8 23:14:40 | 显示全部楼层
2楼能给个简单列子吗?或者哪里有相关资料可参考,谢谢

出0入0汤圆

发表于 2008-5-8 23:56:51 | 显示全部楼层
void(*fun)(void)[3][4]=
{{00,00,f02,00,},
{f10,00,00,00,},
{00,00,00,f23,}
};

//cmd=0,id=2
void f02(void)
{}
...
//cmd=1,id=0
void f10(void)
{}
...
//cmd=2,id=3
void f23(void)
{}

main

......
void(*fun[cmd][id])(void);
.....


就分开了。
注意如果cmd和id不连续,则要注意对齐数组中程序指针的地址。
--------------------更新结构体-----------------
需要接收数据长度是固定的。

union {
struct {
  unsigned char head;
  unsigned char xfel;
  unsigned int  dfa;
  unsigned char cmd;
  unsigned char id;
  unsigned char buf[len];
.....
}struct;
unsigned char array[length];
}uart_data;



接收的时候顺序接收到uart_data.array中。
取的时候
void(*fun[uart_data.struct.cmd][uart_data.struct.id])(void);



如果不是固定的,就只能挨个判断取cmd,id了

出0入0汤圆

 楼主| 发表于 2008-5-9 00:05:46 | 显示全部楼层
谢谢 【6楼】 mljda 技术是人性 的指点,看来用这个方法解协议也不错,如果这样100条协议就要100个涵数了.也挺恐怖

出0入0汤圆

发表于 2012-7-12 17:07:24 | 显示全部楼层
weixichao 发表于 2008-5-8 22:56
我觉得用switch比较直观!
关键在于你有100条命令,对应100种处理,只要这些处理不能合并,就没办法简单! ...

最简单的就这个switch了,其他的都脱了裤子放屁,还不是要写一大堆

出0入0汤圆

发表于 2012-7-13 09:37:43 | 显示全部楼层
写一个流程图,按照你的协议接受和解析数据。
我用switch已可满足了。

mljda 定义的更好,高人。

出0入0汤圆

发表于 2012-7-13 16:08:43 | 显示全部楼层
既然你的帧是有一定格式的
那么你就把你的帧格式要解析出来即可
解析出来符合你帧格式的帧,然后再处理不同命令的功能
用switch case也是在你解析完整了帧格式才用的

我看你格式有帧头和帧尾,那就不存在解析不了的问题了
但是有一点,如果你是全双工工作的话,你得考虑帧头帧尾的转义处理

出0入0汤圆

发表于 2012-7-13 16:17:17 | 显示全部楼层
函数指针那个思路不错,可以试试,学习。

出0入0汤圆

发表于 2012-7-13 17:44:48 | 显示全部楼层
非線性==>線性==>非線性

出0入0汤圆

发表于 2012-9-7 09:25:38 | 显示全部楼层
用函数指针数组的解决办法不错。

unsigned int checkPad0(void)
{
  ...
}
unsigned int checkPad1(void)
{
  ...
}
...
unsigned int checkPad19(void)
{
  ...
}

unsigned int(*const checkPad[])(void) = {
  checkPad0,checkPad1,checkPad2,checkPad3,checkPad4,
  checkPad5,checkPad6,checkPad7,checkPad8,checkPad9,
  checkPad10,checkPad11,checkPad12,checkPad13,checkPad14,
  checkPad15,checkPad16,checkPad17,checkPad18,checkPad19
};

void main(void)
{
  unsigned char i;
  for(i=0;i<20;i++) checkPad[i]();
}

出0入0汤圆

发表于 2012-9-7 09:44:49 | 显示全部楼层
这个 有意思。   这么多命令。

出0入0汤圆

发表于 2012-9-7 10:44:40 来自手机 | 显示全部楼层
路过学习一下!!!!!!

出0入0汤圆

发表于 2019-10-11 17:01:53 | 显示全部楼层
正在找高效率的极简应答方法,有启发

出0入0汤圆

发表于 2019-10-12 13:30:27 来自手机 | 显示全部楼层
习惯了switch

出0入0汤圆

发表于 2019-10-12 16:58:08 | 显示全部楼层
switch最直观,其他搞什么数组函数指针的耗内存调试又不直观,完全没必要

出0入0汤圆

发表于 2019-10-14 00:22:04 | 显示全部楼层
nongxiaoming 发表于 2019-10-12 16:58
switch最直观,其他搞什么数组函数指针的耗内存调试又不直观,完全没必要

同意你的说法,而且看看命令的重复频率,高的放前面!

出140入8汤圆

发表于 2019-10-14 08:46:16 | 显示全部楼层
楼主还是搞少了,几百个函数有什么的呢,没问题的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 09:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表