[开源充电器]通信协议编码解码程序测试,大家指教【附程序GCC】
书写不规范,大家提意见哈!点击此处下载ourdev_186601.rar(文件大小:18K)
整个工程
为什么要在发送和接收时同时解码和编码?
我不知道数据到有多少需要编码解码,所以数组空间不定。同时编解码,只需要定义实际数据长度的数组。
---------------
请教:
1 怎么整合拆包程序便于以后主程序调用,现在情况是全部放在串口接收中断中。
2 解码我占用了一个全局变量fcode;有其他方法么,指针p也是全局的;
---------------
测试使用
启动会发送一个16长的初始包,
上位机发送不定长(现在30> >4)数据包,如果CRC错误,返回发送当前数据包CRC(你就可以用这个CRC构建一个正确的包,方便串口调试助手,或超级终端调试);正确发回原数据包。
接收忽略错误转义字符
1A 1B 0B 1B 14 1B 15 1B 13 FF 1bFF 1B 11 c3 7d 1D
->
1A 1B 0B 1B 14 1B 15 1B 13 FF 1B 11 C3 7D 1D
---1b 后面的FF被忽略了---
上位机发送
1A-------------------CRCl-CRCh-1D
错误返回
接收到的CRCl-CRCh注意(CRC也需要转义的,如果发现含有限制符,需手动转移添加到数据传中)
正确返回
1A-------------------CRCl-CRCh-1D
-------------------发送同步编码CRC----------------------------------------
void encodeUART(unsigned char c)
{ //unsigned char c;
//for(;num>0;num--)
//{ c=*buf++;
if(c==PTC_F_BEGIN) {c=PTC_E_BEGIN;}
else if(c==PTC_F_END) {c=PTC_E_END;}
else if(c==PTC_F_RS) {c=PTC_E_RS;}
else if(c==PTC_F_TEXT) {c=PTC_E_TEXT;}
else if(c==PTC_F_ESC) {c=PTC_E_ESC;}
else //非转移字符直接发送
{while(!(UCSRA&(1<<UDRE)))
;
UDR=c;
return;
}
while(!(UCSRA&(1<<UDRE)))//发送转义
;
UDR=PTC_F_ESC;
while(!(UCSRA&(1<<UDRE)))
;
UDR=c;
//}
}
void sendBufEncodeCRC16(unsigned char *buf,unsigned char num)
{ //unsigned int crc=0;
union {
struct {
unsigned char h;
unsigned char l;
}crc;
unsigned int crc16;
}ram;
while(!(UCSRA&(1<<UDRE)))
;
UDR=PTC_F_BEGIN;
ram.crc16=0;
for(;num>0;num--)
{
ram.crc16 =_crc_xmodem_update(ram.crc16,*buf);
encodeUART(*buf++);
}
encodeUART(ram.crc.l);
encodeUART(ram.crc.h);
while(!(UCSRA&(1<<UDRE)))
;
UDR=PTC_F_END;
}
--------------------接收同步解码------------------------
unsigned char *decodeUART(unsigned char c,unsigned char *p)
{
if(fcode==0 )
{if(c==PTC_F_ESC){fcode=1;return p;}
}
else{
fcode=0;
if(c==PTC_E_BEGIN) {c=PTC_F_BEGIN;}
else if(c==PTC_E_END) {c=PTC_F_END;}
else if(c==PTC_E_RS) {c=PTC_F_RS;}
else if(c==PTC_E_TEXT) {c=PTC_F_TEXT;}
else if(c==PTC_E_ESC) {c=PTC_F_ESC;}
else {return p;} //非转移字符直接发送
}
//while(!(UCSRA&(1<<UDRE)))
//;
//UDR=c;
*p++=c;
return p;
}
--------------main------拆包---------------
while(1)
{
c=UARTgetCHAR();
/* 拆包 */
if(c==PTC_F_BEGIN) {s=PTC_F_BEGIN;p=&usart.buf;}
else if(c==PTC_F_END)
{s=PTC_F_END;
ram0.crc.h=*(--p);ram0.crc.l=*(--p);
ram.crc16=get_crc16_XMODEM(&usart.buf,p-&usart.buf);
if((ram.crc.l==ram0.crc.l) && (ram.crc.h==ram0.crc.h))
{sendBufEncodeCRC16(&usart.buf,p-&usart.buf);
}else{
UARTputCHAR(ram.crc.h);UARTputCHAR(ram.crc.l);
}
}
else if(s==PTC_F_BEGIN) {p=decodeUART(c,p);}
}
------------------------------------ 怎能不顶!MCU固件小组,先顶下! 顶,COOL ! 大顶 惭愧!
现在条件有限,自学,只能先练习堆代码;
在充电器里面做些纯软的工作,大家多指教。我多学习。 顶你个大石^o^
我本也打算在整个协议完成之后,也把代码写出来,没想到你先了。
顺便帮你把这源代码转成繁体版,也方便使用繁体的朋友使用。
点击此处下载ourdev_186985(繁体版).rar(文件大小:18K) ./emotion/em078.gif
./emotion/em078.gif
顶两下,辛苦了,赞一个
呵呵,只能给精神上的支持
程序方面,拿张小板凳,学习中 支持支持。
不知道大家都用什么编辑器来写程序,推荐使用utf-8编码格式,大多数编辑器都支持这个设置,Windows和Linux的内部处理格式都是这种编码,可以繁体和简体混排都不会有问题了。 我在学习中用WinAVR2007自带的PN,不知道有没有问题 放在串口中断中处理并不合适,可能会阻挡有效数据的接受。
接受、发送的同时进行编解码的处理,显然增加了很多CPU的负担。
需要和村长协商一下,最好不要进行转意,不然可以对很方便的实现定位操作,但是又需要有一个判断数据包结尾的方法。
我个人倾向于使用MOSBUS类型的,超时判断数据包终止的方法。 提点意见,如果大家希望随便一个串口助手都能对其进行调试的话应该学习一些GPS产品的通信方式,直接采用字符串传送数据包。
比如:
:<A 1234><B 12345><C 100>...<LRC>\r\n
格式之类的。
虽然降低了通讯效率,但可以给调试带来很多方便。愚见!!
页:
[1]