關(guān)于STM32軟件復(fù)位代碼編寫(xiě)
對(duì)于STM32來(lái)說(shuō)軟件復(fù)位有兩種方式:
1)采用官方自帶的軟件庫(kù)
在官方軟件庫(kù)的stm32f10x_nvic.c 文件里 直接提供了 系統(tǒng)復(fù)位的函數(shù)
/*******************************************************************************
* Function Name : NVIC_GenerateSystemReset
* Description : Generates a system reset.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_GenerateSystemReset(void)
{
SCB->AIRCR = AIRCR_VECTKEY_MASK | (u32)0x04;
}
但是不是直接調(diào)用這個(gè)函數(shù)就OK了?
在Cortex-M3權(quán)威指南中有這么一句話(huà)
這里有一個(gè)要注意的問(wèn)題:從SYSRESETREQ 被置為有效,到復(fù)位發(fā)生器執(zhí)行復(fù)位命令,
往往會(huì)有一個(gè)延時(shí)。在此延時(shí)期間,處理器仍然可以響應(yīng)中斷請(qǐng)求。但我們的本意往往是要
讓此次執(zhí)行到此為止,不要再做任何其它事情了。所以,最好在發(fā)出復(fù)位請(qǐng)求前,先把
FAULTMASK 置位。
所以最好在將FAULTMASK 置位才萬(wàn)無(wú)一失。
同樣官方stm32f10x_nvic.c 文件里也直接提供了該函數(shù)
/*******************************************************************************
* Function Name : NVIC_SETFAULTMASK
* Description : Enables the FAULTMASK priority: Raises the execution priority to -1.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_SETFAULTMASK(void)
{
__SETFAULTMASK();
}
所以要系統(tǒng)復(fù)位 只要 調(diào)用這兩個(gè)函數(shù)就OK了
NVIC_SETFAULTMASK();
GenerateSystemReset();
2)自己編寫(xiě)相應(yīng)匯編代碼
其實(shí)道理是一樣的,我當(dāng)初是沒(méi)有看到官方的函數(shù)所以自己編的,實(shí)際你看官方函數(shù)里面其實(shí)就是調(diào)用的cortexm3_macro.s同樣的代碼 呵呵。
我的代碼:
/*******************************************************************************
* Function Name : SystemReset
* Description : Configures the port pin connected to the push button. GPIO_D_4
* Input : None
* Output : None
* Return : None
*******************************************************************************/
__asm void SystemReset(void)
{
MOV R0, #1 //;
MSR FAULTMASK, R0 //;清除FAULTMASK禁止一切中斷產(chǎn)生
LDR R0, =0xE000ED0C //;
LDR R1, =0x05FA0004 //;
STR R1, [R0] //; 系統(tǒng)軟件復(fù)位
deadloop
B deadloop //; 死循環(huán)使程序運(yùn)行不到下面的代碼
}
然后用的時(shí)候在C程序里直接調(diào)用該函數(shù)就行了。
SystemReset();
在MDK環(huán)境下,包含匯編的代碼嵌入到C代碼中時(shí),編寫(xiě)、調(diào)用與C函數(shù)一樣
在misc.c中定義了上面的函數(shù);
在misc.h中聲明了函數(shù):void SystemReset(void);
在main.c中調(diào)用函數(shù):SystemReset();
補(bǔ)充:
MDK和IAR通用的軟件復(fù)位代碼:
#ifdefined(__CC_ARM)/*------------------RealViewCompiler-----------------*/
__asmvoidGenerateSystemReset(void)
{
MOVR0,#1//;
MSRFAULTMASK,R0//;FAULTMASK禁止一切中斷產(chǎn)生
LDRR0,=0xE000ED0C//;
LDRR1,=0x05FA0004//;
STRR1,[R0]//;
deadloop
Bdeadloop//;
}
#elif(defined(__ICCARM__))/*------------------ICCCompiler-------------------*/
//#pragmadiag_suppress=Pe940
voidGenerateSystemReset(void)
{
__ASM("MOVR0,#1");
__ASM("MSRFAULTMASK,R0");
SCB->AIRCR=0x05FA0004;
for(;;);
}
上面的代碼,程序在FLASH中跑時(shí)可以復(fù)位,在RAM中調(diào)試不成功,原因可能是板子上的boot比較松,導(dǎo)致RAM啟動(dòng)選擇有問(wèn)題
由上面可以看出,IAR下嵌入?yún)R編不是簡(jiǎn)單的asm("...");,如asm("LDRR0,=0xE000ED0C");就會(huì)報(bào)錯(cuò)