stm32H7 hal库错误内容汇总:2 U4 C& Z9 C7 ]7 `
1. I2S. b! V; z0 O( e! F% V
- HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)5 p5 _: i. ^4 s; t9 E' M4 x) ?
- 函数内部有一个判断
/ w2 S$ x% Y! {; e' n - if (hi2s->State == HAL_I2S_STATE_READY) {
Q) B; ^: K7 K: ~ - __HAL_UNLOCK(hi2s);
/ O& m$ H5 O/ B S5 Q - return HAL_BUSY;
4 s+ g n5 v0 g' W) k$ ~0 t9 { A+ h - }- {8 Y9 c4 K% |
- 函数$ v7 P; D& y( F1 ?
- HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
* r4 D5 B# f9 t9 m( i - {
! I' C: J+ p) Y1 _ - if (hi2s->State == HAL_I2S_STATE_READY)
: J6 w. z% K2 w& M* x- q - {8 E4 D4 v( x& ~" b4 D; ^1 u
- __HAL_UNLOCK(hi2s);. _0 c! H1 A" Y% w1 A
- return HAL_BUSY;
8 ?8 k4 Y/ [7 ^) o( _* N$ J - }
" E8 Y0 |' w D; _ - 中同样有
复制代码 应该改为:
2 F0 f* O, o& u) ^- if (hi2s->State != HAL_I2S_STATE_READY)
复制代码
+ P$ M& X# ^ P! n# [& z7 J; z2.寄存器定义/ }8 ]0 d0 v& U9 T) k
我用的HAL库版本为V1.2.0;
5 H8 {1 l2 A8 ~# G% q( G其中Device中的STM32H743XX.h中寄存器定义错误。0 J0 l+ A7 b* j
- #define SPI_I2SCFGR_WSINV_Pos (12U)
8 F/ G7 ]* H' Z) [- J/ G2 @* B - #define SPI_I2SCFGR_WSINV_Msk (0x1U << SPI_I2SCFGR_WSINV_Pos) /*!< 0x00001000 */0 B6 V. z/ P; Q! ]% N* m
- #define SPI_I2SCFGR_WSINV SPI_I2SCFGR_WSINV_Msk /*!<Word select inversion */5 t$ w! J( W2 F& h
- #define SPI_I2SCFGR_FIXCH_Pos (13U) 6 _% K* j. M7 a1 Q7 O+ y
- #define SPI_I2SCFGR_FIXCH_Msk (0x1U << SPI_I2SCFGR_FIXCH_Pos) /*!< 0x00002000 */1 V0 u+ T. \+ S H5 {$ ?, t# k
- #define SPI_I2SCFGR_FIXCH SPI_I2SCFGR_FIXCH_Msk /*!<Fixed channel length in SLAVE */8 W2 i( L+ f2 G5 ^4 A$ M
- #define SPI_I2SCFGR_DATFMT_Pos (12U) 2 @, U2 m5 I9 s1 E
- #define SPI_I2SCFGR_DATFMT_Msk (0x3U << SPI_I2SCFGR_DATFMT_Pos) /*!< 0x00003000 */
6 z# Z2 g9 s `2 C0 p1 G% s - #define SPI_I2SCFGR_DATFMT SPI_I2SCFGR_DATFMT_Msk /*!<Data format
复制代码 9 x. F" G" |1 w2 e4 ?7 ~
4 w# F2 E E4 T3 x
* s7 B' H; I% H1 [# A3 L3 ]
6 M1 X- T/ V1 s2 W" U跟寄存器定义不同。
$ M$ O9 q+ V$ ?. e3 S
! s7 `" s# q! i9 y0 l所以最好使用新的固件库,但项目之前用的旧固件库,并且没有用到I2s。
8 z; M* f: Z2 X# A5 o9 P, `, N# L9 ~. c, k% n8 U' I7 ?$ k
还是关于I2S的坑,这次使用的HAL库版本是在官网下载的最新版本0 W: ^4 s3 v [' u
FW_H7_V1.5.0.在使用全双工I2S时,需要包含2 {; Y7 k; c: V0 a3 l
stm32h7xx_hal_i2s_ex.h 头文件
: l% b/ M5 m0 B, x但是0 R; _1 H& _3 i$ a$ t7 {/ C7 ~7 F
. H! L* \ t) ]* J6 K% K2 a* o
0 @' |+ N5 J6 k; j图中宏定义根本找不到 ,自己添加宏定义后一堆错误 我也是服了。% u1 ]7 L2 w/ ]5 s0 Z0 z4 v
有了SAI就对I2S这么不上心吗?
- c& s* a* c8 R# D* t- T8 k- X" L3.USB device卡死在HAL_PCD_IRQHandler中导致主程序无法运行' n. Q# @" N @8 j+ k/ P6 z; p
但并未出现错误
2 P/ F* {1 I9 @' P% P调试发现
1 U: H; D3 G/ Y) r7 ?程序一直进USB_OTG_DIEPINT_TXFE 即TX FIFO 为空中断
& U0 X2 q/ b2 U, K( p: f+ k: G既然如TX FIFO 后 正常逻辑需要往TX FIFO 中填充数据 测试发现并没有,4 @: [; K8 C9 z# ^9 L" f7 ~
发现 (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) 刚好等于len32b导致条件不满足
3 A$ ~5 G, i* M% o/ x' Y又一直进FIFO为空中断 一直在中断中运行 形成死机现象
) i' Q* e( E: r9 d对比 HAL库1.5.0发现此处已更改为>=
0 r- k- r7 j: P更改后不会死机 但是 USB连接不上时仍需重启
! g; N6 L/ l2 d2 _' P库文件原代码 此BUG在F4驱动库中也存在 已更改' t \/ t' ^8 N3 F
- PCD_WriteEmptyTxFifo 函数
; O' y# |+ Y; n3 U+ N% q
# o F) T+ G1 G6 R h# f q2 @- static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
( o4 n8 N& e4 q: T& o - {
; X9 z& e0 k0 y* Z5 @( ~" v - USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
( z9 a! q) P8 K* u2 g' [5 t - USB_OTG_EPTypeDef *ep = NULL;
7 x6 V/ [( u) I7 z8 `& {/ i - int32_t len = 0U;% ^$ e; h. t/ t% }* i/ N: l" U
- uint32_t len32b = 0U;* m' y2 ^8 a' e
- uint32_t fifoemptymsk = 0U;
' L' q9 g7 O1 w: n - 9 J; f: ?% {; J$ t: A+ _
- ep = &hpcd->IN_ep[epnum];
" d9 |, X G2 V. B2 ~6 h, z - len = ep->xfer_len - ep->xfer_count;; o" C! e. R8 B/ ~
9 X* L- F0 S0 ~) Q4 ]) v- if (len > ep->maxpacket)8 [5 g6 [ p! S
- {
9 Z) j) o4 @0 f( d - len = ep->maxpacket;
+ Q8 s R! r/ E8 O: I8 k' \# \- B - }
5 P: v1 x- T& c9 ~* N7 Y/ Y
+ j' X& B& i& ?2 F3 X3 X1 Q- , v9 W5 c! |4 Z5 v# X0 A6 W
- len32b = (len + 3) / 4;' f' h! c7 O9 @7 E0 a; f% L4 K3 O
- ; ^9 F: ?' t, m
- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
) h7 k2 a3 d6 i& x- Q - ep->xfer_count < ep->xfer_len &&
& G2 v9 h$ e; O' F w( k7 { - ep->xfer_len != 0)- u5 m" u5 ?# r
- {/ V; W& K9 ]; y- w
- /* Write the FIFO */
: f; @, u1 |/ i2 R( ^* S4 P - len = ep->xfer_len - ep->xfer_count;
- O/ p2 j' R+ Q* \1 y+ {* ]5 p' Y
3 Z6 L7 s" n; E- if (len > ep->maxpacket)
0 M8 h; _0 F A' X, w& K* K0 Z - {
8 V: R" [) p& l - len = ep->maxpacket;
. H4 z- Z# Z8 \2 X1 E( e - }8 R. `* \6 ~7 P4 e% ~& U: M9 F
- len32b = (len + 3) / 4;
d, a% i. l; E+ e8 O. ?# V* | - 6 s: Z0 S k5 k( H& O" _
- USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
6 e& v7 M4 _2 P - 5 W/ c+ _; t2 T _( E
- ep->xfer_buff += len;
" _) E+ F& C5 A0 ] - ep->xfer_count += len;
( A7 C8 H/ c. Q! z - }
- F& I8 {2 G2 D9 r! y$ m. p
* C. [; ?6 z0 L5 n& x/ E- if(len <= 0)
$ e1 g* [, G" K9 G6 k H - {
' e' J6 y& k! x" j# f- a/ v, @) @ - fifoemptymsk = 0x1 << epnum;
4 p8 `9 s& B0 ]+ i+ w8 E; } - USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;: f8 Q; I% F' b1 i9 B0 D
- x- Z: f" ?3 {- }
: o) B) K0 D; ^
4 m* Q; d' s2 ]8 c' H6 m; `, q- return HAL_OK; ) M1 {* m4 x- w" a9 C! l* A( I$ l
- }
复制代码
5 Q, ^5 ^( f; l8 [7 s% L/ A需要更改为
* Q' r) k! i8 R$ R2 z- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b &&. l& ?3 R2 _9 m! o
- ep->xfer_count < ep->xfer_len &&
8 q5 A! w/ z2 f1 ]. m7 b - ep->xfer_len != 0)
复制代码 不然会一直进中断但又出不来
- d8 {; o& e$ q( D) ] ^. t& z% c a0 ~
总结: 能用最新的HAL库就用最新的吧 可以避免很多坑5 c3 Q" r( m! ~% [. [8 J
实在不行可以结合寄存器版本的函数来写,直接写寄存器还是比较靠谱,但是要参照HAL的流程
4 M( ~& Z$ `( y0 H: Y! Q8 T+ y/ h( Z" l8 ^, U, \
/ _' i! ^) `4 H' v( N" u- g' _" b* I- ?; X
! I" G- ]$ C1 o" ~: G( X |