Clion搭建stm32开发环境(STM32F103C8T6),有这一篇就够(只愿意博君一笑!!!)

clion环境搭建

当涉及到 STM32 的开发环境时,目前使用 Keil IDE 存在一些缺点,而转向使用 CLion(一个流行的跨平台 C/C++ 集成开发环境)可能带来以下优点,Keil IDE 的集成开发环境可能对于某些项目的需求不够灵活,因为它主要针对 ARM 和特定 MCU 架构的开发,插件和扩展性,Keil IDE 的插件和扩展性相对有限,这可能限制了您在开发过程中使用一些定制化工具和功能,对于新手来说,Keil IDE 的学习曲线可能较陡,特别是在熟悉其界面、配置和工作流程方面,CLion 是一个跨平台的 IDE,可在 Windows、macOS 和 Linux 上运行,为开发者提供了更大的灵活性,强大的代码分析,CLion 提供先进的代码分析和智能感知功能,可以帮助您更轻松地发现和解决代码问题,丰富的插件生态系统CLion 支持丰富的插件,您可以根据项目需求轻松集成各种工具和扩展,CLion 的现代化界面和用户友好的操作方式可以提高开发效率,并使开发过程更加舒适,CMake 集成CLion 对 CMake 的集成非常强大,这对于跨平台开发和项目管理非常有帮助,特别适用于复杂的 STM32 项目,社区支持CLion 拥有活跃的社区,您可以在社区中获取帮助、分享经验,并从其他开发者的经验中受益。
总之,转向使用 CLion 可能为您提供更灵活、功能更强大的开发环境,帮助您更高效地进行 STM32 开发并解决一些 Keil IDE 存在的局限性。但在做出决策之前,建议您仔细考虑您的项目需求、个人偏好以及迁移成本。

一 工具安装

1、工具安装clion

1.1 产品概述

Clion是一款专门开发C以及C++所设计的跨平台的IDE。它是以IntelliJ为基础设计的,包含了许多智能功能来提高开发人员的生产力。这种强大的IDE帮助开发人员在Linux、OS X和Windows上来开发C/C++,同时它还能使用智能编辑器来提高代码质量、自动代码重构并且深度整合Cmake编译系统,从而提高开发人员的工作效率。

提供C以及C++支持(包含C++,libc++和Boost),同时也支持JavaScript,XML,HTML和CSS。跨平台:您可以在64-bit Linux、OS X以及64-bit Windows上使用它。支持GCC、clang、MinGW、Cygwin编译器以及GDB调试器。提供对Cmake支持:包含自动处理Cmake changes和Cmake Targets,更新新创建的C/C++档案以及Cmake Cache编辑器。提供各式编码辅助:包含多行编辑功能、智能完成一键导航等。安全可信的自动代码重构功能。代码分析功能:监控代码品质并提供快速修复让开发人员得以及时就地解决问题。集成了GDB调试器及评估表达式(expressions)功能、STL容器渲染器(renderers)、监视(watches)、内嵌变量视图等。与最热门的版本控制系统集成:Subversion、Git、GitHub、Mercurial、CVS、Perforce及TFS。内建terminal模式并可以通过插件实现提供Vim-emulation模式。

1.2 下载CLion

首先,您需要从JetBrains的官方网站下载CLion安装程序。访问 https://www.jetbrains.com/clion/download/other.html,选择适用于您操作系统的版本,得到Clion.exe文件。

2023-08-14_104829

1.3 运行安装程序

下载完成后,运行安装程序。根据您的操作系统,可能会有一些特定的步骤。以下是一些常见操作系统的安装流程

2023-08-14_105646

1.4 选择安装选项

在安装向导中,您可以选择安装位置、启动菜单文件夹等选项。默认设置通常是可以的,但您可以根据需要进行自定义设置。

2023-08-14_110025

2023-08-14_110158

1.5 安装clion

点击“Install”按钮开始安装过程。安装可能需要一些时间,取决于您的系统性能。

2023-08-14_110411

2023-08-14_110806

1.6 启动CLion

安装完成后,在开始菜单中找到CLion图标并双击它以启动CLion。

2023-08-14_111029

2023-08-14_111254

1.7激活Clion

首次运行CLion时,您可能需要选择激活方式。您可以选择使用JetBrains帐户登录激活,或者使用许可证密钥进行激活。

