相关代码和工程文件链接:https://pan.baidu.com/s/1xE87ZDiRHe7WzxjMQB9_Ng?pwd=1234
-
硬件
stm32f103c8t6开发板网购链接: https://detail.tmall.com/item.htmspm=a1z0d.6639537/tb.1997196601.11.622d7484sYbvlK&id=535614102774
-
工具
串口通信工具:SecureCRT_x86_7.1.1.264_3987 -
软件
3.1 stm32官网代码:en.x-cube-iap-usart,网址:
https://www.st.com/zh/embedded-software/x-cube-iap-usart.html3.2 修改en.x-cube-iap-usart代码:
1)选择en.x-cube-iap-usart\AN4657-STM32Cube_IAP_using_UART\Projects\STM3210C_EVAL文件夹
2)在main.c文件中修改BSP_PB_Init和BSP_PB_GetState修改为Key_GPIO_Config()和Get_Key_State()
key.c 代码如下:
#include "stm32f1xx_hal.h"
/* 配置按键用到的I/O口 */
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure Key GPIO pins : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
uint8_t Get_Key_State(void)
{
return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5);
}
3)SystemClock_Config用CubeMX生成的的SystemClock_Config来代替
4)修改IAP_Init,串口用USART2,PA2 ------> USART2_TX, PA3 ------> USART2_RX
/**
* @brief Initialize the IAP: Configure USART.
* @param None
* @retval None
*/
void IAP_Init(void)
{
MX_USART2_UART_Init();
}
usart.c文件代码如下:
#include "usart.h"
extern void Error_Handler(void);
extern UART_HandleTypeDef UartHandle;
void MX_USART2_UART_Init(void)
{
UartHandle.Instance = USART2;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (uartHandle->Instance == USART2)
{
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle)
{
if (uartHandle->Instance == USART2)
{
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2 | GPIO_PIN_3);
/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
}
}
5)common.c文件中Serial_PutByte函数UartHandle.State修改为UartHandle.gState
6)STM3210C_EVAL\IAP_Main\Inc\flash_if.h修改
#define USER_FLASH_END_ADDRESS 0x08040000
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO9 | OB_WRP_PAGES10TO11 | OB_WRP_PAGES12TO13 | OB_WRP_PAGES14TO15 | \
OB_WRP_PAGES16TO17 | OB_WRP_PAGES18TO19 | OB_WRP_PAGES20TO21 | OB_WRP_PAGES22TO23 | \
OB_WRP_PAGES24TO25 | OB_WRP_PAGES26TO27 | OB_WRP_PAGES28TO29 | OB_WRP_PAGES30TO31 | \
OB_WRP_PAGES32TO33 | OB_WRP_PAGES34TO35 | OB_WRP_PAGES36TO37 | OB_WRP_PAGES38TO39 )
7)修改MDK魔法棒中的C/C++,修改为STM32F103xB
8)修改 STM32F103C8T6最小系统(客户资料)-1411\STM32F103C8T6例程\基本例程-I0操作_LED流水灯\LED流水灯
8.1) 修改MDK魔法棒中Target
8.2) 添加MDK魔法棒中Linker中test.sct文件
test.sct文件代码如下:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08004000 0x00010000 { ; load region size_region
ER_IROM1 0x08004000 0x00010000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00005000 { ; RW data
.ANY (+RW +ZI)
}
}
9)MDK文件截图
10)如果在IAP跳转前添加了“__disable_irq();”,那在App程序开始前一定要添加“__enable_irq();”语句开打开中断请求。
- 验证
注意不能Enable the write protection,否则重新下载代码时会提示如下警告