历史上的今天
返回首页

历史上的今天

今天是:2025年04月22日(星期二)

正在发生

2018年04月22日 | STM32CubeMX开发实战之项目分析法则

2018-04-22 来源:eefocus

一、第一个项目

我们要建立第一个项目,这里主要是为了进行项目分析之用,让我们明白用CubeMX是如何开展工作的以及如何追踪代码逻辑。好了,废话不多说,开干。 
这里我选了一款型号为STM32L151C8Tx作为例子来配置MX,如图所示。这里写图片描述
这里写图片描述
这里写图片描述
按照上图配置完成后,对MX工程进行配置,然后生成代码即可,见图。这里写图片描述 
这里写图片描述
好了,不出大的意外,第一个项目已经生成。大家自行打开即可。

二、项目架构

嗯,真的简单的架构,就那么几个文件夹而已,看图。请叫我贴图王,因为我真的非常喜欢图文并茂。这里写图片描述 
惊不惊喜、意不意外,这样就可以任意驰骋在STM32的海洋里了,无需管那人世间的纷纷扰扰。好了,拉回来。从图中看的确简单,但是我们还是有必要深入代码深处,逐步探究下这CubeMX生成的代码到底是怎么跑起来的。

三、深入代码

深入代码到底多深,只有自己知道,我这里权当抛砖引玉,各路高手自行进一步探究噢。我知道很多人和我一样有强迫症,第一个想看的不是main.c而是。。。。。。江湖中人人传到的汇编!在这个例子中就是startup_stm32l151xb.s。看看这名字,就知道这是个启动代码,只是后缀比较性感,是S。 
写CubeMX的人还是很牛逼的,看汇编文件其实也很好看懂,不信你看。这里写图片描述 
文件的开头写的很清楚就做这么几件事情。 
1. 设置系统初始的SP 
2. 设置系统初始的PC,PC就是reset_hanlder 
3. 设置中断向量表 
4. 配置系统时钟 
5. 跳到C库的_main中,注意_main不是main噢 
看下面的源文件内容吧,我来简要注释下。


/* 栈配置 */

; Stack Configuration

;   Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>

;

Stack_Size      EQU     0x400    /* 设置stack大小为0x400 */


                /* 定义STACK代码段,可读写,对齐8字节 */

                AREA    STACK, NOINIT, READWRITE, ALIGN=3

/* 分一段stack size大小的内存空间 */

Stack_Mem       SPACE   Stack_Size

__initial_sp


/* 堆配置 */

; Heap Configuration

;    Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>

;


Heap_Size      EQU     0x200


                AREA    HEAP, NOINIT, READWRITE, ALIGN=3

__heap_base

Heap_Mem        SPACE   Heap_Size

__heap_limit


                PRESERVE8

                THUMB



/* 向量表 */

; Vector Table Mapped to Address 0 at Reset

                AREA    RESET, DATA, READONLY

                EXPORT  __Vectors

                EXPORT  __Vectors_End

                EXPORT  __Vectors_Size