2023-08-14_112354

2、安装OpenOCD

2.1 产品概述

OpenOCD(Open On-Chip Debugger)是一个开源的、灵活的、用于嵌入式系统开发的调试和编程工具。它允许开发人员通过调试适配器连接到目标芯片的调试接口(如JTAG、SWD等),以进行调试、烧录固件以及执行其他与硬件相关的任务。可以在多个操作系统上运行,包括 Windows、macOS 和各种 Linux 发行版。这使得开发人员能够在不同的开发环境中使用 OpenOCD, 支持多种调试适配器,包括广泛使用的 JTAG、SWD、FTDI 等。这使得您可以选择适合您硬件和需求的合适调试适配器, OpenOCD 提供了广泛的目标芯片支持,包括多种处理器架构(如ARM、MIPS、RISC-V等)。通过相应的配置文件,您可以轻松配置 OpenOCD 以支持特定的目标芯片, 是一个模块化的工具,允许开发人员编写自定义的插件和扩展,以增强功能或添加特定的支持,拥有活跃的社区,您可以在论坛、邮件列表等地方获取帮助、分享经验和解决问题。总之,OpenOCD 是一个功能强大且灵活的嵌入式调试和编程工具,为开发人员提供了在嵌入式系统开发过程中进行调试、烧录和交互的能力。无论您是在开发嵌入式系统、单板计算机还是其他硬件项目,OpenOCD 都可以成为一个有价值的工具。

2.2下载 OpenOCD

首先,您需要从 OpenOCD 官方网站下载 Windows 版本的 OpenOCD。访问 https://gnutoolchains.com/arm-eabi/openocd/ 并选择合适的版本。通常您可以选择预编译的 Windows 执行文件。

2.3解压缩文件

下载完成后,将下载的压缩文件解压到您选择的文件夹中。您可以使用 Windows 自带的压缩工具或第三方工具(如 7-Zip)来完成这一步骤,这里我使用的是WinRAR解压工具,工具方面任选。

2023-08-14_115002

2023-08-14_115139

解压完毕后即可安装成功,安装的本质就是解压。

2.4配置环境变量(可选)

虽然不是必需的步骤,但您可以将 OpenOCD 的路径添加到系统的 PATH 环境变量中,以便在任何目录下都可以直接运行 OpenOCD 命令。要配置环境变量,请按照以下步骤:

  1. 在桌面上,右键单击“此电脑”(或“我的电脑”),然后选择“属性”。

    2023-08-14_140218

  2. 点击左侧的“高级系统设置”。

    2023-08-14_140428

  3. 在弹出的窗口中,点击“环境变量”按钮。

    2023-08-14_140550

  4. 在系统变量部分,找到名为“Path”的变量,双击它,在变量值文本框的末尾,添加 OpenOCD 执行文件所在文件夹的路径,然后点击“确定”。

    2023-08-14_141137

3、安装编译器MinGW 和arm-none-eabi-gcc

3.1下载 MinGW 安装程序

访问 MinGW 官方网站 https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/ 下载 MinGW 安装程序(mingw-get-setup.exe 文件)。

027e89e178844bf091759cfdaae4c484

3.2运行安装程序

双击下载的 mingw-get-setup.exe 文件,系统将提示您是否允许此应用对您的设备进行更改。点击“是”继续。

286f17a6598241318440d70ecb9a6831

ceee0dda772346bc8074d25ac7934433

3.3选择安装目录

在安装向导中,您需要选择 MinGW 的安装目录。建议选择一个不包含空格或特殊字符的路径,例如 C:\MinGW。然后点击“Continue”继续。

3.4 选择组件

在此步骤中,您需要选择要安装的 MinGW 组件。通常,您至少需要选择 mingw32-basemingw32-gcc-g++ 组件,这些组件将提供基本的编译环境。您还可以根据需要选择其他组件。选择完成后,点击“Continue”继续。

19f2ceed524c49d38f57c06d25eb3e20

3.5 安装MinGW

在下一个页面,点击“Installation”以开始安装选择的组件。安装可能需要一些时间,取决于您选择的组件和系统性能。

  1. 这里等待一下,等它安装到100%

