【国民技术车规MCU N32A455开发板】 N32A455的 IAP
[复制链接]
官网有有个IAP例程,但不是N32A455的,要根据例程改一下
#include "main.h"
#include "n32a455_rcc.h"
#include <stdio.h>
#include <stdint.h>
#include "string.h"
#include "bsp_usart.h"
#include "iap.h"
//f_IAP_start 启动IAP升级标置
//slot_timer 定时器定时标置 定事情中断中累计 串口接收到数据则清零
//receive_cnt 用于计算串口接收到数据数据
//receive_app_done 更新完所有闪存的标志
//RX_buf 串口接收到的数据的缓存数组
//TIM3 用做定时100微秒 中断中进入更新后检查f_IAP_start 如果启动IAP升级 则检查200毫秒内串口是否收到数据,没有收到则清空RX_buf
#define app_update_flag_addr 0x08005800 //该地址必须超出APP的内容范围。demo的bin内容结束于0x080054F8
#define TRIGGER_IAP_PIN GPIO_PIN_12
#define TRIGGER_IAP_PORT GPIOD
uint32_t receive_cnt = 0;
uint8_t receive_app_done = 0;
uint8_t f_IAP_flashing = 0;
uint8_t f_IAP_start = 0;
uint16_t slot_timer = 0;
uint8_t f_receive_frame = 0;
uint8_t f_final_frame = 0;
/**============================================== =================
Delay function
================================================== ==============*/
void m_delay_ms(uint32_t ms)
{
uint32_t us = 0;
for(; ms!=0; ms--)
{
us = 1440;
while(us--);
}
}
/**============================================== =================
Read Flash
================================================== ==============*/
uint32_t FLASH_ReadWord(uint32_t address)
{
return *(__IO uint32_t*)address;
}
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Timer3 initialization configuration.
*/
void tim3_init(uint16_t Period, uint16_t Prescaler)
{
TIM_TimeBaseInitType timInitStruct;
NVIC_InitType NVIC_InitStructure;
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE);
timInitStruct.Period = Period;
timInitStruct.Prescaler = Prescaler;
timInitStruct.ClkDiv = 0;
timInitStruct.CntMode = TIM_CNT_MODE_UP;
TIM_InitTimeBase(TIM3, &timInitStruct);
TIM_ConfigInt(TIM3, TIM_INT_UPDATE, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Enable(TIM3, ENABLE);
}
/**
* @brief TIM3 interrupt process function each 100us.Get the TIM2->CNT value, and Calculate the number of pulses by
the difference of two times. Then take the delta pules into the buffer of last channel and toggle to new channel.
*/
void TIM3_IRQHandler(void)
{
if (TIM_GetIntStatus(TIM3, TIM_INT_UPDATE) != RESET)
{
TIM_ClrIntPendingBit(TIM3, TIM_INT_UPDATE);
//
if(f_IAP_start==1) //Start IAP update
{
slot_timer++;
if(slot_timer>=2000) //200ms no data is issued, clear RX_buf data
{
memset(RX_buf,0,256);
slot_timer = 0;
receive_cnt = 0;
}
}
else
{
slot_timer = 0;
}
}
}
void Trigger_IAP_GPIO_init(void)
{
GPIO_InitType GPIO_InitStructure;
/* Check the parameters */
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE);
GPIO_InitStructure.Pin = GPIO_PIN_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOD, &GPIO_InitStructure);
}
int main(void)
{
Trigger_IAP_GPIO_init();
tim3_init(99, 71); //72MH/(71+1)=1M Hz; 1M Hz/(99+1)=100us
USART_Config();
printf("NZ3601_init success! \r\n");
while(1)
{
if (GPIO_ReadInputDataBit(GPIOD, GPIO_PIN_12) == Bit_RESET)
{
printf("Enter the upgrade! \r\n");
while(receive_app_done == 0) //No APP program, waiting to receive updates
{
if(f_IAP_flashing == 1)
{
TIM_Enable(TIM3, DISABLE);
USART_Enable(DEBUG_USARTx, DISABLE);
//
IAP_UPDATE_APP(); //Update the received pack package
f_IAP_flashing = 0;
f_receive_frame = 0; //Clear the receive frame flag
if(f_final_frame == 1)
{
f_final_frame = 0;
receive_app_done = 1; //Update is complete
app_flag_write(0x12345678 ,app_update_flag_addr);//Write IAP upgrade flag
}
TIM_Enable(TIM3, ENABLE);
USART_Enable(DEBUG_USARTx, ENABLE);
}
}
}
printf("iap_load_app! \r\n");
if(FLASH_ReadWord(app_update_flag_addr) == 0x12345678) //Whether the power-on detection needs to jump directly
{
receive_app_done = 1;
}
if(receive_app_done) //App has been updated
{
receive_app_done = 0;
TIM_Enable(TIM3, DISABLE); //Turn off timer interrupt
//
printf("APP address:%x\r\n",(FLASH_START_ADDR));
printf("Start to execute Flash user code!!\r\n");
SCB->VTOR = FLASH_BASE | 0x4000; //Set up interrupt vector table before jump
iap_load_app(FLASH_START_ADDR); //Jump to the start address of the APP, during which it cannot be interrupted by other interrupts, otherwise the jump will fail
}
else{
while(1)printf("receive_app_done OFF\r\n");
}
}
}
有需要可以测测
|