原创 USB--------从STM32的USB-DEMO开始

2008-7-29 23:09 7249 6 7 分类: MCU/ 嵌入式

原来发表于21ic,近期在重新整理并搬家,利用下EDN的博客备份,呵呵,    为了技术的完整性,顺便把香帅的讲解也拷贝过来了




以前只是和朋友合作写过USB的PC端应用层软件,


对USB的协议层及管道只是有一些基本的认识,


近期拿到了一个STM32的最小系统,也接一下USB出来学学固件制作,呵呵


看STM32的USB驱动,首先从中断服务函数看起,   void USB_Istr(void)


  wIstr = _GetISTR(); // 取到USB中断的标志位
  if (wIstr & ISTR_RESET & wInterrupt_Mask) // 在中断打开的情况下,判断标志位,并响应


共处理了8个标志位,依次如下:


#define ISTR_CTR    (0x8000) /* Correct TRansfer (clear-only bit) */
#define ISTR_DOVR   (0x4000) /* DMA OVeR/underrun (clear-only bit) */
#define ISTR_ERR    (0x2000) /* ERRor (clear-only bit) */
#define ISTR_WKUP   (0x1000) /* WaKe UP (clear-only bit) */
#define ISTR_SUSP   (0x0800) /* SUSPend (clear-only bit) */
#define ISTR_RESET  (0x0400) /* RESET (clear-only bit) */
#define ISTR_SOF    (0x0200) /* Start Of Frame (clear-only bit) */
#define ISTR_ESOF   (0x0100) /* Expected Start Of Frame (clear-only bit) */


这里特别要一提的是:清除中断标志的方法,不能采用"读--修改--写"的办法:


Read-modify-write cycles should be avoided because between the read and the write operations another bit could be set by the hardware and the next write will clear it before the microprocessor has the time to serve the event.
清除标志要采用load写入的方式,介绍如下:


it is recommended to clear them with a load instruction where all bits which must not be altered are written with 1, and all bits to be cleared are written with ‘0’


(为什么可以这样写呢?不会形成软件中断吗?-----当然不会,因为这个寄存器的位不是RW的,呵呵,而是RC的,我仔细看了好一会儿才发现的)


ST的usb库为了与用户的应用衔接,采用了C的结构体+函数指针,这样应用时只需要接口DEVICE_PROP Device_Property 的函数,将这个函数填充完整后,即可更改应用了,,这样做一个很大好处时,应用时如果没有特别的应用,不用去关心USB的底层实现,在USB的库之上做应用是可行的.(不过,如果库本身有缺陷,那就郁闷了,偶初学,还是先看看再说)


,在USB的库里都是通过指针DEVICE_PROP *pProperty;来调用Device_Property里的函数实现的,该指针是在USB_Init()里初始化的.


初学嘛,异常的中断处理先略过了,直接看下正常的通信处理吧,都在函数:void CTR_LP(void)中实现,


这里发现了一个问题,    _SetISTR((u16)CLR_CTR); /* clear CTR flag */


这个位不是只读的吗?难不成是我的RM0008Reference manual太旧了??有空去查查了。


先往下看:    EPindex = (u8)(wIstr & ISTR_EP_ID);得到端点号,这个可是很重要的噢,看USB一定要搞清楚什么是端点。


接下当然就是依端点的不同,进行不同的处理啦,


端点0一般用来做一些设置等,这是由协议保留确定的,


其他的都可以拿来做别的应用了,同样,这里还是用函数指针对应用留了接口:


void (*pEpInt_OUT[7])(void) ;
void (*pEpInt_IN[7])(void) ;


根据你的需求去填写吧,嘿嘿。。


-----附注:目前我已经把USB的虚拟串口移植到我的STM32控制台上了


posted @  Walter 发表于 2008-5-10 7:40:00 阅读全文(433) | 回复(3) |


 

-------以下为香帅的评语.

----------------------------------------------------------------------------

Re:开始学习USB--------从STM32的USB-DEMO开始

香水城博主的判断是对的,你发现的问题确实存在,USB_ISTR的CTR位是只读位,_SetISTR((u16)CLR_CTR)这句话没有用。

实际上CTR位也不能在这个位置被清除,否则后面如何判断发生中断的端点号呢?

真正的清除中断是在随后读出EPindex,调用_ClearEP_CTR_TX或_ClearEP_CTR_RX的时候。

<><><><><><><><><><><><><><><><><><><><>
再看你发现的问题,这句话实际上可以被去掉,没用!

在内部,CTR位是所有端点的中断标志"或"起来得到的,接收端点的中断标志为USB_EPnR中CTR_RX,发送端点的中断标志为USB_EPnR中CTR_TX。

<><><><><><><><><><><><><><><><><><><><>
估计写这个库函数的工程师对这个USB设备还理解不够深入,所以出现了这样的错误。整个这个库的架构是十年前我们在第二个USB单片机(ST92163)时就确定的,以后一直延续到ST7的USB库、STR7和STR9的USB库,直至现在的STM32;多年下来证明这个架构是非常好用的。

posted @  香水城(游客)发表评论于2008-5-10 10:26:00

文章评论1条评论)

登录后参与讨论

用户94692 2008-7-30 11:47

果然很强大!
相关推荐阅读
walnutcy_696810119 2012-11-21 08:37
Linux下使用smartCOM调试串口
在Windows下的串口调试一直使用sscom,在Linux下只找到一个cutecom,用了几次,很不喜欢,就着手开发了一款自己的串口调试工具,smartCOM。 smartCOM介绍:http...
walnutcy_696810119 2012-03-29 18:12
【博客大赛】原创--测量基础:什么是测量
写在正文之前: 适逢EDNChina搞活动,而我本人也算在测量业工作,就一起作下笔记吧。若有错误,请大家一起斧正。笔者写本文一方面是梳理知识,另一方面也希望与大家探讨有关测量的知识、应用等,希...
walnutcy_696810119 2011-12-20 18:29
GLONASS 15年来,首次实现24颗星在轨可用
  EDN的博客改版后,不太好用,在SINA重开一个,不过重点改为关注GNSS行业新闻 http://blog.sina.com.cn/s/blog_7420cd1701012en9....
walnutcy_696810119 2011-12-20 17:49
逆向工程第一步:通信协议分析
工程中常有这样的事,想分析下其他知名公司产品中的通信协议,以便生产设计兼容产品。 1) 逆向工程,首先要了解产品,知己知彼,百战不怠;     去年受命想仿一款GARMIN的导航盒,但无法...
walnutcy_696810119 2011-11-14 11:30
通用代码调试方法 (Keil, VCC)
调试代码一般需要定位问题,这里给出一个解决方案, 一般的编译器均支持这些宏指令。   #define DEBUG_WALT_1113     1 extern void log_t...
我要评论
1
6
关闭 站长推荐上一条 /2 下一条