efc0b349daeb4662bff310f70406d6db

  1. 勾选全部选项。

  2. 点击左上角【Installation】中的【Apply Changes】

    8129d31e5d3f433b8c3cd50e25c06e45

  3. 点击【Apply】

    8aeee45338b4463ea4bcac06113a3657

  4. 3.7 点击【Close】,完成

7ff4b5e293124cf098ab42f04f88d07e

3.8 添加 MinGW 到系统 PATH 环境变量(可选)

虽然不是必需的步骤,但您可以将 OpenOCD 的路径添加到系统的 PATH 环境变量中,以便在任何目录下都可以直接运行 OpenOCD 命令。要配置环境变量,请按照以下步骤:

  1. 在桌面上,右键单击“此电脑”(或“我的电脑”),然后选择“属性”。

    2023-08-14_140218

  2. 点击左侧的“高级系统设置”。

    2023-08-14_140428

  3. 在弹出的窗口中,点击“环境变量”按钮。

    2023-08-14_140550

  4. 在系统变量部分,找到名为“Path”的变量,双击它,在变量值文本框的末尾,添加 OpenOCD 执行文件所在文件夹的路径,然后点击“确定”。

    2023-08-14_141137

3.9 验证安装

打开命令提示符(Command Prompt)或 PowerShell,输入以下命令验证 MinGW 是否正确安装:

g++ --version

4、安装arm-none-eabi-gcc

4.1 arm-none-eabi-gcc产品概述

arm-none-eabi-gcc 是 ARM 架构的裸机嵌入式系统开发中常用的编译器工具链。它是 GNU Compiler Collection (GCC) 的一部分,专门用于编译 ARM 架构的代码,适用于嵌入式系统开发,特别是不依赖于操作系统(裸机)的情况。提供了一整套编译器工具,包括 C 语言编译器 (arm-none-eabi-gcc)、C++ 编译器 (arm-none-eabi-g++)、汇编器 (arm-none-eabi-as) 和链接器 (arm-none-eabi-ld) 等。这些工具允许开发人员编译、汇编和链接 ARM 架构的代码。支持多种 ARM 架构: arm-none-eabi-gcc 工具链支持多种 ARM 架构,包括 ARM Cortex-M 系列(如 Cortex-M0、Cortex-M3、Cortex-M4 等)和其他 ARM 架构变体。这使得它适用于广泛的嵌入式项目,主要用于裸机嵌入式系统开发,即开发没有操作系统支持的嵌入式应用。它可以生成适合在裸机环境下运行的代码,如裸机驱动程序、引导加载程序等。工具链提供了丰富的优化选项,可以根据开发人员的需求调整代码生成的优化级别,以提高代码性能和资源利用率。是跨平台的工具链,可以在多种操作系统上运行,包括 Windows、macOS 和各种 Linux 发行版。它遵循自由软件许可证,允许开发人员在开源项目中免费使用和分发它。可以与其他开发工具集(如 GDB、OpenOCD 等)集成,以提供完整的嵌入式开发环境,支持调试、烧录和代码分析等任务。由于 arm-none-eabi-gcc 是 GCC 的一部分,它可以借助 GCC 社区和生态系统的支持和资源。开发人员可以从广泛的社区资源中获益,包括文档、示例和讨论论坛。总之,arm-none-eabi-gcc 工具链是嵌入式系统开发中重要的工具之一,适用于裸机嵌入式应用程序的编译、汇编和链接。它提供了丰富的功能和灵活性,帮助开发人员在 ARM 架构下开发高效的嵌入式应用程序。

4.2 下载arm-none-eabi-gcc

首先,您需要从 ARM 官方网站下载 arm-none-eabi-gcc 工具链。访问 https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads 下载适用于 Windows 的版本。

4.3 安装arm-none-eabi-gcc
  1. 找到下载后的arm-none-eabi-gcc.exe 文件 双击打开。

    2023-08-14_152049

  2. 双击点开exe文件后,进入语言选择界面,进行语言选择后,点击ok。

2023-08-14_152135

  1. 同意协议许可

2023-08-14_152251

  1. 安装路径选择页面,这个根据个人硬盘大小进行修改。

2023-08-14_152333

  1. 安装向导最后一页,勾选最后两项。

2023-08-14_152629

4.4验证安装

打开命令提示符(Command Prompt)或 PowerShell,输入以下命令验证工具链是否正确安装:

