本帖最后由 香水城 于 2017-8-16 14:50 编辑
关于 AN4065中 STM32F0 IAP升级后的外部中断不响应问题
前言
客户在使用STM32F051C8T6的IAP功能时,发现有些端口(比如PB端口)的外部中断端口没有反应,但是有些还是可以的(比如PA端口),不知是何原因,客户也验证过应用代码在没有使用IAP功能时是没有问题的。客户是参考了我们的应用笔记AN4065来编写这部分代码.
问题分析
应用代码
通过查找客户的应用代码,发现如下API函数的调用:
红色标记的API函数此处是有问题的,在此处应该将RCC_APB2PeriphResetCmd函数替换为RCC_APB2PeriphClockCmd函数。这个在AN4065的附件工程中也是这么写的,所以应该是代码的问题。修改后的代码如下,修改之后,程序正常运行了.
深入研究
这个问题其实是这样的:因为SYSCFG寄存器的时钟被关闭了,所以才造成一些外部中断没有响应。
首先:我们看看RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);这个函数做了哪些操作,它是应该是如何工作的?
在APB2PeriphResetCmd()函数中得知这个函数是设置RCC->APB2RSTR的对应位,如果设置了这个寄存器的对应位,那么对应的外设(或者是寄存器)的时钟就被关闭了,那么这个函数本来应该如何工作的呢?通过查看我们的库文件,这个函数只有在PPPP_DeInit()中才会使用,而且是一对儿一对儿的出现:
还有很多的例子,就不一一列出了。总之是为了简单的把一个外设或者是寄存器的值恢复到出厂设置,就可以通过调用两次这个函数来做到(比一个一个位清除要来的快),但是如果单独的只是调用了一次,比如客户代码中的情况,那么就是时钟被关闭了(这个可以简单的通过一个GPIO来测试,我已经测试过了,只要单独的设置上这个位,那么这个外设就肯定不工作了,无论你是不是开启这个外设的时钟在RCC_ AHBENR中),所以这个寄存器该起到的效果都没有了。关于RCC_APB2PeriphClockCmd()这个函数就很简单了,只是打开对应外设的时钟而已,就不说了.
其次,我们再来看看这个SYSCFG寄存器,为啥没有时钟了,它看起来好像也在工作呢?
看看画红线的地方就行了,他是用来重映射内存地址和管理外部中断连接到GPIO的。在默认的时候,这个寄存器的时钟是关闭的,所以默认都是从Flash的起始地址开始运行,外部中断也都连接到GPIOA上,只有需要修改的时候我们才会去开启这个寄存器的时钟,并做对应的修改。 这也就是解释了,为什么客户有的GPIO是好使的(GPIOA是OK的),有些GPIO是不好使的(GPIOB 上的就不好使).
总结:
根本原因是应用代码中API调用错误,一般客户在自己建立工程的时候,又不是很了解如何在开始的时候去设置这个地方造成的。需要以后的工程师在参考AN4065中注意一下这个地方.
对应PDF:关于AN4065中STM32F0 IAP升级后的外部中断不响应问题
更多实战经验请看:【ST MCU实战经验汇总贴】
|