__Vectors       DCD     __initial_sp              ; Top of Stack

                DCD     Reset_Handler             ; Reset Handler

                DCD     NMI_Handler               ; NMI Handler

                DCD     HardFault_Handler         ; Hard Fault Handler

                DCD     MemManage_Handler         ; MPU Fault Handler

                DCD     BusFault_Handler          ; Bus Fault Handler

                DCD     UsageFault_Handler        ; Usage Fault Handler

                DCD     0                         ; Reserved

                DCD     0                         ; Reserved

                DCD     0                         ; Reserved

                DCD     0                         ; Reserved

                DCD     SVC_Handler               ; SVCall Handler

                DCD     DebugMon_Handler          ; Debug Monitor Handler

                DCD     0                         ; Reserved

                DCD     PendSV_Handler            ; PendSV Handler

                DCD     SysTick_Handler           ; SysTick Handler


                ; External Interrupts

                DCD     WWDG_IRQHandler           ; Window Watchdog

                DCD     PVD_IRQHandler            ; PVD through EXTI Line detect

                DCD     TAMPER_STAMP_IRQHandler   ; Tamper and Time Stamp

                DCD     RTC_WKUP_IRQHandler       ; RTC Wakeup

                DCD     FLASH_IRQHandler          ; FLASH

                DCD     RCC_IRQHandler            ; RCC

                DCD     EXTI0_IRQHandler          ; EXTI Line 0

                DCD     EXTI1_IRQHandler          ; EXTI Line 1

                DCD     EXTI2_IRQHandler          ; EXTI Line 2

                DCD     EXTI3_IRQHandler          ; EXTI Line 3

                DCD     EXTI4_IRQHandler          ; EXTI Line 4

                DCD     DMA1_Channel1_IRQHandler  ; DMA1 Channel 1

                DCD     DMA1_Channel2_IRQHandler  ; DMA1 Channel 2

                DCD     DMA1_Channel3_IRQHandler  ; DMA1 Channel 3

                DCD     DMA1_Channel4_IRQHandler  ; DMA1 Channel 4

                DCD     DMA1_Channel5_IRQHandler  ; DMA1 Channel 5

                DCD     DMA1_Channel6_IRQHandler  ; DMA1 Channel 6

                DCD     DMA1_Channel7_IRQHandler  ; DMA1 Channel 7

                DCD     ADC1_IRQHandler           ; ADC1

                DCD     USB_HP_IRQHandler         ; USB High Priority

                DCD     USB_LP_IRQHandler         ; USB Low  Priority

                DCD     DAC_IRQHandler            ; DAC

                DCD     COMP_IRQHandler           ; COMP through EXTI Line

                DCD     EXTI9_5_IRQHandler        ; EXTI Line 9..5

                DCD     0                         ; Reserved

                DCD     TIM9_IRQHandler           ; TIM9

                DCD     TIM10_IRQHandler          ; TIM10

                DCD     TIM11_IRQHandler          ; TIM11

                DCD     TIM2_IRQHandler           ; TIM2

                DCD     TIM3_IRQHandler           ; TIM3

                DCD     TIM4_IRQHandler           ; TIM4

                DCD     I2C1_EV_IRQHandler        ; I2C1 Event

                DCD     I2C1_ER_IRQHandler        ; I2C1 Error

                DCD     I2C2_EV_IRQHandler        ; I2C2 Event

                DCD     I2C2_ER_IRQHandler        ; I2C2 Error

                DCD     SPI1_IRQHandler           ; SPI1

                DCD     SPI2_IRQHandler           ; SPI2

                DCD     USART1_IRQHandler         ; USART1

                DCD     USART2_IRQHandler         ; USART2

                DCD     USART3_IRQHandler         ; USART3

                DCD     EXTI15_10_IRQHandler      ; EXTI Line 15..10

                DCD     RTC_Alarm_IRQHandler      ; RTC Alarm through EXTI Line

                DCD     USB_FS_WKUP_IRQHandler    ; USB FS Wakeup from suspend

                DCD     TIM6_IRQHandler           ; TIM6

                DCD     TIM7_IRQHandler           ; TIM7


__Vectors_End


__Vectors_Size  EQU  __Vectors_End - __Vectors


                AREA    |.text|, CODE, READONLY


/* 重启后进来的第一个地方 */

; Reset handler routine

Reset_Handler    PROC

                 EXPORT  Reset_Handler             [WEAK]

        IMPORT  __main

        IMPORT  SystemInit  

                 LDR     R0, =SystemInit

                 BLX     R0              

                 LDR     R0, =__main

                 BX      R0

                 ENDP


; Dummy Exception Handlers (infinite loops which can be modified)


NMI_Handler     PROC

                EXPORT  NMI_Handler                [WEAK]

                B       .

                ENDP

HardFault_Handler\

                PROC

                EXPORT  HardFault_Handler          [WEAK]

                B       .

                ENDP

MemManage_Handler\

                PROC

                EXPORT  MemManage_Handler          [WEAK]

                B       .

                ENDP

BusFault_Handler\

                PROC

                EXPORT  BusFault_Handler           [WEAK]

                B       .

                ENDP

UsageFault_Handler\

                PROC

                EXPORT  UsageFault_Handler         [WEAK]

                B       .

                ENDP

SVC_Handler     PROC

                EXPORT  SVC_Handler                [WEAK]

                B       .

                ENDP

DebugMon_Handler\

                PROC

                EXPORT  DebugMon_Handler           [WEAK]

                B       .

                ENDP

PendSV_Handler  PROC

                EXPORT  PendSV_Handler             [WEAK]

                B       .

                ENDP