arm-none-eabi-gcc --version

如果显示了工具链的版本信息,则表示安装成功。

现在,您已经成功安装了 arm-none-eabi-gcc 工具链,可以使用它来编译 ARM 架构的代码。在实际使用中,您可能还需要配置您的开发环境(如编辑器、调试工具等)以与工具链配合使用。请注意,上述步骤假设您在 Windows 操作系统上进行安装,如果您使用其他操作系统,请适当调整步骤。

二 项目创建

1、在Clion中创建项目

2023-08-14_193132

2023-08-14_193208

2023-08-14_193537

2、创建新项目文件夹

2023-08-14_194002

3、导入stm32 需要的固件库

3.1 固件库文件准备

ST固件库(STM32 Firmware Library)是由STMicroelectronics提供的一组软件函数和驱动程序,专门用于支持STMicroelectronics的STM32微控制器系列。这些库提供了一些高级功能和底层驱动,使开发人员能够更轻松地编写STM32微控制器的应用程序。

  1. 准备固件库文件

    2023-08-14_194706

  2. 导入源文件

    2023-08-14_195330

  3. 导入头文件

    2023-08-14_195712

  4. 导入系统文件

    2023-08-14_200045

  5. core_cm3 文件导入

    2023-08-14_200409

  6. 导入stm32f10x_conf.h 文件

    2023-08-14_200807

3.2 启动文件准备

STM32启动文件(Startup File)是用于初始化微控制器硬件和软件环境的重要文件。它在微控制器的启动过程中执行,并负责设置初始状态、配置系统时钟、初始化堆栈、调用主函数等。启动文件在裸机编程(Bare-Metal Programming)中扮演关键角色,确保微控制器正确启动并进入应用程序。

2023-08-14_210335

写入如下内容或者文件直接导入

/**
  *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
  * @file      startup_stm32f103xb.s
  * @author    MCD Application Team
  * @brief     STM32F103xB Devices vector table for Atollic toolchain.
  *            This module performs:
  *                - Set the initial SP
  *                - Set the initial PC == Reset_Handler,
  *                - Set the vector table entries with the exceptions ISR address
  *                - Configure the clock system   
  *                - Branches to main in the C library (which eventually
  *                  calls main()).
  *            After Reset the Cortex-M3 processor is in Thread mode,
  *            priority is Privileged, and the Stack is set to Main.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

  .syntax unified
  .cpu cortex-m3
  .fpu softvfp
  .thumb

.global g_pfnVectors
.global Default_Handler

/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss

.equ  BootRAM, 0xF108F85F
/**
 * @brief  This is the code that gets called when the processor first
 *          starts execution following a reset event. Only the absolutely
 *          necessary set is performed, after which the application
 *          supplied main() routine is called.
 * @param  None
 * @retval : None
*/

  .section .text.Reset_Handler
  .weak Reset_Handler
  .type Reset_Handler, %function
Reset_Handler:

/* Copy the data segment initializers from flash to SRAM */
  ldr r0, =_sdata
  ldr r1, =_edata
  ldr r2, =_sidata
  movs r3, #0
  b LoopCopyDataInit

CopyDataInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4

LoopCopyDataInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyDataInit
  
/* Zero fill the bss segment. */
  ldr r2, =_sbss
  ldr r4, =_ebss
  movs r3, #0
  b LoopFillZerobss

FillZerobss:
  str  r3, [r2]
  adds r2, r2, #4

LoopFillZerobss:
  cmp r2, r4
  bcc FillZerobss

/* Call the clock system intitialization function.*/
    bl  SystemInit
/* Call static constructors */
    bl __libc_init_array
/* Call the application's entry point.*/
  bl main
  bx lr
.size Reset_Handler, .-Reset_Handler

/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 *
 * @param  None
 * @retval : None
*/
    .section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b Infinite_Loop
  .size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3.  Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
  .section .isr_vector,"a",%progbits
  .type g_pfnVectors, %object
  .size g_pfnVectors, .-g_pfnVectors


