stm32H7 hal库错误内容汇总:+ H) f9 f9 ~, C# p
1. I2S
8 ^. {3 g$ v4 s3 O- HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size); A* |4 E" `/ C1 m" L8 N3 }4 s
- 函数内部有一个判断( J* E. J! h" t, z* k+ R
- if (hi2s->State == HAL_I2S_STATE_READY) {
% N" w6 c1 c# w" k* u. i - __HAL_UNLOCK(hi2s);
2 Z8 r& _( q' r5 ] - return HAL_BUSY;
1 A, v) R- S/ h( j; O1 p/ m, I - }1 l; n8 s& Y$ D$ l. T
- 函数
& o$ h5 O) @3 W0 }0 ? - HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
! _" l" g: d# G& K$ X - {
, k+ s; u/ u: {8 f% E4 |" i - if (hi2s->State == HAL_I2S_STATE_READY)7 J; P" ^ H6 d; ]
- {: q3 c6 q6 P, Z' Y( g6 z; ^0 h$ K
- __HAL_UNLOCK(hi2s);
9 }6 v/ [1 c' \1 z - return HAL_BUSY;1 l. g$ S5 X0 L" h+ l
- }7 C$ d& s( C5 G5 b n! y
- 中同样有
复制代码 应该改为:; V9 b. b% |( \4 B/ K' S/ G
- if (hi2s->State != HAL_I2S_STATE_READY)
复制代码
6 n- ~. n) r- D3 b2 f$ z+ L) L2.寄存器定义
- T$ E1 E7 S' ^" Y# D$ m H5 |我用的HAL库版本为V1.2.0;
; H+ T7 C/ ]' c& f- ~其中Device中的STM32H743XX.h中寄存器定义错误。
/ y, m2 F; S T& d- #define SPI_I2SCFGR_WSINV_Pos (12U) q8 A5 V" e( S; D& S
- #define SPI_I2SCFGR_WSINV_Msk (0x1U << SPI_I2SCFGR_WSINV_Pos) /*!< 0x00001000 */+ B3 y2 z Q0 `1 T, b
- #define SPI_I2SCFGR_WSINV SPI_I2SCFGR_WSINV_Msk /*!<Word select inversion */% b5 k, l- t% V7 ~* z6 ^9 K
- #define SPI_I2SCFGR_FIXCH_Pos (13U) h3 D. K8 @! h" w- }% m( w
- #define SPI_I2SCFGR_FIXCH_Msk (0x1U << SPI_I2SCFGR_FIXCH_Pos) /*!< 0x00002000 */' z5 o/ ~7 x# n
- #define SPI_I2SCFGR_FIXCH SPI_I2SCFGR_FIXCH_Msk /*!<Fixed channel length in SLAVE */
$ x s) O0 b/ D( A0 [, X4 l; } - #define SPI_I2SCFGR_DATFMT_Pos (12U)
* C; S: I& ^! Y/ p - #define SPI_I2SCFGR_DATFMT_Msk (0x3U << SPI_I2SCFGR_DATFMT_Pos) /*!< 0x00003000 */
5 ^: l6 u4 _' `, k- s6 [ - #define SPI_I2SCFGR_DATFMT SPI_I2SCFGR_DATFMT_Msk /*!<Data format
复制代码 ! U7 ]& k3 j$ M, N. F/ e9 s1 m
+ {/ ?. S* A5 Z6 f7 ~) i" F6 a; x, V0 H' f- K# I3 S
# r( U# i7 w( o) v. A6 u7 O跟寄存器定义不同。
8 ]" t$ @) g$ ?0 T) ~7 U1 c! S* c+ ?% ]0 |) [. }3 I6 ^6 t
所以最好使用新的固件库,但项目之前用的旧固件库,并且没有用到I2s。- E, D- g% f+ ~; [: q" g$ L
8 G1 ?# |5 I9 I$ o$ M
还是关于I2S的坑,这次使用的HAL库版本是在官网下载的最新版本
) @% ?8 F, V* ^ q. l+ c0 ]FW_H7_V1.5.0.在使用全双工I2S时,需要包含) ?; l! J' L, h( P2 y
stm32h7xx_hal_i2s_ex.h 头文件
8 I- }8 T2 J# _/ ]1 y但是
, M4 h3 y: \! L4 W A: H0 F1 o, U8 ^. h
I* q2 B3 }* I7 A2 R' x# z图中宏定义根本找不到 ,自己添加宏定义后一堆错误 我也是服了。8 f' K- z8 ~+ e1 i; T
有了SAI就对I2S这么不上心吗?1 U8 L# F9 v/ \- x. j: X
3.USB device卡死在HAL_PCD_IRQHandler中导致主程序无法运行
. D; G) r3 e F4 e3 J; s. d但并未出现错误
# N! U0 q/ E* u, U/ G( R调试发现4 t) L7 G! c0 u- m2 ]9 N
程序一直进USB_OTG_DIEPINT_TXFE 即TX FIFO 为空中断! ?' n1 h' }" x% g8 O
既然如TX FIFO 后 正常逻辑需要往TX FIFO 中填充数据 测试发现并没有,4 M2 T- ]& x; }8 o0 l+ e9 b* H
发现 (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) 刚好等于len32b导致条件不满足2 `) G% U5 c2 p) u. Y
又一直进FIFO为空中断 一直在中断中运行 形成死机现象) i1 @: }: w, Q% p
对比 HAL库1.5.0发现此处已更改为>=( J! Q! t9 o" h( \3 B) {0 I9 Q. h
更改后不会死机 但是 USB连接不上时仍需重启9 L* N, k1 t4 k& R1 D$ F# }
库文件原代码 此BUG在F4驱动库中也存在 已更改
; |& E$ X% a' x( C4 R% D- PCD_WriteEmptyTxFifo 函数
j; x0 g. _0 d R6 |
4 t% ]' w' l4 P* c h: m- static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)% {! Y; p( x- B; _. ^2 w8 |3 B
- {
/ c. f% }9 N2 ~1 Q- c, G2 B" F1 D8 F - USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + y& M# P9 e; ?* d2 ~7 F
- USB_OTG_EPTypeDef *ep = NULL;
; n3 W* D6 q# ] - int32_t len = 0U;
1 |. n1 Q" d; t" F! @ - uint32_t len32b = 0U;! @% F4 K3 l6 P9 k8 H0 j
- uint32_t fifoemptymsk = 0U; f/ \' S8 D1 u8 j! T0 A
- , j: C2 C4 {! F/ b
- ep = &hpcd->IN_ep[epnum];$ } j/ G/ g- h+ e. Z- r1 |5 q
- len = ep->xfer_len - ep->xfer_count;/ \( J! ?# l. G# p: o" P
- " N/ h" T1 M" h2 [: C6 M1 b
- if (len > ep->maxpacket)
9 A6 z1 x% k; A% W0 J! z - {$ _+ M) ?; V6 }. |1 `3 X3 s1 Q. K' n
- len = ep->maxpacket;( V( R- M8 P8 h- U( s+ U
- }8 }& d/ N: K: I& D: z+ M0 i
6 o9 O, q9 u+ h: `. k6 ?- 6 R& P" j9 j1 p4 c i
- len32b = (len + 3) / 4;( R% e, ~4 |1 W+ U
( ]% [7 z, y( ] b; i1 g) [- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&' z" Z2 d# R" ?6 c: z5 t
- ep->xfer_count < ep->xfer_len &&2 ^7 M$ P( R2 V' J
- ep->xfer_len != 0)0 p) T/ V! K% S' \9 C: N
- {: `" u, C( Z, d/ X& Y
- /* Write the FIFO */+ [$ \& o6 [) i# u) [
- len = ep->xfer_len - ep->xfer_count;
+ O; X7 T# s6 C( a6 L' z
4 j7 t1 g! U' M( Z4 B- if (len > ep->maxpacket)
* A0 `! M! _! g$ y9 b - {
7 Y3 e2 X& K3 N6 n4 F2 D9 @( \4 k - len = ep->maxpacket;
7 m! V3 @ q" I! M* ^. p3 o - }
- T Q$ z+ F e. P - len32b = (len + 3) / 4;9 \. l; ~" n% @4 y H5 m
( p) g2 {, T; w& n- USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); & ]6 X% N9 h# z! E- b
- 9 P9 V R# Z9 J) i6 {
- ep->xfer_buff += len;
5 I" B J& q% o/ Q2 \ - ep->xfer_count += len;& k# l9 n" s5 A I0 X. p
- }
) y% c2 \9 @, B& { - $ w& g. t8 f) X7 h
- if(len <= 0)
, c, p2 l8 ^$ a8 v: _4 b - { ?, ?( I# m( p' ] g
- fifoemptymsk = 0x1 << epnum;
4 p7 U* g, J, i' f" [ - USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;8 h: F8 s. }( i
# G2 M2 J5 S$ T8 f1 ]1 M+ f- }
3 M* y7 Q2 x% k0 G1 [
' r8 ^1 T5 |5 y' v& q4 V- Q* q- return HAL_OK;
; W) n4 L8 v0 o- a8 a% g - }
复制代码
% Z. w; | J: D$ X9 S' q需要更改为
/ K r$ e0 a* G$ O% Z' P- while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b &&
5 y5 X& @, [ d! @& J( e) O - ep->xfer_count < ep->xfer_len &&
1 A( S c$ D R6 O - ep->xfer_len != 0)
复制代码 不然会一直进中断但又出不来
* F* E/ v+ Z9 O
% y( a1 n3 `. y5 ^$ t! B/ t总结: 能用最新的HAL库就用最新的吧 可以避免很多坑
% s% g* L, a o实在不行可以结合寄存器版本的函数来写,直接写寄存器还是比较靠谱,但是要参照HAL的流程( x! S$ f+ l k7 u
( T! F& }# x/ c4 o( D; x8 p$ S& q. V! b' j7 v# z
2 M* `1 p) u* S( y# _ f& c
) c- o0 a0 t0 k
|