1、首先要知道103C8T6是 64K flash的
2、要知道每页是1K, 0x400表示1K, 0x1000表示4K, 0x4000表示16K,0x10000表示64K
3、下载官方AN4657-STM32Cube_IAP_using_UART程序,STM3210C_EVAL工程
4、修改flash_if.h文件
#define USER_FLASH_END_ADDRESS 0x08010000 //定义总flash为0x1000
/* Define the user application size */
#define USER_FLASH_SIZE ((uint32_t)0x0000C000) /* 用户程序为乘下的48K */
// 修改写程序的页,16–63K为用户程序,需要写保护
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES16TO19| OB_WRP_PAGES20TO23 | OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31 | \
OB_WRP_PAGES32TO35 | OB_WRP_PAGES36TO39 | OB_WRP_PAGES40TO43 | OB_WRP_PAGES44TO47 | \
OB_WRP_PAGES48TO51 | OB_WRP_PAGES52TO55 | OB_WRP_PAGES56TO59 | OB_WRP_PAGES60TO63 )
5、用STM32CubeMX生成一个带1个按键,和串口的 基本程序,把串口变量huart1改为UartHandle,方便其它地方不用修改。并在main.h中声明为外部变量。
6、加入.s文件,编译OK
7、复制官网下载的这4个文件和对应的.h文件到自己的工程中
8、在main.c中加入#include “menu.h”,把程序改成如下
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
// printf("systems is start.....");
if(HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin)==GPIO_PIN_RESET)
{
FLASH_If_Init();
Main_Menu ();
}
else
{
//printf("start to running APP");
/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
JumpToApplication();
}
}
while (1);
}
9、把4个.c文件加入工程,并在main.c开头声明以下外部变量
extern pFunction JumpToApplication;
extern uint32_t JumpAddress;
10、删除以下头文件
//#include “stm3210c_eval.h”
11、在使用到串口的.c文件中都加入extern UART_HandleTypeDef UartHandle;
12、编译OK,下载,电脑上打开SecureCRT 8.1,按住按键,可以出来菜单了
13、按 键盘 1 ,
选择send ymodem 发送APP的bin文件
第二步:
写APP程序
1、改变flash地址,这个要根据上面IAP设定的来改
2、生成bin文件
C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe --bin --output "E:\proj\APP_LED_test\MDK-ARM\APP_LED_test\APP_LED.bin" "E:\proj\APP_LED_test\MDK-ARM\APP_LED_test\APP_LED_test.axf"
或者更简单
C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe --bin --output "[email protected]" "#L"
3、APP的程序里要重新定位向量表。查了网上都是调用NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);
这个函数,但调用这个函数又要#include “misc.h",include “misc.h"这个后又会出现找不到stm32f10x.h
找了好久,用HAL库的,直接调用下面的操作寄存器
int main(void)
{
HAL_Init();
SCB->VTOR=FLASH_BASE|0x4000;
........
其它:
1、IAP里有一个判断语句
if ((((__IO uint32_t)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)//判断栈定地址值是否在0x2000 0000 - 0x 2002 0000之间,0x2000 0000地址之后的一段是SRAM,20000表示128K,如果下载了APP程序,APP的堆栈地址肯定在这128K的SRAM内。如果不在,说明没有下载APP程序。严格地说103C8T6只有20K SRAM,所以
if ((((__IO uint32_t)APPLICATION_ADDRESS) & 0x2FFFA000 ) == 0x20000000) 更严格。