g_pfnVectors:

  .word _estack
  .word Reset_Handler
  .word NMI_Handler
  .word HardFault_Handler
  .word MemManage_Handler
  .word BusFault_Handler
  .word UsageFault_Handler
  .word 0
  .word 0
  .word 0
  .word 0
  .word SVC_Handler
  .word DebugMon_Handler
  .word 0
  .word PendSV_Handler
  .word SysTick_Handler
  .word WWDG_IRQHandler
  .word PVD_IRQHandler
  .word TAMPER_IRQHandler
  .word RTC_IRQHandler
  .word FLASH_IRQHandler
  .word RCC_IRQHandler
  .word EXTI0_IRQHandler
  .word EXTI1_IRQHandler
  .word EXTI2_IRQHandler
  .word EXTI3_IRQHandler
  .word EXTI4_IRQHandler
  .word DMA1_Channel1_IRQHandler
  .word DMA1_Channel2_IRQHandler
  .word DMA1_Channel3_IRQHandler
  .word DMA1_Channel4_IRQHandler
  .word DMA1_Channel5_IRQHandler
  .word DMA1_Channel6_IRQHandler
  .word DMA1_Channel7_IRQHandler
  .word ADC1_2_IRQHandler
  .word USB_HP_CAN1_TX_IRQHandler
  .word USB_LP_CAN1_RX0_IRQHandler
  .word CAN1_RX1_IRQHandler
  .word CAN1_SCE_IRQHandler
  .word EXTI9_5_IRQHandler
  .word TIM1_BRK_IRQHandler
  .word TIM1_UP_IRQHandler
  .word TIM1_TRG_COM_IRQHandler
  .word TIM1_CC_IRQHandler
  .word TIM2_IRQHandler
  .word TIM3_IRQHandler
  .word TIM4_IRQHandler
  .word I2C1_EV_IRQHandler
  .word I2C1_ER_IRQHandler
  .word I2C2_EV_IRQHandler
  .word I2C2_ER_IRQHandler
  .word SPI1_IRQHandler
  .word SPI2_IRQHandler
  .word USART1_IRQHandler
  .word USART2_IRQHandler
  .word USART3_IRQHandler
  .word EXTI15_10_IRQHandler
  .word RTC_Alarm_IRQHandler
  .word USBWakeUp_IRQHandler
  .word 0
  .word 0
  .word 0
  .word 0
  .word 0
  .word 0
  .word 0
  .word BootRAM          /* @0x108. This is for boot in RAM mode for
                            STM32F10x Medium Density devices. */

