加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 技术文章

PDIUSBD12固件软件包(V5.0)使用心得

时间:2012-11-24  来源:123485.com  作者:9stone
    说句实在话,ZLG团队做的软件包真的非常好,非常专业!基本上不用怎么修改就可以直接使用。不过在使用过程中,还是有些地方需要我们去注意。以下是我们公司在使用过程中出现的情况,请ZLG团队及D12的用户们多多交流!

1.   当MCU通过D12发数据给主机时不能简简单单的调用写函数,如下:D12_WriteEndpoint(5,64,filebuffer);
如果您用的是51等慢速的单片机可能没什么事情,当用ARM等快速的处理器作大量数据传输时可能会出现丢包的现象。在MCU连续的给主机发包的过程中,主机还没有将上一个包的数据从D12读走(就是D12的缓冲区处于满的情况),MCU又将另一个包写进去时会覆盖掉以前的。因此在每写入一个包时必须先判断 D12有没有空的缓冲区,如下:   
while (1)                   //如果端点的两个缓冲区都为满,则等待
{
  outportb(D12_COMMAND,0x85);
  EndpState = inportb(D12_DATA);
  EndpState &= 0x60;
  if (EndpState != 0x60)         //有空缓冲区,则发送数据
  {
    break;
  }
}
D12_WriteEndpoint(5,64,filebuffer);

2.   同样,在主机给MCU发送大量数据时也可能会产生丢包的情况。起初我们的MCU是直接查询bEPPflags.bits.ep2_rxdone来判断D12是否收到主机数据,然后读取。下面的代码在主程序中执行,如下:
  if (bEPPflags.bits.ep2_rxdone == 1)   //收到主机下载的数据
  {                           
    for(i=0;i<64;i++)           //从缓冲区中读走一包数据
    {
        CheckSum +=EpBuf;     //累加校验和
        *pUsbByte= EpBuf;     //保存数据
        pUsbByte ++;
    }
    RecDataLong += 64;         //累加收到的数据长度
    ARMDisableInt(); //关中断,我觉得没有必要,因为都没有判断该标志
    bEPPflags.bits.ep2_rxdone = 0; //清空端点2收到数据标志
    ARMEnableInt();
}
有一种很奇怪的现象:当PC机打开的应用程序越多且频繁的操作这些程序时,丢包的现象越严重!所以当我要从PC机发送一个几十MByte的文件到MCU时,就不能让PC机做其它事情了,否则就出现丢包。起初我们在PC机软件做了很多努力,但都失败。后来发现不是D12里的缓冲区被覆盖了,而是软件包中的 EpBuf缓冲区被覆盖。因为D12接收到主机发来的一个包后会产生中断,然后将数据放入EpBuf,而此时如果我们还没有从EpBuf读走数据时, D12又从主机收到一个包产生中断,此时读取包数据时就会将EpBuf原来的数据覆盖掉,因为端点接收数据处理函数便没有去判断 bEPPflags.bits.ep2_rxdone是否等于0,如下:
void ep2_rxdone(void)
{
  INT8U len;
  D12_ReadLastTransactionStatus(4);               //清中断标志位
  len = D12_ReadEndpoint(4,EP2_PACKET_SIZE,EpBuf);   //读取缓冲区中的数据
  if (len != 0)
    bEPPflags.bits.ep2_rxdone = 1;
}
此时由于已经调用了D12_ReadEndpoint(4,EP2_PACKET_SIZE,EpBuf)函数,而在该函数中写了清缓冲区的命令,所以主机就会继续往D12发送数据,而使EpBuf内容被覆盖。我觉得最简单最保险的方法就是从D12中读出的数据直接存入自己的缓冲区中,就可以保证在给D12 写清缓冲区命令前数据都被存放好了,而且也提高了响应速度!修改ep2_rxdone函数如下:
extern unsigned char *pUsbByte;             //指向自己定义的缓冲区
void ep2_rxdone(void)
{
  INT8U len;
  D12_ReadLastTransactionStatus(4);         //清中断标志位
if (pUsbByte && to_pctrans.trans_type)   
{
    len = D12_ReadEndpoint(4,EP2_PACKET_SIZE,pUsbByte);
    pUsbByte += len;
    RecDataLong += len;               //累加实际收到的数据长度
  }
  if (len != 0)
  {
    bEPPflags.bits.ep2_rxdone = 1;
    USBTestBack += 1;
  }
}
为什么PC机运行的程序越多且在频繁的操作这些程序时,丢包的情况越严重呢?我是这样理解:多任务操作系统(windows也不例外)的调度是由定时中断触发的,所以两次调度的时间间隔是个定值。在第一次调度时,由于很多优先级更高的任务将USB发送任务推迟了。而在第二次调度时,第一次优先级高的任务又被挂起,而使第二次USB发送任务没有被推迟。在最坏的情况下两次USB发送的时间间隔远比正常情况下的时间间隔短,就使MCU出现了EpBuf包被上一次覆盖的情况。

分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->技术文章
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门