单片机
返回首页

STM32L152的IAP移植笔记

2016-12-27 来源:eefocus

本文将针对STML152的IAP移植过程作一个笔记。

首先得下载AN3310的示例代码,地址为:http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries-expansions/stsw-stm32075.html

下载完成后,我们需要做些修改,我们将在NUCLEO-L152RE板子上进行验证测试。

由于NUCLEO-L152RE板子默认MCU是没有外挂晶振的,但可以通过ByPass方式使用ST-LInk的8M晶振,但这里只是作为IAP,且只需要使用到串口,因此可以只使用HSI,于是,在AN3310的工程中打开system_stm32l1xx.c文件找到SystemInit函数,注释掉//SetSysClock();,让系统使用默认的HSI即可。


  1. void SystemInit (void)  

  2. {  

  3.   /*!< Set MSION bit */  

  4.   RCC->CR |= (uint32_t)0x00000100;  

  5.   

  6.   /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */  

  7.   RCC->CFGR &= (uint32_t)0x88FFC00C;  

  8.   

  9.   /*!< Reset HSION, HSEON, CSSON and PLLON bits */  

  10.   RCC->CR &= (uint32_t)0xEEFEFFFE;  

  11.   

  12.   /*!< Reset HSEBYP bit */  

  13.   RCC->CR &= (uint32_t)0xFFFBFFFF;  

  14.   

  15.   /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */  

  16.   RCC->CFGR &= (uint32_t)0xFF02FFFF;  

  17.   

  18.   /*!< Disable all interrupts */  

  19.   RCC->CIR = 0x00000000;  

  20.   

  21. #ifdef DATA_IN_ExtSRAM  

  22.   SystemInit_ExtMemCtl();  

  23. #endif /* DATA_IN_ExtSRAM */  

  24.   

  25.   /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */  

  26.   //SetSysClock();  

  27.   

  28. #ifdef VECT_TAB_SRAM  

  29.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */  

  30. #else  

  31.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */  

  32. #endif  

  33. }  

然后修改man.c文件中的main函数,注释掉一些按键,让程序默认进入到升级模式:


  1. int main(void)  

  2. {  

  3.   /* Unlock the Flash Program Erase controller */  

  4.   FLASH_If_Init();  

  5.   

  6.   /* Initialize Key Button mounted on STM32L15xx-EVAL board */  

  7.   //STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);  

  8.   

  9.   /* Test if Key push-button on STM32L15xx-EVAL Board is pressed */  

  10.   //if (STM_EVAL_PBGetState(BUTTON_KEY) != 0x00)  

  11.   {  

  12.     /* Execute the IAP driver in order to reprogram the Flash */  

  13.     IAP_Init();  

  14.     /* Display main menu */  

  15.     Main_Menu ();  

  16.   }  

  17. #if 0  

  18.   /* Keep the user application running */  

  19.   else  

  20.   {  

  21.     /* Test if user code is programmed starting from address 'APPLICATION_ADDRESS' */  

  22.     if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)  

  23.     {  

  24.       /* Jump to user application */  

  25.       JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);  

  26.       Jump_To_Application = (pFunction) JumpAddress;  

  27.       /* Initialize user application's Stack Pointer */  

  28.       __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);  

  29.       Jump_To_Application();  

  30.     }  

  31.   }  

  32. #endif  

  33.   while (1)  

  34.   {}  

  35. }  


由于NUCLEO板子默认使用的是USART2,因此需要修改使用的串口:


  1. void IAP_Init(void)  

  2. {  

  3.  USART_InitTypeDef USART_InitStructure;  

  4.   /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/  

  5.   /* USART configured as follow: 

  6.         - BaudRate = 115200 baud 

  7.         - Word Length = 8 Bits 

  8.         - One Stop Bit 

  9.         - No parity 

  10.         - Hardware flow control disabled (RTS and CTS signals) 

  11.         - Receive and transmit enabled 

  12.   */  

  13.   USART_InitStructure.USART_BaudRate = 115200;  

  14.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;  

  15.   USART_InitStructure.USART_StopBits = USART_StopBits_1;  

  16.   USART_InitStructure.USART_Parity = USART_Parity_No;  

  17.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

  18.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  

  19.   

  20.   //STM_EVAL_COMInit(COM2, &USART_InitStructure);  

  21.   USART2_Init(&USART_InitStructure);  

  22. }  