SysTick_Handler PROC

                EXPORT  SysTick_Handler            [WEAK]

                B       .

                ENDP


Default_Handler PROC


                EXPORT  WWDG_IRQHandler            [WEAK]

                EXPORT  PVD_IRQHandler             [WEAK]

                EXPORT  TAMPER_STAMP_IRQHandler    [WEAK]

                EXPORT  RTC_WKUP_IRQHandler        [WEAK]

                EXPORT  FLASH_IRQHandler           [WEAK]

                EXPORT  RCC_IRQHandler             [WEAK]

                EXPORT  EXTI0_IRQHandler           [WEAK]

                EXPORT  EXTI1_IRQHandler           [WEAK]

                EXPORT  EXTI2_IRQHandler           [WEAK]

                EXPORT  EXTI3_IRQHandler           [WEAK]

                EXPORT  EXTI4_IRQHandler           [WEAK]

                EXPORT  DMA1_Channel1_IRQHandler   [WEAK]

                EXPORT  DMA1_Channel2_IRQHandler   [WEAK]

                EXPORT  DMA1_Channel3_IRQHandler   [WEAK]

                EXPORT  DMA1_Channel4_IRQHandler   [WEAK]

                EXPORT  DMA1_Channel5_IRQHandler   [WEAK]

                EXPORT  DMA1_Channel6_IRQHandler   [WEAK]

                EXPORT  DMA1_Channel7_IRQHandler   [WEAK]

                EXPORT  ADC1_IRQHandler            [WEAK]

                EXPORT  USB_HP_IRQHandler          [WEAK]

                EXPORT  USB_LP_IRQHandler          [WEAK]

                EXPORT  DAC_IRQHandler             [WEAK]

                EXPORT  COMP_IRQHandler            [WEAK]

                EXPORT  EXTI9_5_IRQHandler         [WEAK]

                EXPORT  TIM9_IRQHandler            [WEAK]

                EXPORT  TIM10_IRQHandler           [WEAK]

                EXPORT  TIM11_IRQHandler           [WEAK]

                EXPORT  TIM2_IRQHandler            [WEAK]

                EXPORT  TIM3_IRQHandler            [WEAK]

                EXPORT  TIM4_IRQHandler            [WEAK]

                EXPORT  I2C1_EV_IRQHandler         [WEAK]

                EXPORT  I2C1_ER_IRQHandler         [WEAK]

                EXPORT  I2C2_EV_IRQHandler         [WEAK]

                EXPORT  I2C2_ER_IRQHandler         [WEAK]

                EXPORT  SPI1_IRQHandler            [WEAK]

                EXPORT  SPI2_IRQHandler            [WEAK]

                EXPORT  USART1_IRQHandler          [WEAK]

                EXPORT  USART2_IRQHandler          [WEAK]

                EXPORT  USART3_IRQHandler          [WEAK]

                EXPORT  EXTI15_10_IRQHandler       [WEAK]

                EXPORT  RTC_Alarm_IRQHandler       [WEAK]

                EXPORT  USB_FS_WKUP_IRQHandler     [WEAK]

                EXPORT  TIM6_IRQHandler            [WEAK]

                EXPORT  TIM7_IRQHandler            [WEAK]


WWDG_IRQHandler

PVD_IRQHandler

TAMPER_STAMP_IRQHandler

RTC_WKUP_IRQHandler

FLASH_IRQHandler

RCC_IRQHandler

EXTI0_IRQHandler

EXTI1_IRQHandler

EXTI2_IRQHandler

EXTI3_IRQHandler

EXTI4_IRQHandler

DMA1_Channel1_IRQHandler

DMA1_Channel2_IRQHandler

DMA1_Channel3_IRQHandler

DMA1_Channel4_IRQHandler

DMA1_Channel5_IRQHandler

DMA1_Channel6_IRQHandler

DMA1_Channel7_IRQHandler

ADC1_IRQHandler

USB_HP_IRQHandler

USB_LP_IRQHandler

DAC_IRQHandler

COMP_IRQHandler

EXTI9_5_IRQHandler

TIM9_IRQHandler

TIM10_IRQHandler

TIM11_IRQHandler

TIM2_IRQHandler

TIM3_IRQHandler

TIM4_IRQHandler

I2C1_EV_IRQHandler

I2C1_ER_IRQHandler

I2C2_EV_IRQHandler

I2C2_ER_IRQHandler