/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/

  .weak NMI_Handler
  .thumb_set NMI_Handler,Default_Handler

  .weak HardFault_Handler
  .thumb_set HardFault_Handler,Default_Handler

  .weak MemManage_Handler
  .thumb_set MemManage_Handler,Default_Handler

  .weak BusFault_Handler
  .thumb_set BusFault_Handler,Default_Handler

  .weak UsageFault_Handler
  .thumb_set UsageFault_Handler,Default_Handler

  .weak SVC_Handler
  .thumb_set SVC_Handler,Default_Handler

  .weak DebugMon_Handler
  .thumb_set DebugMon_Handler,Default_Handler

  .weak PendSV_Handler
  .thumb_set PendSV_Handler,Default_Handler

  .weak SysTick_Handler
  .thumb_set SysTick_Handler,Default_Handler

  .weak WWDG_IRQHandler
  .thumb_set WWDG_IRQHandler,Default_Handler

  .weak PVD_IRQHandler
  .thumb_set PVD_IRQHandler,Default_Handler

  .weak TAMPER_IRQHandler
  .thumb_set TAMPER_IRQHandler,Default_Handler

  .weak RTC_IRQHandler
  .thumb_set RTC_IRQHandler,Default_Handler

  .weak FLASH_IRQHandler
  .thumb_set FLASH_IRQHandler,Default_Handler

  .weak RCC_IRQHandler
  .thumb_set RCC_IRQHandler,Default_Handler

  .weak EXTI0_IRQHandler
  .thumb_set EXTI0_IRQHandler,Default_Handler

  .weak EXTI1_IRQHandler
  .thumb_set EXTI1_IRQHandler,Default_Handler

  .weak EXTI2_IRQHandler
  .thumb_set EXTI2_IRQHandler,Default_Handler

  .weak EXTI3_IRQHandler
  .thumb_set EXTI3_IRQHandler,Default_Handler

  .weak EXTI4_IRQHandler
  .thumb_set EXTI4_IRQHandler,Default_Handler

  .weak DMA1_Channel1_IRQHandler
  .thumb_set DMA1_Channel1_IRQHandler,Default_Handler

  .weak DMA1_Channel2_IRQHandler
  .thumb_set DMA1_Channel2_IRQHandler,Default_Handler

  .weak DMA1_Channel3_IRQHandler
  .thumb_set DMA1_Channel3_IRQHandler,Default_Handler

  .weak DMA1_Channel4_IRQHandler
  .thumb_set DMA1_Channel4_IRQHandler,Default_Handler

  .weak DMA1_Channel5_IRQHandler
  .thumb_set DMA1_Channel5_IRQHandler,Default_Handler

  .weak DMA1_Channel6_IRQHandler
  .thumb_set DMA1_Channel6_IRQHandler,Default_Handler

  .weak DMA1_Channel7_IRQHandler
  .thumb_set DMA1_Channel7_IRQHandler,Default_Handler

  .weak ADC1_2_IRQHandler
  .thumb_set ADC1_2_IRQHandler,Default_Handler

  .weak USB_HP_CAN1_TX_IRQHandler
  .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler

  .weak USB_LP_CAN1_RX0_IRQHandler
  .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler

  .weak CAN1_RX1_IRQHandler
  .thumb_set CAN1_RX1_IRQHandler,Default_Handler

  .weak CAN1_SCE_IRQHandler
  .thumb_set CAN1_SCE_IRQHandler,Default_Handler

  .weak EXTI9_5_IRQHandler
  .thumb_set EXTI9_5_IRQHandler,Default_Handler

  .weak TIM1_BRK_IRQHandler
  .thumb_set TIM1_BRK_IRQHandler,Default_Handler

  .weak TIM1_UP_IRQHandler
  .thumb_set TIM1_UP_IRQHandler,Default_Handler

  .weak TIM1_TRG_COM_IRQHandler
  .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler

  .weak TIM1_CC_IRQHandler
  .thumb_set TIM1_CC_IRQHandler,Default_Handler

  .weak TIM2_IRQHandler
  .thumb_set TIM2_IRQHandler,Default_Handler

  .weak TIM3_IRQHandler
  .thumb_set TIM3_IRQHandler,Default_Handler

  .weak TIM4_IRQHandler
  .thumb_set TIM4_IRQHandler,Default_Handler

  .weak I2C1_EV_IRQHandler
  .thumb_set I2C1_EV_IRQHandler,Default_Handler

  .weak I2C1_ER_IRQHandler
  .thumb_set I2C1_ER_IRQHandler,Default_Handler

  .weak I2C2_EV_IRQHandler
  .thumb_set I2C2_EV_IRQHandler,Default_Handler

  .weak I2C2_ER_IRQHandler
  .thumb_set I2C2_ER_IRQHandler,Default_Handler

  .weak SPI1_IRQHandler
  .thumb_set SPI1_IRQHandler,Default_Handler

  .weak SPI2_IRQHandler
  .thumb_set SPI2_IRQHandler,Default_Handler

  .weak USART1_IRQHandler
  .thumb_set USART1_IRQHandler,Default_Handler

  .weak USART2_IRQHandler
  .thumb_set USART2_IRQHandler,Default_Handler

  .weak USART3_IRQHandler
  .thumb_set USART3_IRQHandler,Default_Handler

  .weak EXTI15_10_IRQHandler
  .thumb_set EXTI15_10_IRQHandler,Default_Handler

  .weak RTC_Alarm_IRQHandler
  .thumb_set RTC_Alarm_IRQHandler,Default_Handler

  .weak USBWakeUp_IRQHandler
  .thumb_set USBWakeUp_IRQHandler,Default_Handler

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


3.3 创建链接脚本文件

是一个链接脚本(Linker Script)文件,用于指导编译器如何组织生成的代码和数据,以及如何在微控制器的存储器中分配空间。它是在使用GNU工具链(如GCC编译器)进行STM32F103C8Tx微控制器的裸机编程时使用的一个重要文件。

2023-08-14_210835

在STM32F103C8Tx_FLASH.ld文件中写入如下内容