USART2_Init()函数为新添加的串口初始化函数,其定义如下:


  1. void USART2_Init(USART_InitTypeDef* USART_InitStruct)  

  2. {  

  3.   GPIO_InitTypeDef GPIO_InitStructure;  

  4.   

  5.   /* Enable GPIO clock */  

  6.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  

  7.   

  8.   /* Enable UART clock */  

  9.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  

  10.   

  11.   /* Connect PXx to USARTx_Tx */  

  12.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);  

  13.   

  14.   /* Connect PXx to USARTx_Rx */  

  15.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);  

  16.   

  17.   /* Configure USART Tx as alternate function push-pull */  

  18.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;  

  19.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  

  20.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;  

  21.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  

  22.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  

  23.   GPIO_Init(GPIOA, &GPIO_InitStructure);  

  24.   

  25.   /* Configure USART Rx as alternate function push-pull */  

  26.   //GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM];  

  27.   //GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure);  

  28.   

  29.   /* USART configuration */  

  30.   USART_Init(USART2, USART_InitStruct);  

  31.   

  32.   /* Enable USART */  

  33.   USART_Cmd(USART2, ENABLE);  

  34. }  


接下来需要修改程序中使用到的打印函数:


  1. void SerialPutChar(uint8_t c)  

  2. {  

  3.   USART_SendData(USART2, c);  

  4.   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)  

  5.   {  

  6.   }  

  7. }  



  1. uint32_t SerialKeyPressed(uint8_t *key)  

  2. {  

  3.   

  4.   if ( USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)  

  5.   {  

  6.     *key = (uint8_t)USART2->DR;  

  7.     return 1;  

  8.   }  

  9.   else  

  10.   {  

  11.     return 0;  

  12.   }  

  13. }  


基本上就移植好了,编译烧录进NUCLEO板中运行。


接下来需要找一个PC端软件超级终端。

由于我使用的是64位Windows7,默认是不带Hyper Terminal的,需要下载个:http://download.csdn.net/detail/crifan/3508497

我是下载的这个,是XP中带的那个,还不错吧。


除了IAP程序,我们还得准备APP程序,由于IAP支持烧录的是BIN文件,因此,我们得生成BIN文件,HEX是不行的。

在APP工程中我们得注意几项内容,以IAR为例:

1 在option->Linker下:

  config->Edit..--->Vector Table 的起始地址改为:0x08003000

  ---->Memory Regions->ROM改为:0x08003000


2 option->Output Converter->修改生成BIN文件


3  sysytem_stm32l1xx.c文件下

 找到宏定义

    #define VECT_TAB_OFFSET  0x3000

 偏移位置必须改为0x3000

到此基本可以了,APP就这样。


最后就是测试了。


测试:

首先得将IAP烧录进MCU,然后再通过IAP烧录APP。

通过IAP烧录APP过程如下:

打开超级终端,连接上串口,有如下界面:

波特率:115200 data bis:8 parity:none stop bits:1 Flow control:none

通过键盘输入1:

从菜单transfer->Send file打开如下界面,输入APP的BIN文件路径,并使用Ymodem传输协议,如下图:

点击Send,开始烧录。。。

传输结束后,按下3,运行APP程序,至此,整个IAP与APP都可以正常工作了。


结束语:

这个只是个示例,实际IAP是还需要修改的,得判断是进行升级模式还是直接跳过进入APP,这个就需要看设计如何了。


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 用数字电路CD4069制作的万能遥控轻触开关

  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 带有短路保护系统的5V直流稳压电源电路图

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章