stm32H7 hal库错误内容汇总:
J8 n) P4 i: O1. I2S" m* H4 ^4 e8 q( E
- HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)3 u* }+ x3 W5 O4 @% t( Z# W
- 函数内部有一个判断
8 ^, x) `! v- F9 R6 n - if (hi2s->State == HAL_I2S_STATE_READY) {" h8 P, B; ]+ e8 Q3 H c
- __HAL_UNLOCK(hi2s);
" Q' z {* U, h - return HAL_BUSY;- e4 S/ ^8 T7 U! [8 ~8 Z/ _& Q& u
- }
, w' f/ L( ^/ d5 _+ D5 \& s }. h" s1 y - 函数- _& G* A, D7 L
- HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)' t; Q, m! U' p. d1 r" I! E
- {
7 l' E8 s3 Y5 v ~2 V" V - if (hi2s->State == HAL_I2S_STATE_READY)& q' }& ~0 v1 a8 E6 D
- {
- S' h5 w4 p/ c6 ^6 U - __HAL_UNLOCK(hi2s);
) {- L$ d D7 s& h( K; F# _* A - return HAL_BUSY;
3 C+ } T6 S) f* ` - }. d( V- c, }. w w
- 中同样有
复制代码 应该改为:6 l7 U! g+ y3 U3 c" e( H, a
- if (hi2s->State != HAL_I2S_STATE_READY)
复制代码 $ y; v* ]2 P$ ^2 U. f# G
2.寄存器定义% t" q/ F7 Q) ]. z+ B2 M
我用的HAL库版本为V1.2.0;" U; O$ y& E# y+ _
其中Device中的STM32H743XX.h中寄存器定义错误。5 m: f! r+ ?4 C' F5 ~! Y
- #define SPI_I2SCFGR_WSINV_Pos (12U) " W( X# ~/ z# @% }; D
- #define SPI_I2SCFGR_WSINV_Msk (0x1U << SPI_I2SCFGR_WSINV_Pos) /*!< 0x00001000 */: g2 N1 V: C# I2 w% P' {3 ]
- #define SPI_I2SCFGR_WSINV SPI_I2SCFGR_WSINV_Msk /*!<Word select inversion */
8 U i) D& ^5 ~+ w/ r - #define SPI_I2SCFGR_FIXCH_Pos (13U) r( u* `# C* j8 o& \+ |: g+ b4 W
- #define SPI_I2SCFGR_FIXCH_Msk (0x1U << SPI_I2SCFGR_FIXCH_Pos) /*!< 0x00002000 */# h- P% O5 h0 v. V& l% T) {
- #define SPI_I2SCFGR_FIXCH SPI_I2SCFGR_FIXCH_Msk /*!<Fixed channel length in SLAVE */
0 X# k, R" N9 U) X+ J - #define SPI_I2SCFGR_DATFMT_Pos (12U)
3 ?1 U% i# R2 O6 M ^3 d5 X - #define SPI_I2SCFGR_DATFMT_Msk (0x3U << SPI_I2SCFGR_DATFMT_Pos) /*!< 0x00003000 */4 A1 r5 |/ O( l4 a1 {* C& t8 n
- #define SPI_I2SCFGR_DATFMT SPI_I2SCFGR_DATFMT_Msk /*!<Data format
复制代码 ) o$ {2 @6 ~2 I+ \0 n" Y* I
. O5 P5 a6 r- K* F
' U; G2 G, y4 o% G2 t5 B- z7 j1 n I8 `! B& Z# W# `
跟寄存器定义不同。
4 t7 p f* d6 A8 G1 s. T' _7 A G& U
" z+ {; w$ w5 b$ c0 q所以最好使用新的固件库,但项目之前用的旧固件库,并且没有用到I2s。
8 `1 @ K8 T. y% w/ G4 E3 u" H; F# g" a
还是关于I2S的坑,这次使用的HAL库版本是在官网下载的最新版本
# |" X' d$ m1 I* Q$ K a/ iFW_H7_V1.5.0.在使用全双工I2S时,需要包含
. U7 T* |- ]: P) Y4 _stm32h7xx_hal_i2s_ex.h 头文件9 h( d9 b8 a# L
但是
: ?. R, w* Z/ a9 Z& v3 U
9 r) b" c$ q8 j6 R; |+ {9 F- \* D3 u1 Y3 H: g
图中宏定义根本找不到 ,自己添加宏定义后一堆错误 我也是服了。5 c0 {6 ^ L, `1 Y' J0 A
有了SAI就对I2S这么不上心吗?- `( S6 Y4 X" `" S
3.USB device卡死在HAL_PCD_IRQHandler中导致主程序无法运行6 ^) X# `: L8 g" g4 f% s
但并未出现错误% g$ X5 j3 D9 b" `3 \
调试发现% d3 J1 a0 L7 X8 Y# K) _3 R8 i3 N7 r
程序一直进USB_OTG_DIEPINT_TXFE 即TX FIFO 为空中断- I$ Z. n! j7 B+ Q9 k
既然如TX FIFO 后 正常逻辑需要往TX FIFO 中填充数据 测试发现并没有,
& s3 k2 j# g7 r/ N H0 u发现 (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) 刚好等于len32b导致条件不满足
1 C$ m, O7 I+ Q) H- j; c c又一直进FIFO为空中断 一直在中断中运行 形成死机现象
3 V# F( R4 ~4 z) ]对比 HAL库1.5.0发现此处已更改为>=
& T, M n ?3 X; Z更改后不会死机 但是 USB连接不上时仍需重启
6 U: O2 P) d" `; e库文件原代码 此BUG在F4驱动库中也存在 已更改; ~ `5 N1 l" \2 b/ S
- PCD_WriteEmptyTxFifo 函数
+ E2 a8 {/ S3 O* s - # H- H6 L! c: g5 E! F* E
- static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)& {- K, \ J) B; P
- {
2 j$ q" @% X9 h! r - USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
6 X% v/ e& a% X' K2 _3 V - USB_OTG_EPTypeDef *ep = NULL;
, V0 T a: f3 t: D" @$ E - int32_t len = 0U;
+ p) G1 @8 d, X3 v( l7 U1 J - uint32_t len32b = 0U;: k8 J4 p! A) R: R4 ?6 U# _/ T7 w7 C
- uint32_t fifoemptymsk = 0U;
$ {; Y5 Q+ n* i0 f1 ^
! V! y0 r- S/ _2 \8 {- A2 u6 |9 f- ep = &hpcd->IN_ep[epnum];# [# W+ r, P8 a. N2 r
- len = ep->xfer_len - ep->xfer_count;& K6 l: |; ]6 ]) b$ i8 b- G
/ k3 Y3 ]1 m9 ]+ t/ q- if (len > ep->maxpacket)
% m' Z* O; D" u4 W7 ~3 P2 A0 U0 k - {2 Q6 M0 S1 S# o1 W
- len = ep->maxpacket;2 Z+ v2 x6 {4 v* g6 v
- }
3 z2 t/ Q% M- Y: C; U( @
3 {6 m/ `1 I0 \5 e! r- 8 W) r; n7 \+ K5 r% Y: s9 ?$ L% c* j
- len32b = (len + 3) / 4;
% Y) Y2 H! v7 I
; k2 G% d) u9 Q! V- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
: u) L6 p' X, L. {/ h - ep->xfer_count < ep->xfer_len &&
l+ c# l& m! H5 z! ^$ h8 \1 h1 G5 X5 E - ep->xfer_len != 0)
3 a" n4 y6 I5 Y. c8 D/ _ - {6 }' L( S# s* g8 i+ z; d: ^: w4 V
- /* Write the FIFO */& S3 Y, ^9 L* f: `: n$ f
- len = ep->xfer_len - ep->xfer_count;
! p3 X" X. \2 l# }- q
% x6 _8 [5 x+ Q' _8 }- if (len > ep->maxpacket)
2 Z% p5 E/ r# z3 i0 g3 Z' F3 r$ V6 Q9 A - {! P8 `0 p" M* f: d9 h- R5 K( R
- len = ep->maxpacket;' [* M( t' r7 Q& r* c
- }. j# V4 z* S+ ?2 @' F
- len32b = (len + 3) / 4;
2 S( e& d; v/ C - % S1 E) q% P, Y) s, z5 E
- USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); # [* V* U& F) d. M5 c: z: Q" `6 D
- 9 j5 z7 S+ G6 f# X' \
- ep->xfer_buff += len;
% K, v0 w# y1 e z* [ - ep->xfer_count += len;6 I& @! Y0 \9 [9 u' l2 H8 k
- }
' X0 o) Z! J8 R5 a9 T - 4 ^3 F0 O/ z5 z2 z1 [. ~6 V
- if(len <= 0) O- ]) N. P/ m! U; C$ d! @
- {
) u) R, y; Y6 B - fifoemptymsk = 0x1 << epnum;# y+ `# H/ V7 D
- USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
5 V- m' O: G0 [7 U; \! }) D# }9 ` - 8 e$ Z$ `$ k6 i
- }
" O2 ~6 h0 C" S
1 Z8 }- S* G% o7 d0 O, v- return HAL_OK; ' v3 N* [6 X3 C1 e; k5 G- X, L
- }
复制代码 / Y9 G' O8 j& s0 {/ s! k
需要更改为
, T* T3 n2 E* o. D6 _0 W0 v- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b &&
: U. C# v4 s5 Q - ep->xfer_count < ep->xfer_len &&
! Z% J! d) \0 A2 @/ \! y - ep->xfer_len != 0)
复制代码 不然会一直进中断但又出不来
% b Y+ ^& Y8 t1 _8 t3 D! G2 S/ |3 U- q3 q ~/ e& u
总结: 能用最新的HAL库就用最新的吧 可以避免很多坑
0 d8 F& F& N- h3 D1 y* }, j实在不行可以结合寄存器版本的函数来写,直接写寄存器还是比较靠谱,但是要参照HAL的流程
: e) `6 R8 f/ m% f* z, k* i( O% `; n4 t& Q. x1 t* V
8 c% e5 S3 `8 q z- C
3 M1 z( k, s; f. L+ h' ?$ I' ?7 n( v' S; B& \
|