从用户代码跳转到启动程序代码区去执行Bootloader之前必须执行以下操作:1) 关闭所有外设时钟2) 关闭PLL的使用3) 禁用所有的中断4) 清除所有挂起的中断标志位
实现方式我们先设计一个用户程序APPJumpToBootloader,程序主要完成一个LED的闪烁操作,另外在检测一个用户按键,当按键按下之后就直接跳转到系统Bootloader(跳转之前需清除中断等信息)。软件流程图如下图所示:

int main(void)
{
uint32_t LedTimer = 0, LedTog = 0;
system_clock_config();
at32_board_init();
LedTog = system_core_clock / 80;
while (1)
{
if (USER_BUTTON == at32_button_press())
{
/*清除 Clock, PLL, Interrupt*/
app_clear_sys_status();
app_jump_to_bootloader();
}
if (LedTimer == LedTog)
{
at32_led_toggle(LED4);
LedTimer = 0;
}
LedTimer++;
}
}
void app_clear_sys_status()
{
/*Close Peripherals Clock*/
CRM->apb2rst = 0xFFFF;
CRM->apb2rst = 0;
CRM->apb1rst = 0xFFFF;
CRM->apb1rst = 0;
CRM->apb1en = 0;
CRM->apb2en = 0;
/*Close PLL*/
/* Reset SW, AHBDIV, APB1DIV, APB2DIV, ADCDIV and CLKOUT_SEL bits */
CRM->cfg_bit.sclksel = 0;
CRM->cfg_bit.ahbdiv = 0;
CRM->cfg_bit.apb1div = 0;
CRM->cfg_bit.apb2div = 0;
CRM->cfg_bit.adcdiv_l = 0;
CRM->cfg_bit.adcdiv_h = 0;
CRM->cfg_bit.clkout_sel = 0;
CRM->ctrl_bit.hexten = 0;
CRM->ctrl_bit.cfden = 0;
CRM->ctrl_bit.pllen = 0;
CRM->cfg_bit.pllrcs = 0;
CRM->cfg_bit.pllhextdiv = 0;
CRM->cfg_bit.pllmult_l = 0;
CRM->cfg_bit.pllmult_h = 0;
CRM->cfg_bit.usbdiv_l = 0;
CRM->cfg_bit.usbdiv_h = 0;
CRM->cfg_bit.pllrange = 0;
/* Disable all interrupts and clear pending bits */
CRM->clkint_bit.lickstblfc = 0;
CRM->clkint_bit.lextstblfc = 0;
CRM->clkint_bit.hickstblfc = 0;
CRM->clkint_bit.hextstblfc = 0;
CRM->clkint_bit.pllstblfc = 0;
CRM->clkint_bit.cfdfc = 0;
/*Colse Systick*/
SysTick->CTRL = 0;
/*Disable ALL interrupt && Pending Interrupt Flag*/
/*这里需要根据用户开启的外设进行清除中断和挂起的中断标志*/
/*
user add code...
*/
}
我要赚赏金
