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

【经验分享】关于 AN4065 中 STM32F0 IAP 升级后的外部中断不响应问题

[复制链接]
STMCU小助手 发布时间:2022-2-27 16:46
前言
1 {+ p5 c" {9 c9 w客户在使用 STM32F051C8T6 的 IAP 功能时,发现有些端口(比如 PB 端口)的外部中断端口没有反应,但是有些还是可以的(比如 PA 端口),不知是何原因,客户也验证过应用代码在没有使用 IAP 功能时是没有问题的。客户是参考了我们的应用笔记 AN4065 来编写这部分代码.
2 k8 j+ n7 o+ r3 H4 B4 w* A) b) `
问题分析
0 _$ n+ f6 k8 M. `6 G5 f! u; i5 W应用代码4 G2 T. z$ {) k1 N7 k
通过查找客户的应用代码,发现如下 API 函数的调用:9 Q/ _8 T* i9 a7 W! N
  1. /* Enable the SYSCFG peripheral clock*/
      z6 _; u6 Q: J3 T1 U2 G$ K# A
  2. RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    ) q" Y, M3 K* x
  3. /* Remap SRAM at 0x00000000 */8 e5 N9 G) A! c7 ?5 t
  4. SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
复制代码
# G9 K1 {6 w, J- {; M; X
红色标记的 API 函数此处是有问题的,在此处应该将 RCC_APB2PeriphResetCmd 函数替换为RCC_APB2PeriphClockCmd 函数。这个在 AN4065 的附件工程中也是这么写的,所以应该是代码的问题。修改后的代码如下,修改之后,程序正常运行了.
* J, B% ]1 z7 P1 C
  1. /* Enable the SYSCFG peripheral clock*/4 Z3 B3 A. _3 O) k4 n/ n( H0 D3 `
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);3 T- o  X) l' y; ]
  3. /* Remap SRAM at 0x00000000 */
    ; T: G5 }; z) A
  4. SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
复制代码
6 D% S0 U! L4 H" D
深入研究* v7 V5 _; Y9 `$ J6 @* Q
这个问题其实是这样的:因为 SYSCFG 寄存器的时钟被关闭了,所以才造成一些外部中断没有响应。
8 ]8 }3 V- S3 |首先:我们看看 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);这个函数做了哪些操作,它是应该是如何工作的?$ A3 a9 e# Y) [( x* }+ R3 }+ B/ j
在 APB2PeriphResetCmd()函数中得知这个函数是设置 RCC->APB2RSTR 的对应位,如果设置了这个寄存器的对应位,那么对应的外设(或者是寄存器)的时钟就被关闭了,那么这个函数本来应该如何工作的呢?通过查看我们的库文件,这个函数只有在 PPPP_DeInit()中才会使用,而且是一对儿一对儿的出现:. i5 Q) B8 B$ j; @: s) O
  1. /* Enable SPI1 reset state */9 N! R4 a" v  J4 I
  2. RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);, M: B' W* e% `9 N* N+ o
  3. /* Release SPI1 from reset state */
    $ N0 }( I+ D" o* Y. R/ ?4 N& t
  4. RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
复制代码
  1. RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE);
    9 k  d+ S- Z+ D9 M4 d# `# k2 }
  2. RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE);: S  g4 g& N6 [! V! ~
  3. if (USARTx == USART1)
    # ~4 {2 s, l- r1 p3 A/ u
  4. {8 O9 h; J* z; s0 s2 G/ ]1 {3 O
  5. RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);( {9 `) s8 Y* t. F9 P+ x  V1 G
  6. RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);; _. G* v3 V  w. e" T) H
  7. }
复制代码

% O6 d( f$ g' j$ T( L还有很多的例子,就不一一列出了。总之是为了简单的把一个外设或者是寄存器的值恢复到出厂设置,就可以通过调用两次这个函数来做到(比一个一个位清除要来的快),但是如果单独的只是调用了一次,比如客户代码中的情况,那么就是时钟被关闭了(这个可以简单的通过一个 GPIO 来测试,我已经测试过了,只要单独的设置上这个位,那么这个外设就肯定不工作了,无论你是不是开启这个外设的时钟在 RCC_ AHBENR 中),所以这个寄存器该起到的效果都没有了。关于RCC_APB2PeriphClockCmd()这个函数就很简单了,只是打开对应外设的时钟而已,就不说了.* j- k7 E1 t. a+ ]

2 z' l6 D4 |$ T- _8 N( f其次,我们再来看看这个 SYSCFG 寄存器,为啥没有时钟了,它看起来好像也在工作呢?
3 N# u+ g% _# M+ m% G! x8 }2 S/ F: e0 {) W% S* c
_7BO{AZ}SRB4LA9}]W_M0JO.png
% _$ s0 t/ i$ H( f; F/ @7 @, a% e, z- S: X1 L1 i1 ]# y3 s
看看画红线的地方就行了,他是用来重映射内存地址和管理外部中断连接到 GPIO 的。在默认的时候,这个寄存器的时钟是关闭的,所以默认都是从 Flash 的起始地址开始运行,外部中断也都连接到 GPIOA 上,只有需要修改的时候我们才会去开启这个寄存器的时钟,并做对应的修改。 这也就是解释了,为什么客户有的 GPIO 是好使的(GPIOA 是 OK 的),有些 GPIO是不好使的(GPIOB 上的就不好使).. Z4 ^1 O3 x* H- [# k4 Z

$ ]6 W; [+ L# c. l1 u8 Y; r* o( }6 a
总结:( Z+ @& E! |* d) @' e) R
根本原因是应用代码中 API 调用错误,一般客户在自己建立工程的时候,又不是很了解如何在开始的时候去设置这个地方造成的。需要以后的工程师在参考 AN4065 中注意一下这个地方.
/ f8 [5 L1 Q9 H8 P3 ], t
( u& A$ `$ {4 o. S' x7 K" x: P4 Y& g9 B$ l4 Y8 P2 x0 s
收藏 评论0 发布时间:2022-2-27 16:46

举报

0个回答

所属标签

相似分享

官网相关资源

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