/*
******************************************************************************
**

**  File        : LinkerScript.ld
**
**  Author		: Auto-generated by System Workbench for STM32
**
**  Abstract    : Linker script for STM32F103C8Tx series
**                64Kbytes FLASH and 20Kbytes RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed “as is,” without any warranty
**                of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
**
** Redistribution and use in src and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**   1. Redistributions of src code must retain the above copyright notice,
**      this list of conditions and the following disclaimer.
**   2. Redistributions in binary form must reproduce the above copyright notice,
**      this list of conditions and the following disclaimer in the documentation
**      and/or other materials provided with the distribution.
**   3. Neither the name of STMicroelectronics nor the names of its contributors
**      may be used to endorse or promote products derived from this software
**      without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20005000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 64K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH

  
  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM

  

  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

4、编写CMakeLists.txt文件

是用于配置CMake构建系统的脚本文件,它的作用是指导CMake如何生成项目的构建文件(如Makefile、Visual Studio项目等),以便在不同的编译环境中进行项目的构建和编译。

使用如下内容覆盖原来的CMakeLists.txt文件内容

#THIS FILE IS AUTO GENERATED FROM THE TEMPLATE! DO NOT CHANGE!
# 设置交叉编译的系统名称为 Generic,系统版本为 1
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
# 指定最低的 CMake 版本要求为 3.20
cmake_minimum_required(VERSION 3.20)

# specify cross compilers and tools
# 指定交叉编译的工具
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
set(SIZE arm-none-eabi-size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# project settings
# 项目设置
project(CLionSTM32Demo C CXX ASM)
# CMake 中的一个命令,用于设置 C++ 编译的标准版本。在这个特定的命令中,它将 C++ 标准设置为 C++17set(CMAKE_CXX_STANDARD 17)
#是 CMake 中的一个命令,用于设置 C 编译的标准版本。在这个特定的命令中,它将 C 标准设置为 C11set(CMAKE_C_STANDARD 11)

#Uncomment for hardware floating point
#add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
#add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)

#Uncomment for software floating point
#add_compile_options(-mfloat-abi=soft)
# 添加 ARM Cortex-M3 处理器相关的编译选项
add_compile_options(-mcpu=cortex-m3 -mthumb -mthumb-interwork)
# 添加编译选项,优化代码大小和资源使用
add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0)


# uncomment to mitigate c++17 absolute addresses warnings
# 设置 C++ 编译选项,以减轻 C++17 的绝对地址警告
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register")

# 根据 CMake 构建类型设置编译选项
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") #这是一个条件判断语句,检查 CMake 构建类型是否为 "Release"(发布)模式。
    message(STATUS "Maximum optimization for speed") #如果构建类型是 "Release",则会输出一条状态消息,指示当前选择了最大化的速度优化。
    add_compile_options(-Ofast) #在 "Release" 模式下,通过 add_compile_options 命令添加编译选项 -Ofast,这是 GCC 编译器的一个选项,用于启用最大级别的优化,以提高代码运行速度。它通常会应用各种优化策略,包括内联函数、循环展开等。
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") # 如果构建类型不是 "Release",则检查是否为 "RelWithDebInfo"(带有调试信息的发布)模式。
    message(STATUS "Maximum optimization for speed, debug info included") #如果构建类型是 "RelWithDebInfo",则输出一条状态消息,指示当前选择了最大化的速度优化,并且还包含了调试信息。
    add_compile_options(-Ofast -g) # 在 "RelWithDebInfo" 模式下,除了启用最大化的速度优化外,还添加了 -g 选项,该选项会生成用于调试的符号信息,以便在调试时可以查看变量和代码执行的详细信息。
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel") # 如果构建类型不是 "RelWithDebInfo",则检查是否为 "MinSizeRel"(最小化大小发布)模式。
    message(STATUS "Maximum optimization for size") # 如果构建类型是 "MinSizeRel",则输出一条状态消息,指示当前选择了最大化的大小优化。
    add_compile_options(-Os) # 在 "MinSizeRel" 模式下,添加编译选项 -Os,这是 GCC 编译器的一个选项,用于启用最大化的大小优化,以减小生成的可执行文件的大小。
else () # 如果前面的条件都不满足,即构建类型不是 "Release""RelWithDebInfo""MinSizeRel",则执行下面的代码块。
    message(STATUS "Minimal optimization, debug info included") # 在其他构建类型下,输出一条状态消息,指示当前选择了最小化的优化,并且还包含了调试信息。
    add_compile_options(-Og -g) # 在其他构建类型下,添加编译选项 -Og -g,这是 GCC 编译器的选项,用于启用适用于调试的优化级别,并生成调试符号信息。
endif ()
# 添加宏定义,指定使用 HAL 驱动和 STM32F103xB 芯片
add_definitions(-DUSE_HAL_DRIVER -DSTM32F103xB -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD)

# 链接源文件 # 配置头文件搜索路径
include_directories( user/inc STM32F10x_FWLib/inc hardware/inc)
# 文件 # 设置源文件列表
file(GLOB_RECURSE SOURCES "startup/*.*" "user/*.*" STM32F10x_FWLib/*.* "hardware/*.*")

# 设置链接脚本路径
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/STM32F103C8Tx_FLASH.ld)
# 添加链接选项,包括链接脚本和其他选项
add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-mcpu=cortex-m3 -mthumb -mthumb-interwork)
add_link_options(-T ${LINKER_SCRIPT})

add_link_options(-specs=nano.specs -specs=nosys.specs -u _printf_float)
# 创建可执行文件目标,包括源文件和链接脚本
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
# 数学函数需要用到
target_link_libraries(${PROJECT_NAME}.elf  m)

# 设置输出的 HEX 和 BIN 文件路径
set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)


# 添加自定义的构建命令,用于生成 HEX 和 BIN 文件
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
        COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
        COMMENT "Building ${HEX_FILE}
Building ${BIN_FILE}")

5、编写主函数测试

5.1 添加主函数

2023-08-14_213459

5.2 删除cmake-build-debug

2023-08-14_213853

5.3 测试项目

更新或重新生成 CMake 构建系统的相关文件,随后点击运行按钮。

2023-08-14_214005

5.4 出现异常

内存地址 [r1] 处尝试进行字节存储,操作失败。

image-20230814214238485

解决方式修改STM32F10x_FWLib/src/core_cm3.c文件的第736行和752行

// 736 行内容
//__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
   __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
// 752 行内容
  //__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
   __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );

image-20230814215506877

5.5 再次点击运行

上面错误基本都会出现,修改代码后即可解决,修改完成后再次点击运行即可。

2023-08-14_221102

出现如上内容编译通过

三、烧录配置

1. 创建烧录配置文件

工程根目录下新建一个文件夹Config,在里面新建一个配置文件linkConfig.cfg,文件的内容如下:

2023-08-14_211959

2. 仿真器文件创建:

野火fireDap作为

# choose st-link/j-link/dap-link etc.
adapter driver cmsis-dap
source [find target/stm32f1x.cfg]

用ST-Link使用:

source [find interface/stlink.cfg]
transport select hla_swd
source [find target/stm32f1x.cfg]
adapter speed 10000
3. clion添加open ocd

点击File ->Settings->Build,Execution,Deployment->Embedded Development

修改OpenOCD为我们自己的安装路径

2023-08-14_221851

4.添加烧录配置

选择 OpenOCD Download& Run 配置选项,准备编辑烧录配置文件。

2023-08-14_222303

编辑配置,点击烧录配置文件,为烧录做准备。

2023-08-14_222601

配置完成之后就可以进行烧录了。

最后提升如下内容没有出现异常,即为项目创建成功,clion打印信息是红色的没有关系

[0m[0mOpen On-Chip Debugger 0.12.0 (2023-02-02) [https://github.com/sysprogs/openocd]
Licensed under GNU GPL v2
libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use '
transport select <transport>'.
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: SWO-UART supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: FW Version = 0253
Info : CMSIS-DAP: Serial# = 0700000100480064410000104e543246a5a5a5a597969908
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x1ba01477
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : gdb port disabled
[stm32f1x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xb9337822 msp: 0x4c05b510
** Programming Started **
Info : device id = 0x20036410
Info : flash size = 64 KiB
Warn : Adding extra erase range, 0x080066e8 .. 0x080067ff
** Programming Finished **
shutdown command invoked

四、 项目模板:https://github.com/xing-guangEasy/stm32-STM32F103C8T6.git

五、 创建所需文件:https://pan.baidu.com/s/1H0fhTDgxEjwXgBIk6KlM0Q?pwd=6i1m

提取码:6i1m

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值