DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 648|回复: 0
打印 上一主题 下一主题

[接口电路] PIC单片机和PDIUSBD12开发USB传输器备忘录

[复制链接]
跳转到指定楼层
楼主
发表于 2011-5-10 22:36:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PIC单片机和PDIUSBD12开发USB传输器备忘录

选用的原因
为什么要选用PIC?居做硬件的来说,我们要接Flash,51引脚不够,所以挑了PIC。
方案的缺点
用PIC和D12作为搭配来开发USB数据传输器并不是个好注意,因为PIC对外部操作是通过I/O口来进行的,这样就要用软件来模拟51和D12的通信时序。而软件的执行是顺序的,如果晶振接4M,那么主频就是1M  ,每条单周期指令要花费1us,而对D12如果是采用复合总线通信的话,一个outportb就要8条指令,约8us,是C51的两倍。
其次,由于D12的INT脚在上电后就是低电平,这时候main函数还没有启动,而PIC是边沿触发中断,所以第一个中断就无法捕捉到,为了保证程序正确性,就采用了轮询的方式。这也是影响速度的愿意之一。
字节顺序
有个小小的注意点,PIC是little-endian,C51是big-endian,USB是little-endian所以如果用周立功的程序来改的话,SWAP就不需要了。
PIC和D12的接口方式
A0是用来区别总线上是数据还是命令的,但是如果是复合总线的话,是由ALE来判别数据和命令的,所以可以把A0接高电平,但是我做了跳线,接低电平也可以,看了周立功的原理图,发现他们是接地的,只要接固定电平就可以了。而ALE则要接在MCU的I/O  out上。
在开发中,由于PCB人员的马虎以及PIC引脚不是按照顺序排列的,头板把PIC  PORT的引脚顺序和D12数据线的顺序接乱了,事后我才知道,比较胸闷,这样每次通信前,我都要把bit移位,要浪费不少时间,后来重新制板才纠正了。大家千万不要犯这样的错误。
对总线复位中断和suspend的处理
我看周立功的代码里,这两个处理都是空的,所以我干脆就删除了,因为我做成轮询的,太多判别会影响速度,后来我把endpoint  1  in/out的判别也都扔掉了
上电后的第一次中断处理
我跟踪了下,发现D12在上电后,如果在main里已经正确发送了reconnect的命令的话,D12会产生3个中断
第一个:bur  reset中断,只要读D12中断寄存器,就可以清这个中断
第二个:suspend中断,不必去理会它,同上处理
第三个:endpoint  0  IN中断,是上位机要求D12传送device  descriptor数据结构的请求
因为上位机在得到端口电平变化的信息后,就会发送这个请求,如果有应答,上位
机才真正认为有设备插入。
上位机  USB总线枚举的一些问题
只要在应答getdescriptor这个请求后,传送了数据的话,上位机就会提示安装驱动的向导,也就是在bushound中如果能看到getdescriptor后面有DI数据的话16byte,那么就应该有安装提示。至于是否能正确安装,就要看你的固件的PID和UID是否与驱动的inf文件中匹配。
值得注意的是,我听到经常有人说在枚举时候,出了问题。其中一位老兄的症状是:在设备插入后,goodlink的led灯亮了3下就不亮了。我也遇到了这种错误,后来我好好想了下,结果发现是我把字节顺序给搞混了,我把PIC当作big-endian了,所以无法正确识别请求类型。而goodlink的灯闪3下,是上位机发了3次getdescriptor,没有应答,它就认为不是真正有设备插入。
其次,在安装驱动时候,也经常有人出问题。驱动安装不上!我看了一位老兄的代码,他是自己发现自己的问题,问题似乎是point如果不指向rom的话,好象向上位机传送的数据就有错误。那么PID,UID肯定就不匹配了。于是那位老兄在传送前都指定了rom  point。居他自己说是改正了。我是没碰到他类似的问题,我就是按照普通C语言中的指针来用,就可以正确安装驱动的。我在这里提出来,是希望大家如果以后遇到类似问题,可以试试这中方法。
MCU对D12操作时序
这个,如果光看D12的Datasheet是不够的,我觉得那里面说的不全面。因为我是从一点不懂开始做起的,所以一开始被D12的时序问题搞了一把。
后来,我看了赵明兄使用的MCU(51)的datasheet中的时序图才搞明白,咳,费了点时间摸索的。程序如下:注意,CS选通可别忘记了,PORT  C默认要接成output,WR,RD接成高电
void  outportb(unsigned  char  port,unsigned  char  val)
{   
ALE  =  0;//ALE  low
ALE  =  1;//ALE  up
PORTC  =  port;//出地址
ALE  =  0;//锁存地址

PORTC  =  val;//写数据
ASSERT_WR  =  0;
ASSERT_WR  =  1;

ASSERT_RD  =  1;//RD  =  0  active
}

unsigned  char  inportb(unsigned  char  port)
{
unsigned  char  bData;
TRISC  =  0x00;
ALE  =  0;//ALE  low
ALE  =  1;//ALE  up
PORTC  =  0x02;
ALE  =  0;//ALE  low

TRISC  =  0xFF;
ASSERT_RD  =  0;//RD  =  0  active
bData  =  PORTC;
ASSERT_RD  =  1;

TRISC  =  0x00;
ASSERT_WR  =  1;
return(bData);
}
大家看到了吧,用I/O模拟时序,要那么多指令,编译成汇编还不知道要多少呢,而51的话,大概在2个指令周期就能完成。到这里,我才真正理解为什么说vhdl里很多是并发的而软件程序是顺序执行的。
上位机程序
读一个文件,每64个字节为一个数据包,扔给驱动。这样做不如把数据扔给驱动去分割来的快,不过我想X86那么快,也无所谓了吧。。。在驱动里,每次提交URB也都是按照endpoint2  out的最大缓冲来发送的。已经是尽全力了。不过,应用程序最好每次提交的数据等于64字节,小于这个的话,总的传输时间会加长,超过了的话,就会丢包,除非驱动设计成能分割大于64字节的功能。
还有,我的驱动是用driverstudio写的,不是直接用DDK,不知道速度有多少差异。。。

最终数据传输速度
在PIC上,接了4M晶振,这样测试了下,传输83k字节的文件,大概用了5秒不到的
时间,也就是17k/s左右--------大家别笑了,我自己都觉得不好意思了,人家写USB协议的人那么辛苦,我就做出这么个鸟东西。。。。
我请教了做过的人,也是PIC+D12的,凭他的经验,最快可以达到100k/s,不过他使用的是8M晶振,我写这篇文章的时候,还是使用的4M,我明天去试下,如果各位有什么好的建议,也请告诉我。不过我觉得要达到200K/s是无论如何也不可能的。
我已经试过10M的晶振了,速度可以达到40K/s,看来的确是I/O  速度的问题  
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-6-11 04:07 , 耗时 0.089452 秒, 18 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

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