stm32H7 hal库错误内容汇总:2 S+ i. ^1 P: S( X. V
1. I2S
1 g& U8 O: S# d0 N* b- HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)2 @" t- s8 K u$ \9 D
- 函数内部有一个判断3 Q, P5 s8 w1 u! ~
- if (hi2s->State == HAL_I2S_STATE_READY) {
& Z5 P7 e! s% t, W$ Z% y6 [ - __HAL_UNLOCK(hi2s);
b" w# U$ b. W/ R - return HAL_BUSY;
' L1 t- }7 v" X1 I* p - }
8 r0 ]) Q' t& v) q$ Y. y: w; T - 函数- d/ \9 c* _! D. P' ^5 B& [
- HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
7 n0 n1 }5 T5 X2 o% { - {
' p2 x! t9 t( @/ H$ G9 [9 m2 W - if (hi2s->State == HAL_I2S_STATE_READY)
% I) r, A3 g( ` - {
& M' f7 X d& x+ J$ ` ~ - __HAL_UNLOCK(hi2s);
9 q. T$ K3 q/ q2 f - return HAL_BUSY;1 ~( b9 u& t1 [! _- \
- }1 _- Z- A8 v. o+ Y* p$ B
- 中同样有
复制代码 应该改为:
8 i8 {% t" r5 M+ h+ t" o b- if (hi2s->State != HAL_I2S_STATE_READY)
复制代码 . S$ k P8 N' K8 L
2.寄存器定义
) F9 U/ }+ @: i$ f' H我用的HAL库版本为V1.2.0;6 f) [& p3 k: k& t- ?
其中Device中的STM32H743XX.h中寄存器定义错误。/ W4 K. W3 V( l+ P4 c1 H6 M
- #define SPI_I2SCFGR_WSINV_Pos (12U)
/ f2 j) W# `3 _ - #define SPI_I2SCFGR_WSINV_Msk (0x1U << SPI_I2SCFGR_WSINV_Pos) /*!< 0x00001000 */
! A. L7 O- O E- b - #define SPI_I2SCFGR_WSINV SPI_I2SCFGR_WSINV_Msk /*!<Word select inversion */# c5 T# _% U% ?& D
- #define SPI_I2SCFGR_FIXCH_Pos (13U) ) j1 L# e, Q4 ?; X
- #define SPI_I2SCFGR_FIXCH_Msk (0x1U << SPI_I2SCFGR_FIXCH_Pos) /*!< 0x00002000 */
" n$ L j7 ]" Y/ Z/ u0 A" c0 e- _. R6 X - #define SPI_I2SCFGR_FIXCH SPI_I2SCFGR_FIXCH_Msk /*!<Fixed channel length in SLAVE */
! ~1 ~3 e$ h( ]* v% r - #define SPI_I2SCFGR_DATFMT_Pos (12U)
2 p9 ^, P$ ~' Q0 i - #define SPI_I2SCFGR_DATFMT_Msk (0x3U << SPI_I2SCFGR_DATFMT_Pos) /*!< 0x00003000 */" V5 P, P; T9 i) A5 L7 p' A
- #define SPI_I2SCFGR_DATFMT SPI_I2SCFGR_DATFMT_Msk /*!<Data format
复制代码 1 R( w& Y4 b2 c/ A7 B! ~ U; G
. k7 h2 h4 V, U2 s% c! ?3 Z( m
) X+ k! r$ H' Y* y( H
2 N0 Y. G w6 x! I1 c跟寄存器定义不同。
7 |8 m9 V( H$ P4 g! R2 ^* p
5 p, f1 t) C8 }! X! [5 F所以最好使用新的固件库,但项目之前用的旧固件库,并且没有用到I2s。! o, O+ Z& r! _2 r( q, q' _
0 n6 K2 Q/ \6 W- r8 [ K- x Z还是关于I2S的坑,这次使用的HAL库版本是在官网下载的最新版本
* G0 n5 A- ^8 C% F1 w2 r7 i9 _( SFW_H7_V1.5.0.在使用全双工I2S时,需要包含) @& | U1 a: q2 R0 @- y, M/ f. G
stm32h7xx_hal_i2s_ex.h 头文件
( u- C; C4 K& k: H6 Q J7 l$ X但是+ M: o, a1 L) B$ D" }4 m0 J9 J! |7 i
7 n( }( ^. o' ]) t. W$ r7 n* _4 t
图中宏定义根本找不到 ,自己添加宏定义后一堆错误 我也是服了。5 n% H' _1 z+ Z o7 B
有了SAI就对I2S这么不上心吗?
) c6 B4 i" F, V7 m1 v) ^- {3.USB device卡死在HAL_PCD_IRQHandler中导致主程序无法运行
/ A+ U# T( ?( S但并未出现错误
$ Q7 F9 I! j7 a4 K! u& U& v( l1 g调试发现
+ \) o! x3 w2 d" }7 f m程序一直进USB_OTG_DIEPINT_TXFE 即TX FIFO 为空中断& _4 \: U/ `. p6 a7 I
既然如TX FIFO 后 正常逻辑需要往TX FIFO 中填充数据 测试发现并没有,
) u+ [ d' Z$ `; C. ^5 A发现 (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) 刚好等于len32b导致条件不满足
- c3 ?/ M8 }- f' e又一直进FIFO为空中断 一直在中断中运行 形成死机现象* e7 o _& d) F8 M9 l
对比 HAL库1.5.0发现此处已更改为>=
2 A* D4 b, M5 L更改后不会死机 但是 USB连接不上时仍需重启
- W- ^0 _$ g: [4 [库文件原代码 此BUG在F4驱动库中也存在 已更改
/ @$ c! G7 L) w" B- PCD_WriteEmptyTxFifo 函数! D8 _( g' K- Z$ U
) Z1 z1 q+ B6 n( t8 S- static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
! W* h- |/ ]% D - {
! }6 n$ z& I* c& |, c# T: ^6 K- L - USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; ! r! E5 F2 _/ h1 g: U) V u2 u+ v
- USB_OTG_EPTypeDef *ep = NULL;- V' b h- V1 j0 B
- int32_t len = 0U;* [$ i4 K! l+ N4 M( r, s* ~) O
- uint32_t len32b = 0U;- X) l6 ?& J. O
- uint32_t fifoemptymsk = 0U;
4 O1 b+ l6 J( t) Q" T& W
& D6 r- V. @* ]" k% g- ep = &hpcd->IN_ep[epnum];
; T, G3 }7 J2 x7 c* Q9 m* _ - len = ep->xfer_len - ep->xfer_count;
" c. L0 W1 |9 U- o9 ]& @0 |8 _
, g' F( S8 Y3 d) T7 o+ W3 o- if (len > ep->maxpacket)' m7 A: `+ k! {. a8 t* a: y) d4 A
- {
4 [8 k( t4 m* A" f - len = ep->maxpacket;
2 t0 ?1 I9 N W) X - }! D3 ?. i) l/ }6 h3 t) {
- 1 L4 i9 s+ ?$ o2 O" U7 N& o
3 ?% ~" `/ K4 r5 L+ u5 \2 T- len32b = (len + 3) / 4;
7 l! @8 R3 ^5 q3 r9 c
" ]6 C+ _: V3 d& [) h; k! r' \- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&* @+ X" } y1 i1 I
- ep->xfer_count < ep->xfer_len &&" `& B2 N# @* W$ |0 B4 g) {% M5 D
- ep->xfer_len != 0)5 t# J7 \* Q9 j' |8 T, E1 x
- {
6 G1 F9 u2 D* E - /* Write the FIFO */
( T+ ]4 s% O+ `1 f: s - len = ep->xfer_len - ep->xfer_count;
( {" G- @$ o7 `) X u6 `
6 R, J, f* s" ?8 r- if (len > ep->maxpacket)8 L* g$ @- U. M/ V3 y
- {
% a3 Q* x* t: D( @, S' Z' Z- U5 ] - len = ep->maxpacket;. D$ U2 G, [2 |( Y$ |7 l
- }5 `1 F+ }1 b) d0 E3 v2 b' o
- len32b = (len + 3) / 4;
+ n- g! Z9 w' Q4 }7 {: K
' G8 a* N" ?4 m- USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
$ O% b9 }9 B& z2 H2 |/ I' Q - & T8 ^7 d; w E7 `' {
- ep->xfer_buff += len;
5 _' m5 k- Q, N* Z - ep->xfer_count += len;
! L5 l) G0 Y% U& R5 Z7 a - }( i3 p, C. f- ?- L
' g, g/ Z5 h: v. P- if(len <= 0)
$ ~# z5 {) o B# i: [ - {
7 U# ]% t6 i. g4 P0 F* S: A - fifoemptymsk = 0x1 << epnum;1 S5 A2 V; o- p8 r2 @
- USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
2 ~5 n" K \" ?. C' ~
0 K+ ]* }/ f" L4 E% C- }/ A: Q8 w/ i. h& [
- 9 \3 C- b+ ?! P' D. F
- return HAL_OK;
; @ n* p! y. f9 K e5 d& [, @/ I - }
复制代码
, V2 G% }% J" b0 |1 n3 m需要更改为6 m) t6 Z1 W5 g4 k f% l- j
- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b &&* a/ t( b8 u" }# }6 C0 c
- ep->xfer_count < ep->xfer_len &&1 a: J0 w2 d6 h) w) Y( j# R
- ep->xfer_len != 0)
复制代码 不然会一直进中断但又出不来: m1 [0 Z# `$ J d* i0 E
: R( Q* t) i: j8 m. U- j总结: 能用最新的HAL库就用最新的吧 可以避免很多坑
7 f1 `/ l0 d3 @$ x9 u实在不行可以结合寄存器版本的函数来写,直接写寄存器还是比较靠谱,但是要参照HAL的流程& B1 a% ^" j3 Q) d. a+ A% P4 k+ V
$ q2 A+ M4 S7 j/ K
3 {0 X; l5 a5 e; h( @8 ^$ X
" D' S+ k5 l1 E0 }' d
* f0 @! o' k2 [ |