SONY LANC协议应用-转载于 武汉广电网

来源:互联网 发布:linux的vi到指定行 编辑:程序博客网 时间:2024/04/30 00:48

早些时候发现的这篇文章,后来网站整理被删除了。于是在其他地方找到了此备份,贡献给大家


//===============================================================================================================================

>>首页>>广电杂志>>声像与电脑>>技术维修与应用


SONY LANC协议应用

  前段时间单位的相机控制器坏了,找了很多地方没买到合适的,想着无非就是用LANC协议控制摄像机录制和停止应该不难的,就打算自己动手做一个,哪知道看是简单的一个东西要做起来也还是很不容易的。

  LANC协议据说需要向SONY公司索取,可能需要付费,但在网上很容易就找到一份名为《The SONY LANC protocol》的资料。根据这份资料的内容我们可以很清楚地知道LANC协议的电路接口标准、波形特征和编码信息,但是这份资料仅限于介绍LANC协议,你可以据此分析LANC编码获取信息,要通过LANC协议控制设备就是另外一回事了。

  虽然可以从网上搜索到各式各样的LANC控制器,甚至还有写好程序的PIC单片机芯片,但是找不到一份可以参考的应用资料。没办法,我们只好做了各种猜测和尝试,最后借助逻辑分析仪和计算机串行通信调试软件对LANC协议才有了较清楚的了解,然后通过计算机串口模拟了一个LANC编码收发设备来搭建一个可调试的实验平台,最终完成了偷拍机LANC控制器的设计制作。

      这里先简单介绍一下LANC协议,LANC电路接口有两种形式(见下图),从电路接口可知LANC接口可提供5V的电源给其它设备供电,不过尚不知输出电流限额是多少;LANC信号传递是通过一根信号线来完成的。

[图片丢失]

      LANC编码由8比特编码信息组成,分别是4比特的起始码,和4比特的状态码,8比特的编码都由受控制的录像机、摄像机发出,每组编码间隔一帧画面(所以NTSC和PAL制设备间隔时间不同)。当控制设备发送命令时,只需要输出第一个设备识别码和第二个控制命令码,然后设备返回四个编码的设备状态信息。编码符合9600Hz串行编码特征,即一个起始位,八位编码,一个停止位,没有校检位,简单的说是编码为CMOS串行信号,即9600.n.8.1。如果需要使用计算机RS232端口读取则需要进行CMOS到TTL的电平转换。

      特别需要注意的是,LANC信号的编码都是经过翻转之后发出的,接收或者发送LANC指令都需要取反才对。编码及分析图如下:

[图片丢失]

      综上所述,读取LANC信息还是比较容易的,要写入LANC指令来控制设备就比较麻烦了,一是何时写入,二是通过何种方式写入,这的确是个难题。在互联网上也搜索不到相关的信息,卖LANC控制器的倒是不少。

      我们知道MCU端口输出电流的能力远比不上灌入电流的能力,假设两个端口连在一起,同一时间段内一个输出高电平,一个输出低电平,人为地制造一个电平竞争,再来测量两个端口的电平值,读取到的便是低电平。当LANC信号为起始码,输出0xff(协议描述的起始编码为0x00,实际应用中是取反的,即为0xff),这期间同步输出一个命令参数,例如0x28,0x28取反为0xD7,0xD7和0xff叠加在一起,摄像机或录像机在输出0xff的同时进行读取,这时候读取到的数值便是0xD7。这样便可以实现命令的发送。

      现在的问题就是如何设计一个稳定可靠的电路来接收LANC信息、发送LANC指令以及确定何时发送指令。既然LANC编码符合串行编码规则,使用MCU的UART端口发送和接收LANC指令是最简单的。实际电路见下图,做偷拍机控制器AVR Mega8单片机的端口是有富余的,所以单独使用了一个端口做起始电平的检测。

[图片丢失]  

      通过上面的分析我们知道LANC设备发送编码是以4比特0xff为起始码,然后是4比特返回码,控制器发送命令是修改第一和第二比特起始码,即变成了2比特命令码,2比特0xff起始码,4比特返回码。要正确发送LANC命令就需要确定从什么地方开始发送的是第一个编码,从程序设计的角度来说至少需要一个LANC指令周期来确定起始位置,也就是和编码发送周期同步。我们通过下面的一段程序来完成这个工作。(本文所引用代码均为AVR单片机,CodeVisionAVR程序)。

  char lanc[8];

  char i;

  char isfound,cmds;

  char start,rec,stop;

  //全局参数声明

  char find8byte()

  {//指令周期同步函数

       char idata;

       char k,isff;

       isff=0;

       for(k=1;k<9;k++)

       {

           idata=getchar();

           lanc[k-1]=idata;

           if(k<5)

           {

               if(idata==0xff)

               {

                   isff++;

               }else{

                   k=0;

                   isff=0;

               }

           }

       }

       return isff;

  }

      通过上面的程序来同步到LANC指令的发送周期后,我们就可以等待下一个指令周期的起始码了。前面说到LANC编码是串行编码,符合9600.n.8.1的规则,即是说在起始比特0xff编码发送前首先发送一个低电平的起始位,单片机检测到这个低电平信号就立即发送串行命令编码,拉低编码中为低电平的位,发送端便收到了LANC控制命令。检测可以利用单片机的中断模式来实现,也可以通过不间断地读取端口电平来确定,我们在实际应用中发现使用中断的情况较复杂,极容易触发多余的中断,于是改为轮询的设计。

      实际应用中为了应对现场各种干扰信号,有必要将控制指令多次重复发送。当然,分析返回码确定设备状态再决定是否需要进一步发送控制命令是更稳妥的做法,这里为了简单起见,我们略去了这个过程。控制命令发送程序如下:

  void sendcmd(char cmd1,char cmd2)

  {

       while(PIND.2==1)

       {//等待同步低电平

       }

       putchar(cmd1);

       delay_us(20);

       lanc[0]=getchar();

       while(PIND.2==1)

       {

       }

       putchar(cmd2);

       delay_us(20);

       lanc[1]=getchar();

      

  }

    

     至此,基本介绍完毕LANC协议的应用方法。仓促之间难免有疏漏之处,还望谅解!

  关于LANC协议更多的指令和返回码的解析方式请参考附录所列文献。

  附录:参考文献:

  《The SONY LANC protocol》

0 0
原创粉丝点击