你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的USB程序开发笔记(一、二)

[复制链接]
乡村布拉德 发布时间:2008-12-23 11:48
lbxxx原创 
# P; k; d& D% X7 P/ E4 f: r7 T. D; Q7 Y# _7 N5 M) M: \. c
 - @0 R1 r3 @' ~) g6 F, e! H" E3 |
基于STM32的USB程序开发笔记(一) ; @7 o3 ]8 D% F7 m; r' D

( ]7 v) X' H. f5 E0 Z第一篇:需要准备的一些资料
4 C( |* k/ a8 w6 a
/ [( O6 _$ s9 R1:STM32的参考手册,这对于设备底层USB的硬件配置以及事件驱动机制的了解尤为重要,你需要了解各个寄存器的功能以及如何操作,比如CNTR、ISTR、EPnR、DADDR等等,如果你想学习USB,这个手册是必须的。   d; M! P5 b- T% F! z( ~
2:USB2.0 协议,这个资料同样必不可少,如果因为英语阅读能力而苦苦寻找中文版的USB2.0协议,建议不要这么做,现在网络中的所谓的中文版的USB2.0协议不是官方撰写的,大多数是一些热心朋友自己翻译的,却不是很全面,如果你在为寻找这类的资料而无所获时,建议认真塌实的看看官方英文版的USB2.0协议,官方协议阐述的十分详细,650多页,一字一句的了解全部协议不太可行,可针对性的重点理解,比如对第9章USB Device Framework的详细理解对于你的USB Device固件开发不可缺少(这里就是STM32)。 " s: T/ N" i8 G* A8 W
3:ST提供的USB固件库,这个类库较为散乱,但不可不参考
- @4 C+ w! w/ [4 g2 E' N: Q2 E+ h0 u& v$ l4 E# z7 Q
以下是最近这段时间的成果,包含固件、驱动以及应用程序,固件部分有些功能是不被支持的,如SR_SetDescriptor()、 SR_SynchFrame()等等,在此说明战士不支持非故意如此,而是还没时间仔细深入编写完善,因为这些目前不被支持的部分目前不被使用到。 7 C) S1 B/ @4 L$ n
后序将接着对各个部分进行一些说明,希望朋友们多多支持,同时欢迎朋友们讨论。 0 w' ^! x- j0 r6 [7 m+ _: j7 ?
如果你使用的是万利的STM3210B-LK1开发板,则可以烧写hex文件后进行测试。
6 C. U, }! E6 D: P
) N/ t5 O+ a6 M( I8 p; m下载该文件请参阅: 4 G2 R$ h+ m4 ]
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1808061&bbs_page_no=1&bbs_id=3020 % t1 `3 c9 s3 N9 Q) Z
/ W4 d8 }  `4 H

8 `! `9 c0 E! e第2篇:STM32 USB固件函数的驱动原理
# G+ f* J  N& e! ]7 G首先需要了解一个概念: 2 `# |& @1 l  V6 a  V- P  {5 D
USB 设备(DEVICE)从来只是被动触发,USB主机(HOST)掌握主动权,发送什么数据,什么时候发送,是给设备数据还是从设备请求数据,都是由USB 主机完成的,USB设备只是配合主机完成设备的枚举、数据方向和大小。根据数据特性再决定该不该回复该如何回复、该不该接收该如何接收这些动作。
  h. `2 [- z2 h. X  p  g( \了解这些,再仔细查看STM32的参考手册USB部分以及STM32的中断向量表,从中可以找到两个中断: 7 Y( t- F% y$ M& u# J
/*******************************************************************************
! B3 s6 D' V! p( `; ^' ]) G* Function Name  : USB_HP_CAN_TX_IRQHandler " E3 s& A3 D+ e4 L* }1 b: }
* Description    : This function handles USB High Priority or CAN TX interrupts ( k# C( D: [% }$ U* j0 R
*                  requests.
$ E# K/ j  v5 ~; Z* Input          : None " k( y0 h# Y8 R/ A
* Output         : None ; G& w8 Q/ Z9 w1 E4 [$ a
* Return         : None
/ e3 @+ R+ C& V( Z+ y4 |*******************************************************************************/ ; k5 _1 Y+ _$ h- ^' |/ ]
void USB_HP_CAN_TX_IRQHandler(void) / n, G1 Q/ ?6 S. d- a$ p
{   {4 K( b& t1 P  T4 e6 _( m
  USB_HPI(); ) Q3 O1 a5 w. R5 w% g# u7 C. `! P
}
! ?, ]1 O) n* o' u; ~
! L& l+ _; b4 B) L/*******************************************************************************
' ]& i' H$ E$ C" h7 f! i" J7 G* Function Name  : USB_LP_CAN_RX0_IRQHandler * a9 p- D& F& B: ~. [; [
* Description    : This function handles USB Low Priority or CAN RX0 interrupts $ ?) H1 J& x7 Q
*                  requests. ) V$ R/ T1 C6 g8 o- i
* Input          : None
7 m' n6 k# ]+ n) \7 w& ^* Output         : None * _* d1 M0 k: A' b/ ^8 P! t6 h
* Return         : None ( w! T# o, y: a
*******************************************************************************/ 3 C0 ]4 P) Q8 I" ^
void USB_LP_CAN_RX0_IRQHandler(void)
" P" ^- Y$ m: ]: L, A# y$ a{ ( A/ d" e& u) e: Z5 g! q) k3 b
  USB_LPI(); ( ~) X, @( m; z, I
}
6 Y9 T: @5 X3 Z" s; u% n
( A0 s/ W% P2 R- Q/ ]即 USB的高、低优先权中断处理函数,这也是整个STM32 USB的事件驱动源,USB_HPI()与USB_LPI()既而转向usb_core(.c,.h)进行相关处理。中断传输(interrupt)、控制传输(control)、大流量传输(bulk)由USB_LPI()响应,大流量传输(bulk)同样可能响应USB_HPI(),同步传输 (isochronous)只响应USB_HPI()。 % U/ W1 P" Z3 j# C4 J

* r& B/ v& i2 F3 p这样响应USB的所有请求只需要关注usb_core.c文件中的 USB_LPI()与USB_HPI()函数。由于本人也是对USB刚刚有所了解,因而在本例笔记中USB_HPI()函数未做任何处理,在此开源希望大家能完善与纠正错误并能共享喜悦。以下是USB_LPI()函数:
8 J4 f7 ?- H+ @; d2 q// ***************************************************************************** 7 D6 ]* n1 b2 w( y0 f" l2 M1 H
// Function Name  : USB_LPI. ) l- m) C- S5 {
// Description    : Low Priority Interrupt's service routine. - w0 {. D& b5 x( z% `: j( o& h
// Input          :
1 v/ @6 N9 ]- e, O, ]7 i! y// Output         :
( H5 W% b8 [8 g* b$ k' |// Return         : & ]1 m- t& ^1 b5 @$ k4 u
// *****************************************************************************
: V- v7 Q4 t6 \6 Cvoid USB_LPI(void)
' _" _) B; E2 E( [+ U+ ~# ^7 C/ H0 I{ ; s( F* b7 E0 j! y
  unsigned short wValISTR = GetISTR(); & R& {1 y+ t8 @6 V4 A6 w
9 U3 b8 ^& K  @4 _( U
#if(CNTR_MASK & ISTR_RESET)   // Reset
; }! \$ }$ t* S) z1 C5 A  if(wValISTR & ISTR_RESET & vwInterruptMask)
% @( G8 E; r% Z# y1 Q  { , F! t9 n9 p" f9 T- V* O, g& b
    SetISTR(CLR_RESET); 2 Z, |: W( V! K7 Z3 L
    INT_ISTR_RESET(); " n0 d( j$ i" A
  } 1 D6 }5 f% u' E4 T6 I/ U% J; x% e
#endif
5 s' a3 U" J8 n7 h5 @! {* }! J+ N+ |( J1 T1 `# S8 ?; u
#if(CNTR_MASK & ISTR_DOVR)   // DMA Over/Underrun
! {8 I1 x# u. ?9 O2 [) d  if(wValISTR & ISTR_DOVR & vwInterruptMask) 8 X9 |# R5 S, ?7 k; L, B. [
  { : z/ C, p; p2 Y/ g, z& }5 l
    SetISTR(CLR_DOVR); : f: O" [" x! o% s
    INT_ISTR_DOVR(); ) ], r% H' H$ o1 U/ \1 d; U
  } 0 r, `( n/ Q5 e. u; j2 `) S# P