SPI1_IRQHandler

SPI2_IRQHandler

USART1_IRQHandler

USART2_IRQHandler

USART3_IRQHandler

EXTI15_10_IRQHandler

RTC_Alarm_IRQHandler

USB_FS_WKUP_IRQHandler

TIM6_IRQHandler

TIM7_IRQHandler


                B       .


                ENDP


                ALIGN


;*******************************************************************************

; User Stack and Heap initialization

;*******************************************************************************

                 /* micro lib的话,就导出这些符号 */

                 IF      :DEF:__MICROLIB           


                 EXPORT  __initial_sp

                 EXPORT  __heap_base

                 EXPORT  __heap_limit


                 ELSE


                 IMPORT  __use_two_region_memory

                 EXPORT  __user_initial_stackheap


__user_initial_stackheap


                 LDR     R0, =  Heap_Mem

                 LDR     R1, =(Stack_Mem + Stack_Size)

                 LDR     R2, = (Heap_Mem +  Heap_Size)

                 LDR     R3, = Stack_Mem

                 BX      LR


                 ALIGN


                 ENDIF


                 END


从汇编到main其实需要好好分析,大家课可以找个安静的环境慢慢深入,嗯,慢慢深入。假设我们已经走到了main的内心,那么我们从main开始吧。

/* main函数 */

int main(void)

{

  记得cubeMX配置后,会生成项目,新的文件,凡是出现user code begin的地方,将你的个人代码写在该区域,以免你配置后把你辛苦写  的代码覆盖了

  /* USER CODE BEGIN 1 */


  /* USER CODE END 1 */


  /* MCU Configuration----------------------------------------------------------*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();


  /* USER CODE BEGIN Init */


  /* USER CODE END Init */


  /* Configure the system clock */

  SystemClock_Config();


  /* USER CODE BEGIN SysInit */


  /* USER CODE END SysInit */


  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_USART1_UART_Init();


  /* USER CODE BEGIN 2 */


  /* USER CODE END 2 */


  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

  熟悉的主循环

  /* USER CODE END WHILE */


  /* USER CODE BEGIN 3 */


  }

  /* USER CODE END 3 */


}

整个main其实还是很简单的,这也是CubeMX的初衷,简化开发的难度。大家可以注意到,在项目里有个文件夹Drivers/STM32L1XX_HAL_Driver,里面存的是你的兵器库,是各种库文件,以后你会用的飞起。后面会结合具体项目来具体讲解,今天有点晚了,就到这了噢。

推荐阅读

史海拾趣

EIC [EIC discrete Semiconductors]公司的发展小趣事

EIC公司自创立之初,就致力于离散半导体技术的研发与创新。在成立初期,公司面临了技术瓶颈和市场接受度的双重挑战。然而,EIC的研发团队通过不懈努力,成功研发出了一款高性能、低功耗的离散半导体产品,这一技术突破不仅为公司赢得了市场认可,也为后续的产品线扩展奠定了坚实的基础。随着技术的不断进步和产品线的不断丰富,EIC逐渐在电子行业中树立起了自己的品牌形象。

FutureWafer公司的发展小趣事

EIC公司非常重视人才培养和团队建设。公司注重员工的技能培训和职业发展规划,为员工提供了广阔的发展空间和良好的职业前景。同时,EIC还积极引进国内外优秀人才,打造了一支高素质、专业化的研发团队和管理团队。这些人才为公司的发展提供了强有力的智力支持,也为公司的持续创新提供了源源不断的动力。

BOOKHAM公司的发展小趣事

BOOKHAM公司自创立之初,就专注于光学元件的研发和生产。随着电子行业的快速发展,公司不断投入研发资源,终于在一次技术突破中,成功开发出一款高性能的光学元件。这款元件凭借其卓越的性能和稳定的品质,迅速获得了市场的认可,BOOKHAM公司也因此名声大噪,逐渐在电子行业中崭露头角。

GainSpan ( Telit)公司的发展小趣事

风华的故事始于1984年,当时广东肇庆风华电子厂成立,最初业务聚焦于收录机装配。一年后,即1985年,国内首条从美国引进的年产1亿只片式多层陶瓷电容器生产线落户风华,标志着公司正式踏入高新技术产业领域。这一举措不仅提升了公司的技术实力,也为后续的发展奠定了坚实基础。

