大家好,欢迎来到IT知识分享网。
转载自:visca协议及其实现的简单认识
visca协议及其实现的简单认识
李迟 2014-06-30 14:09:01 7064 收藏 12
分类专栏: 程序编程 代码生活 打工人的知识库
版权
最近在搞visca协议,在这里写写,算是个记录。
visca是索尼公司搞出来的,用来控制相机的协议,一般通过rs232来通信(看了些资料,也有用rs485的)。
一、命令格式
命令通信的基本单元称为包(Packet)。一个包的长度为3到16字节,由头部、消息体和结束符三部分组成。命令包的第一个字节称为命令头(Header)。高半字节由1 (最高位,固定为1)和发送方(控制者)地址(地址一般为0)组成,低半字节由0和设备(相机)地址(或称“编号”)组成,从组成格式看,可以外接的相机最多有7台,如向1号相机发送命令,则命令头为0x81。命令包最后一个字节为终结符号,固定为0xff。中间部分字节称为消息体。协议说明文档中将命令头写成“8x”,其中x表示相机地址。
二、响应
四、实现
很庆幸,关于visca,已经有libvisca开源项目了(见参考资源)。下面参考这个项目,做了一些小修改,写一下关键的实现代码。
关于串口的打开、读写、关闭,在此不再多说。下面说一下命令的封装:
void _visca_append_byte(VISCAPacket_t *packet, unsigned char byte) { packet->bytes[packet->length]=byte; (packet->length)++; } void _visca_init_packet(VISCAPacket_t *packet) { // set it to null memset(packet->bytes, '\0', sizeof(packet->bytes)); // we start writing at byte 1, the first byte will be filled by the // packet sending function(_visca_send_packet). This function will also append a terminator. packet->length=1; } 
这两个函数是命令的填充,每次调用_visca_append_byte就填充一个字符,在未填充前,要调用_visca_init_packet来初始化包的长度。当然,实现上也可以直接用数组形式把每个命令合到一起发送出去。_visca_send_packet是填充头部和尾部数据,无须调用者进行考虑,调用者只需关注实际的命令数据即可。这也是使用了VISCAInterface_t的好处(后面写pelco实现的将会看到)。
int32_t _visca_send_packet(VISCAInterface_t *iface, VISCACamera_t *camera, VISCAPacket_t *packet) { // check data: if ((iface->address>7)||(camera->address>7)||(iface->broadcast>1)) { com_print("(%s): Invalid header parameters\n",__FILE__); com_print("addr: %d %d broadcast: %d(0x%x)\n",iface->address,camera->address, iface->broadcast,iface->broadcast); return VISCA_FAILURE; } // build header: packet->bytes[0]=0x80; packet->bytes[0]|=(iface->address << 4); if (iface->broadcast>0) { packet->bytes[0]|=(iface->broadcast << 3); packet->bytes[0]&=0xF8; } else { packet->bytes[0]|=camera->address; } // append footer(0xff) _visca_append_byte(packet,VISCA_TERMINATOR); return _visca_write_packet_data(iface,packet); }
命令响应包函数如下:
int32_t _visca_get_reply(VISCAInterface_t *iface, VISCACamera_t *camera) { // first message: ------------------- if (_visca_get_packet(iface)!= VISCA_SUCCESS) return VISCA_FAILURE; iface->type=iface->ibuf[1]&0xF0; // skip ack messages while (iface->type==VISCA_RESPONSE_ACK) { if (_visca_get_packet(iface)!=VISCA_SUCCESS) return VISCA_FAILURE; iface->type=iface->ibuf[1]&0xF0; } switch (iface->type) { case VISCA_RESPONSE_CLEAR: return VISCA_SUCCESS; break; case VISCA_RESPONSE_ADDRESS: return VISCA_SUCCESS; break; case VISCA_RESPONSE_COMPLETED: return VISCA_SUCCESS; break; case VISCA_RESPONSE_ERROR: return VISCA_CMDERROR; break; } return VISCA_FAILURE; }
里面一些宏定义如下:
/* response types */ #define VISCA_RESPONSE_CLEAR 0x40 #define VISCA_RESPONSE_ADDRESS 0x30 #define VISCA_RESPONSE_ACK 0x40 #define VISCA_RESPONSE_COMPLETED 0x50 #define VISCA_RESPONSE_ERROR 0x60
参考资源:
1、开源的visca协议库:libvisca: http://damien.douxchamps.net/libvisca/
 2、visca协议的wiki介绍:http://en.wikipedia.org/wiki/VISCA_Protocol
后记:截止本文编写时,手上还没有得到硬件资源,文章是根据libvisca和visca协议文档中的描述来写的,应该不具有实践价值。
李迟记于2014年6月30日
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/121229.html
                