#endif
, p& t8 J( O; t$ Q0 o
" C# g) f: l$ V' X#if(CNTR_MASK & ISTR_ERR)   // Error + q- I* H1 x8 p
  if(wValISTR & ISTR_ERR & vwInterruptMask)
+ z: w6 S& G9 C- K  { 4 z& j$ U- j9 F, w. O( {9 M8 C
    SetISTR(CLR_ERR);
4 x/ E  k7 i/ D: }    INT_ISTR_ERROR(); + Q1 ^* G6 M4 V5 E7 u
  } 8 W* ?$ }) M: W. [8 {$ |
#endif * F2 l1 W0 ^) S" {8 @

# O& s- e$ b  w) |8 W#if(CNTR_MASK & ISTR_WKUP)    // Wakeup
+ B9 H# }1 Y$ F) \! a' m( K: T  if(wValISTR & ISTR_WKUP & vwInterruptMask) ; D! U3 j/ h8 W6 {2 U* d; N- e8 b
  {
& h, X/ A+ |6 z7 ?. ?0 o! m    SetISTR(CLR_WKUP); 5 e( G9 A/ J8 k: K) B
    INT_ISTR_WAKEUP(); ) N8 C0 o0 p- A! c9 m. b
  }
; t8 }& W% D# s# q% D#endif . k5 g6 v7 X! f+ O0 E6 C: K9 D' K
1 e8 E/ @; C5 ^5 T
#if(CNTR_MASK & ISTR_SUSP)   // Suspend ! x6 X/ q/ f  `6 o+ X; n
  if(wValISTR & ISTR_SUSP & vwInterruptMask)