Hirschmann公司的发展小趣事
由于TC4066是模拟开关,其开关状态可以由外部数字信号控制。因此,可以通过编程改变输入到TC4066的数字信号(A、B、C、D等),从而改变电路中的电阻/电容值或信号路径,进而间接调整延时时间。这种方法更加灵活和精确,但需要一定的编程知识和电路调试经验。
3E SECURITY公司的发展小趣事

随着网络安全威胁的不断加剧,电子安全行业面临着前所未有的挑战。3E SECURITY公司紧跟行业趋势,加强了网络安全服务的研发和推广。公司推出了一系列网络安全解决方案,帮助客户有效应对各类网络攻击和数据泄露风险。同时,公司还加强了对客户的安全培训和技术支持,提升了客户的安全意识和应对能力。

问答坊 | AI 解惑

热烈庆祝电子工程世界MCU单片机专题隆重上线!

发展、融合MCU专题融合了走进MCU、应用文章、厂商掠影,三大版块。 走进MCU中详细介绍了MCU基本原理与发展历史,带领读者一起回顾MCU的发展里程。 应用文章中细分了单片机在控制、显示、电源、无线、通信、解码等一系列领域的设计方案。 ...…

查看全部问答>

PCBA清洗工艺方案图示

大家好!         我从事SMT清洗工艺已有多年,自己整理了一些好资料和大家分享,希望大家多多交流,详细资料见附件   “PCB清洗工 艺方案图示”…

查看全部问答>

PB安装后定制内核出现得问题,请教高人!

请问我得PB装好了后,安装了2440的BSP包,为什么定制内核时没有sysgen选项啊。build os里都没白色。但我用x86定制内核却有sysgen选项。高手请指导下啊…

查看全部问答>

电气专业学嵌入式开发适合么?

我是电气工程及其自动化专业的,今年大三,现在想学嵌入式开发,以后搞硬件层或驱动层,请问电气专业学嵌入式是不是偏离了本专业的发展方向?能将嵌入式学好么?请各位前辈和高手指导。…

查看全部问答>

PB5.0导出SDK

PB5.0导出SDK时出错,请高手指教 我在PB5.0导出SDK时,出现下列错误,高手给我把把脉啊,看看问题出在哪了?刚刚开始搞这个东东.... Committing database changes Creating \'required\' feature Adding required files Committing database ...…

查看全部问答>

请大家推荐一款好用的CDMA模块

急求一款好用的CDMA模块,请大家推荐,真的很急,呵呵...如果您有时间的话请高抬贵手指,推荐推荐!! 该模块主要是用来做数据传输的,做车载的GPS系统,所以要满足以下要求: 1、内置TCP/IP、PPP协议栈。 2、可以打电话。 3、支持PDU格式的短信 ...…

查看全部问答>

关于sim卡的基本问题!

有两个问题要请教: 1 sim卡都用到了哪些gsm协议规范? 2 我现在做的项目是读sim卡的信息,就是给sim发送ADPU命令包,但是我不知道sim卡的存储格式,比如我要读电话本,应当怎么做?这方面的资料去哪里找?…

查看全部问答>

外部中断的问题,麻烦版主解答。

现在有一个怪问题,外部中断我设为上升沿触发时,的确是上升沿触发,但是设为下降沿触发时,就上升沿和下降沿都能触发,为什么呢? 外部中断用按键触发。我的电路是用一个按键一端接地,一端接I/O,I/O设为输入上拉模式。…

查看全部问答>

请教 chenbing 长老,关于写到 Flash中运行的程序

本帖最后由 dontium 于 2015-1-23 13:20 编辑 Chenbing 长老: 我用 DSP 2407A  也有一段时间了.但是由于以前手中只有孤零零的一块开发板,生怕弄坏了,断了炊,所以自己写的程序都是 Load 到扩展RAM 中运行,没有写入Flash.做过几次写 Fla ...…

查看全部问答>

有人做过MCU51单片机uIP协议栈+ENC28J60网卡实现tcp协议通讯的大大吗?

如题    在淘宝店家买回ENC28J60 以太网模块http://item.taobao.com/item.htm?scm=1007.77.0.0&id=10390385522&ad_id=&am_id=&cm_id=&pm_id=想做tcp协议的温湿度的传递,采集方面已完成。买回模块以后,对这个uIP协议栈不了解 ...…

查看全部问答>