CM3(STM32)内核复位与系统复位区别及应用

相关标题:STM32软件复位  、 Cortex - M芯片软件内核复位  、  STM32系统复位


为方便大家阅读,本文内容已经整理成PDF文件:

http://pan.baidu.com/s/1gfHygyn


Ⅰ、写在前面

某些系统允许复位,但对外设又有特殊要求:某一个IO状态不能因为复位而改变,某一个定时器计数器不能改变等。

例子:我一个A系统通过一个IO控制另一个B系统的电源,而这个IO置高时才开启B系统的电源。

正常工作过程中,B系统只有收到A系统关机命令任务才会进行关机(也就是说不能掉电关机),而A系统在工作过程中有复位的需求。

这个时候如果我使用常规的引脚复位,就会使IO置低,不符合要求,就需要使用到本文说到的内核复位

Ⅱ、关于复位

说到复位,我们都不会陌生,学习时,开发板上基本都有一个复位按键

复位的种类有很多:上电复位、掉电复位、复位引脚复位、看门狗复位、软件复位等。

上面说的复位按键,也就是对应复位引脚复位;而本文说的内核复位系统复位是属于软件复位

Ⅲ、内核与系统复位区别

本文说的内核是指处理器内核,拿STM321处理器来说,STM32F1的内核就是Cortex-M3内核,而这里的系统就是包含内核和外设整个一起。

内核复位:它会使Cortex-M3进行复位,而不会影响其外设,如GPIOTIMUSARTSPI等这些寄存器的复位。

系统复位:这个复位会使整个芯片的所有电路都进行复位,我们查看寄存器手册时,会发现某某某寄存器复位值等于多少。

因此,我们常说的复位一般指的就是系统复位。

Ⅳ、内核与系统复位应用及代码分析

本文拿CM3STM32F1)进行举例说明,其他芯片类似。在下一节提供源代码工程供大家参考学习。

本文提供的复位函数分:内核和系统复位C语言和汇编共四个版本(在一个工程),主要讲解其4个函数:

void NVIC_CoreReset(void);

void NVIC_CoreReset_a(void);

void NVIC_SysReset(void);

void NVIC_SysReset_a(void);

本章节内容可以参照Cotrex-M3权威指南中,Cotrex-M3其他特性章节下的自复位控制(软件复位)。中文版位于第13张,英文版位于第14张。

同时结合core_cm3.h源代码,其中系统复位中的C语言版就是core_cm3.h里面的源代码。

1.NVIC_CoreReset内核复位

CM3 允许由软件触发复位序列,用于特殊的调试或维护目的。在CM3中,有两种方法可以执行自我复位。第一种方法,是通过置位 NVIC 中应用程序中断与复位控制寄存器(AIRCR)VECTRESET 位(位偏移:0)。

这种复位的作用范围覆盖了整个CM3处理器中,除了调试逻辑之外的所有角落,但是它不会影响到 CM3 处理器外部的任何电路,所以单片机上的各片上外设和其它电路都不受影响。

C语言版函数:

void NVIC_CoreReset(void)

{

  __DSB();

  //置位VECTRESET

  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |

                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |

                 SCB_AIRCR_VECTRESET_Msk);

  __DSB();

  while(1);

}

汇编版函数:

__asm void NVIC_CoreReset_a(void)

{

  LDR R0, =0xE000ED0C

  LDR R1, =0x05FA0001  //置位VECTRESET

  STR R1, [R0]

deadloop_Core

  B deadloop_Core

}

内核主要注意:SCB_AIRCR_VECTRESET_MskLDR R1, =0x05FA0001,它是和系统复位唯一的区别。

2.NVIC_SysReset系统复位

系统复位是置位同一个寄存器中的 SYSRESETREQ 位。这种复位则会波及整个芯片上的电路:它会使 CM3 处理器把送往系统复位发生器的请求线置为有效。但是系统复位发生器不是CM3的一部分,而是由芯片厂商实现,因此不同的芯片对此复位的响应也不同。因此,读者需要认真参阅该芯片规格书,明白当发生片内复位时,各外设和功能模块都会回到什么样的初始状态,或者有哪些功能模块不受影响(比如, STM32系列的芯片有后备存储区,该区就被特殊对待)。

大多数情况下,复位发生器在响应 SYSRESETREQ 时,它也会同时把 CM3 处理器的系统复位信号(SYSRESETn)置为有效。通常, SYSRESETREQ 不应复位调试逻辑。

这里有一个要注意的问题:从 SYSRESETREQ 被置为有效,到复位发生器执行复位命令,往往会有一个延时。在此延时期间,处理器仍然可以响应中断请求。但我们的本意往往是要让此次执行到此为止,不要再做任何其它事情了。所以,最好在发出复位请求前,先把FAULTMASK置位。因此,我在提供源代码中有这么一句:__set_FAULTMASK(1);,也就是置位FAULTMASK

C语言版函数:

void NVIC_SysReset(void)

{

  __DSB();

  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |

                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |

                 SCB_AIRCR_SYSRESETREQ_Msk);

  __DSB();

  while(1);

}

汇编版函数:

__asm void NVIC_SysReset_a(void)

{

  LDR R0, =0xE000ED0C

  LDR R1, =0x05FA0004

  STR R1, [R0]

deadloop_Sys

  B deadloop_Sys

}

细心的朋友可能会发现:

1.内核复位与系统源代码和相近,差异在于SYSRESETREQSYSRESETREQ这两位。

2.C语言版本的代码和core_cm3.hNVIC_SystemReset函数相似。对的这个函数就是系统复位函数,而我们的内核复位只是简单修改了一下。

3.main函数应用

Main函数中主要以LED1LED2两个IO来说明。

LED1作为"标志灯": 上电"标志"置为高;

LED2作为指示灯:看从内核启动改变状态没有。

请在main函数中应用不同的配置进行测试:

#if 0 /* 内核复位 */

    NVIC_CoreReset();

//  NVIC_CoreReset_a();

#else /* 系统复位 */

    NVIC_SysReset();

//  NVIC_SysReset_a();

#endif

Ⅴ、代码下载

Cotrex-M3权威指南:

http://pan.baidu.com/s/1mhQYa1q

本文源代码工程(STM32F103ZEKeil_Reset):

http://pan.baidu.com/s/1hskScba

提示:如果网盘链接失效,可以微信公众号“底部菜单”查看更新链接。

Ⅵ、最后

微信搜索EmbeddDeveloper” 或者扫描下面二维码、关注,查看更多精彩内容!

 

猜你喜欢

转载自blog.csdn.net/ybhuangfugui/article/details/73354918