- D, @( r4 l$ ]( Z% R  { + g* s$ j+ h) `2 v
    INT_ISTR_SUSPEND();
' P2 ?( b8 d, m; W3 l( s    SetISTR(CLR_SUSP);     // must be done after setting of CNTR_FSUSP
: b% }/ p# }* j3 O" |* O  }
$ R+ @9 J1 o) z( j#endif % h0 `% \1 G& [! s4 D
1 b" m4 k9 L5 N
#if(CNTR_MASK & ISTR_SOF)   // Start Of Frame " ~5 U( ~8 m5 D; m7 h  ?. I. i5 b
  if(wValISTR & ISTR_SOF & vwInterruptMask) " g4 J3 q5 j  t/ _% M" E
  { . @) ^: F: R+ D) G
    SetISTR(CLR_SOF); : w2 b/ b9 S: A3 X, U/ l  F8 ?
    INT_ISTR_SOF();
2 g! L6 t: H& q* j  }
! ^/ X& Y/ p4 z8 Y#endif
1 J0 c5 Y! \% ?# b! D6 J. K: J6 j: H7 }0 A- e. c; y
#if(CNTR_MASK & ISTR_ESOF)   // Expected Start Of Frame + Y, V! W) P/ {
  if(wValISTR & ISTR_ESOF & vwInterruptMask)
% D  @* B* \4 X( S+ m* H) z0 g  { 0 ?0 J- m9 U0 }' ?* m+ X
    SetISTR(CLR_ESOF); ( e: |* L, p5 r; E/ C/ C# f
    INT_ISTR_ESOF();
, C% W0 S% M8 @0 R3 v( L- n  }
  _4 Z, y" p: J#endif
/ M; u, K3 z+ J5 t
2 [: O1 E) f. {. ]( T#if(CNTR_MASK & ISTR_CTR)   // Correct Transfer
7 B. O" k" e4 G5 B- p  if(wValISTR & ISTR_CTR & vwInterruptMask) 6 ^0 Y. T3 Y7 f1 F
  { & p' d& l& e, r: W$ z/ {8 Z5 G
    INT_ISTR_CTR();   U$ h" d6 l5 `( t, \* l
  }
, ^6 y+ R& u8 |; ]#endif
  j; \4 w+ @8 u- j& o6 I$ H}
: V4 `3 g! y6 O- e' H: j2 P: g( ^9 I
// ***************************************************************************** , R6 `/ p$ c' M
// Function Name  : USB_HPI. 0 p! ^2 }# x  M, \
// Description    : High Priority Interrupt's service routine.
* X6 I. h# h' D  m; K& r  }5 r+ J$ a; H// Input          : 5 d& q3 x- g/ F
// Output         :
/ a4 u0 {2 k6 V$ [// Return         :
( P8 ^$ k# m. T/ i// *****************************************************************************
: K7 s4 x& z; \" Evoid USB_HPI(void) " O; o$ ]& l3 I$ Z% B1 C: y- W7 d
{
+ i3 x: |' L; U& e( @, o 
* i5 X: h, ~4 ?; Q} 9 B! c; C2 x+ v
: g0 a6 R* z( F4 S3 j4 C# `: Y
可以看出,在USB_LPI()函数中,根据STM32 USB的中断状态寄存器(ISTR)的标志位的状态以及定义的USB控制寄存器中断事件屏蔽码,响应各自的中断事件,比如 INT_ISTR_RESET()响应USB的复位中断,一般可在此函数内进行USB的寄存器的初始化;INT_ISTR_CTR()响应一次正确的数据传输中断,故名思意,在完成一次正确的数据传输操作后,就会响应此函数。
$ l: k) B7 B; p# O, J. A' X具体含义请仔细查阅STM32参考手册,下篇将针对这些响应函数进行逐一的详细介绍。
收藏 1 评论2 发布时间:2008-12-23 11:48

举报

2个回答
党国特派员 回答时间:2015-1-21 09:27:29
1.png
子曰小玖 回答时间:2015-1-21 09:53:17
谢谢分享

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版