|
lbxxx原创 ' x* ? `3 c) J4 B 9 k4 O8 _+ u/ P( Z% [ 基于STM32的USB程序开发笔记(一) 7 m. Q. z1 [7 F) X5 `5 W+ w : }7 f& K( o" r) n1 w" P 第一篇:需要准备的一些资料 1:STM32的参考手册,这对于设备底层USB的硬件配置以及事件驱动机制的了解尤为重要,你需要了解各个寄存器的功能以及如何操作,比如CNTR、ISTR、EPnR、DADDR等等,如果你想学习USB,这个手册是必须的。 ( P O9 o6 s$ a } 2:USB2.0 协议,这个资料同样必不可少,如果因为英语阅读能力而苦苦寻找中文版的USB2.0协议,建议不要这么做,现在网络中的所谓的中文版的USB2.0协议不是官方撰写的,大多数是一些热心朋友自己翻译的,却不是很全面,如果你在为寻找这类的资料而无所获时,建议认真塌实的看看官方英文版的USB2.0协议,官方协议阐述的十分详细,650多页,一字一句的了解全部协议不太可行,可针对性的重点理解,比如对第9章USB Device Framework的详细理解对于你的USB Device固件开发不可缺少(这里就是STM32)。 ) Q7 h. W; q5 J1 U 3:ST提供的USB固件库,这个类库较为散乱,但不可不参考 / Q# E7 }" Q' Y: X7 k1 p7 W 以下是最近这段时间的成果,包含固件、驱动以及应用程序,固件部分有些功能是不被支持的,如SR_SetDescriptor()、 SR_SynchFrame()等等,在此说明战士不支持非故意如此,而是还没时间仔细深入编写完善,因为这些目前不被支持的部分目前不被使用到。 & @9 k$ N- s/ D' q 后序将接着对各个部分进行一些说明,希望朋友们多多支持,同时欢迎朋友们讨论。 8 T* Z% @: l0 q/ @ 如果你使用的是万利的STM3210B-LK1开发板,则可以烧写hex文件后进行测试。 下载该文件请参阅: http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1808061&bbs_page_no=1&bbs_id=3020 % w. r8 w4 u; i& f- m3 y* M. _ 0 t% ^2 _! |: r, k; m 第2篇:STM32 USB固件函数的驱动原理 首先需要了解一个概念: " _: U9 _& P5 `- f USB 设备(DEVICE)从来只是被动触发,USB主机(HOST)掌握主动权,发送什么数据,什么时候发送,是给设备数据还是从设备请求数据,都是由USB 主机完成的,USB设备只是配合主机完成设备的枚举、数据方向和大小。根据数据特性再决定该不该回复该如何回复、该不该接收该如何接收这些动作。 2 g- N7 T' o; O" t 了解这些,再仔细查看STM32的参考手册USB部分以及STM32的中断向量表,从中可以找到两个中断: /******************************************************************************* * Function Name : USB_HP_CAN_TX_IRQHandler * Description : This function handles USB High Priority or CAN TX interrupts & w. G! ]3 e8 I9 D! C * requests. ( O$ d( i% o: k% Q * Input : None * Output : None " J$ P: P# B [' L p' B * Return : None *******************************************************************************/ void USB_HP_CAN_TX_IRQHandler(void) { USB_HPI(); * ?! L2 r. Y: t! u) D } % |0 H1 b: V" n' b5 i8 n. ? /******************************************************************************* * Function Name : USB_LP_CAN_RX0_IRQHandler 2 W" x6 C. `" l * Description : This function handles USB Low Priority or CAN RX0 interrupts ! ^5 Y/ n( v: I: s * requests. * Input : None * Output : None 2 z' Z7 \9 N) Y5 V8 p * Return : None *******************************************************************************/ + b/ U2 `" E$ B- h: @2 H, h! S# {: ] void USB_LP_CAN_RX0_IRQHandler(void) { ; ?( G: i) D( J2 [4 _9 n USB_LPI(); ! n" [1 H# v: b9 |0 u3 x, [# L5 e v2 \ } 6 d( H( E" Z5 e3 P# _% [ 5 F5 f) ~1 @4 r7 w) w) U: W 即 USB的高、低优先权中断处理函数,这也是整个STM32 USB的事件驱动源,USB_HPI()与USB_LPI()既而转向usb_core(.c,.h)进行相关处理。中断传输(interrupt)、控制传输(control)、大流量传输(bulk)由USB_LPI()响应,大流量传输(bulk)同样可能响应USB_HPI(),同步传输 (isochronous)只响应USB_HPI()。 , [+ A+ K ?$ y+ F( m. i 2 e9 N+ c6 N" X$ @8 m 这样响应USB的所有请求只需要关注usb_core.c文件中的 USB_LPI()与USB_HPI()函数。由于本人也是对USB刚刚有所了解,因而在本例笔记中USB_HPI()函数未做任何处理,在此开源希望大家能完善与纠正错误并能共享喜悦。以下是USB_LPI()函数: // ***************************************************************************** 5 G# x. [4 }# c0 G, i. U // Function Name : USB_LPI. // Description : Low Priority Interrupt's service routine. 0 b! f$ U! }2 }" T ~; B3 q // Input : // Output : / O7 o' K9 L( u+ }3 ? // Return : 8 k. S" x! A7 f; p" y& ~! o8 ? // ***************************************************************************** 8 ]% F+ ]9 i# S5 \( X void USB_LPI(void) 4 H; ~+ e/ b& C9 _6 C/ D4 U { unsigned short wValISTR = GetISTR(); 5 y4 ?1 x& U& j' v6 _ #if(CNTR_MASK & ISTR_RESET) // Reset * P* j( h. z0 F9 H5 o3 Z$ k if(wValISTR & ISTR_RESET & vwInterruptMask) { SetISTR(CLR_RESET); % l' d% O. u6 V INT_ISTR_RESET(); } # z" H, A7 w. ~$ u. m; i1 C #endif #if(CNTR_MASK & ISTR_DOVR) // DMA Over/Underrun if(wValISTR & ISTR_DOVR & vwInterruptMask) { + Q+ U& R9 _5 k7 _ v) h% z8 ] SetISTR(CLR_DOVR); 0 e4 Z4 y! u6 R& L% X INT_ISTR_DOVR(); 0 J* ~( T( m2 Y } & x2 ~9 G* B5 K7 `) V" [ #endif " ^: Z5 Z" v- L* h( s/ b" Q% w #if(CNTR_MASK & ISTR_ERR) // Error 4 G2 V4 X% |4 {/ ^7 [& h, K8 {6 e- m$ _ if(wValISTR & ISTR_ERR & vwInterruptMask) 5 _1 m2 h. h/ O7 b9 b { 8 K0 B2 _0 F2 N- y0 m6 m SetISTR(CLR_ERR); INT_ISTR_ERROR(); A. F0 n. y1 \+ K0 q! ^) T! ^ } #endif # {% H+ t2 R/ k. Y$ {( v" ^( N * e" D" q! y4 Z# D$ F! X" ~/ y #if(CNTR_MASK & ISTR_WKUP) // Wakeup 5 b, \5 L# v) w. n& Y9 c/ i; x0 ~ if(wValISTR & ISTR_WKUP & vwInterruptMask) 1 J5 v: ?" |* l6 X! R- R { SetISTR(CLR_WKUP); INT_ISTR_WAKEUP(); } % O t! X- r0 i( l+ X' G6 Q' d* {* p #endif #if(CNTR_MASK & ISTR_SUSP) // Suspend 8 L }6 J8 m/ K9 N8 l if(wValISTR & ISTR_SUSP & vwInterruptMask) { INT_ISTR_SUSPEND(); SetISTR(CLR_SUSP); // must be done after setting of CNTR_FSUSP 3 o$ g0 s) L8 X" b j } #endif #if(CNTR_MASK & ISTR_SOF) // Start Of Frame if(wValISTR & ISTR_SOF & vwInterruptMask) 0 |& t6 G% S8 V! O) m { SetISTR(CLR_SOF); INT_ISTR_SOF(); , ]7 D; }' Z" ~% A* }' ] \/ { } #endif 5 o! b- P, m' r K* f #if(CNTR_MASK & ISTR_ESOF) // Expected Start Of Frame # R- L7 \( l; u* D4 Z- Z$ S if(wValISTR & ISTR_ESOF & vwInterruptMask) { . Q# w- G% N# Q- e/ ] SetISTR(CLR_ESOF); , h5 e/ _ g8 Y' T2 A+ c! q INT_ISTR_ESOF(); } #endif 5 p3 Z, M" ]1 J, _! c " M5 i4 G8 x5 y; D/ j- M #if(CNTR_MASK & ISTR_CTR) // Correct Transfer if(wValISTR & ISTR_CTR & vwInterruptMask) { INT_ISTR_CTR(); " u' M% @* J1 s& h, l1 W } 9 a1 X; h' I# E2 Z' c% G/ b #endif . F# c4 T" d" B: @ } " S) F8 c/ z/ x& k) C7 A% Q) D l // ***************************************************************************** // Function Name : USB_HPI. // Description : High Priority Interrupt's service routine. ( T# Q y; ]4 E1 D( i+ a8 O2 z // Input : // Output : // Return : , B2 @3 x. D& ]! j6 w: o9 `& \ // ***************************************************************************** void USB_HPI(void) { 7 b8 J3 q% K) T6 h8 t2 F ]5 ^ } * c' k& r4 v; f' Z- M, {1 T 3 \$ R8 G$ w( K9 N 可以看出,在USB_LPI()函数中,根据STM32 USB的中断状态寄存器(ISTR)的标志位的状态以及定义的USB控制寄存器中断事件屏蔽码,响应各自的中断事件,比如 INT_ISTR_RESET()响应USB的复位中断,一般可在此函数内进行USB的寄存器的初始化;INT_ISTR_CTR()响应一次正确的数据传输中断,故名思意,在完成一次正确的数据传输操作后,就会响应此函数。 具体含义请仔细查阅STM32参考手册,下篇将针对这些响应函数进行逐一的详细介绍。 |
|
| 谢谢分享 |
最全USB HID开发资料,悉心整理一个月,亲自测试
【源码】STLINK-V3MINI 高速USB仿真器,成功改刷【高速CMSIS-DAP】
STM32 USB CDC 虚拟多串口
实战经验 | 选择USBX模块生成USB CDC ACM无PD的项目
STM32 USB HID键盘例程
刘氓兔的杂谈【001】-片上USB 高速PHY
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
在线直播|无需编写任何代码即可在STM32上实现USB-C Power Delivery
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
USB Audio设计与实现
微信公众号
手机版