關(guān)于STM32軟件復(fù)位代碼編寫
對于STM32來說軟件復(fù)位有兩種方式:
1)采用官方自帶的軟件庫
在官方軟件庫的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)用這個函數(shù)就OK了?
在Cortex-M3權(quán)威指南中有這么一句話
這里有一個要注意的問題:從SYSRESETREQ 被置為有效,到復(fù)位發(fā)生器執(zhí)行復(fù)位命令,
往往會有一個延時(shí)。在此延時(shí)期間,處理器仍然可以響應(yīng)中斷請求。但我們的本意往往是要
讓此次執(zhí)行到此為止,不要再做任何其它事情了。所以,最好在發(fā)出復(fù)位請求前,先把
FAULTMASK 置位。
所以最好在將FAULTMASK 置位才萬無一失。
同樣官方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)用這兩個函數(shù)就OK了
NVIC_SETFAULTMASK();
GenerateSystemReset();
2)自己編寫相應(yīng)匯編代碼
其實(shí)道理是一樣的,我當(dāng)初是沒有看到官方的函數(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í),編寫、調(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啟動選擇有問題
由上面可以看出,IAR下嵌入?yún)R編不是簡單的asm("...");,如asm("LDRR0,=0xE000ED0C");就會報(bào)錯