使用openocd、clion开发stm32H7

软件配置和AD

你需要有Stm32CubeMX,STM32CubeProg,Clion,OpenOCD,安装方法可以去B站搜索。

Stm32H750VBT6一般开发板会配置一个外部Flash,与单片机通过QSPI连接,其配置过程有很多种。同时给大家推荐一个宝藏店铺:https://m.tb.cn/h.5WdDoPw?tk=ojMqdwoLcQD

反客联盟一生推!WeACT也相当不错,两家店的单片机电路板做的都非常牛,绝缘漆摸起来特别细腻,上面也没有助焊剂残留,焊盘都是烫金的黑色和金色相配,我哭死,太懂我了!!!!

反客科技:https://m.tb.cn/h.5dTczLA

WeACT:https://m.tb.cn/h.5XyuqhE

这俩家店铺无偿广告,因为是产品质量打动了我,有stm32系列芯片采购需求可以看看这俩家,质量绝对好,同时也有C8T6的平价高配替代品:stm32f411ceu6

配置文件

openocd的stm32h750xbh6.cfg文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# SPDX-License-Identifier: GPL-2.0-or-later

# This is a FK750M5-XBH6-SDRAM with a single STM32H750XBH6 chip.
# https://item.taobao.com/item.htm?id=682521953131
# QQ交流群:536665479
# Made by Peakors

# This is for using the STLINK
source [find interface/stlink.cfg]

transport select hla_swd

set CHIPNAME STM32H750XBH6

set QUADSPI 1

# enable stmqspi
if {![info exists QUADSPI]} {
set QUADSPI 1
}

source [find target/stm32h7x.cfg]

reset_config srst_only

# QUADSPI initialization
proc qspi_init { qpi } {
global a
mmw 0x580244E0 0x000007FF 0;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)
mmw 0x580244D4 0x00004000 0;# RCC_AHB3ENR |= QSPIEN (enable clock)
sleep 1;# Wait for clock startup

# Port F: PF10:AF09:H, PF09:AF10:H, PF08:AF10:H, PF07:AF09:H, PF06:AF09:H
mmw 0x58021400 0x002AA000 0x00155000 ;# MODER
mmw 0x58021408 0x002AA000 0x00155000 ;# OSPEEDR
mmw 0x5802140C 0x00000000 0x003FF000 ;# PUPDR
mmw 0x58021420 0x99000000 0x66000000 ;# AFRL
mmw 0x58021424 0x000009AA 0x00000655 ;# AFRH
# Port G: PG06:AF10:H
mmw 0x58021800 0x00002000 0x00001000 ;# MODER
mmw 0x58021808 0x00002000 0x00001000 ;# OSPEEDR
mmw 0x5802180C 0x00000000 0x00003000 ;# PUPDR
mmw 0x58021820 0x0A000000 0x05000000 ;# AFRL

mww 0x52005000 0x01000F10 ;# QUADSPI_CR: PRESCALER = 0x1(2分频), FTHRES = 0b01111, FSEL=0, DFM=0, SSHIFT=1
mww 0x52005004 0x00160001 ;# QUADSPI_DCR: FSIZE = 0b10110, CSHT = 0b000, CKMODE = 0b1
mmw 0x52005000 0x00000001 0 ;# QUADSPI_CR: EN=1
# 内存映射模式 单线SPI模式, 3字节地址
mww 0x52005014 0x0D002503 ;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ

}


$_CHIPNAME.cpu0 configure -event reset-init {
global QUADSPI

mmw 0x52002000 0x00000004 0x0000000B ;# FLASH_ACR: 4 WS for 192 MHZ HCLK

mmw 0x58024400 0x00000001 0x00000018 ;# RCC_CR: HSIDIV=1, HSI on
mmw 0x58024410 0x10000000 0xEE000007 ;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock
mww 0x58024418 0x00000040 ;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1
mww 0x5802441C 0x00000440 ;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2
mww 0x58024420 0x00000040 ;# RCC_D3CFGR: D3PPRE=2
mww 0x58024428 0x00000040 ;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI
mmw 0x5802442C 0x0001000C 0x00000002 ;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide
mww 0x58024430 0x01070217 ;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24
mmw 0x58024400 0x01000000 0 ;# RCC_CR: PLL1ON=1
sleep 1
mmw 0x58024410 0x00000003 0 ;# RCC_CFGR: PLL1 as system clock
sleep 1

adapter speed 24000

if { $QUADSPI } {
qspi_init 1
}
}

对于vbt6一样,新建一个stm32h750vbt6.cfg,写入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

# Choose debugger
source [find interface/stlink.cfg]

# Choose transport interfance
transport select hla_swd

# Set chip name
set CHIPNAME STM32H7B0VBT6

# Enable stmqspi
if {![info exists OCTOSPI1]} {
set OCTOSPI1 1
set OCTOSPI2 0
}

# Use built-in stm32h7 openocd configs
source [find target/stm32h7x.cfg]

reset_config none separate

# OCTOSPI initialization
proc octospi_init { octo } {
global a b
mmw 0x58024540 0x000006FF 0 ;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)
mmw 0x58024534 0x00284000 0 ;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)
sleep 1 ;# Wait for clock startup

mww 0x5200B404 0x03010111 ;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1
mww 0x5200B408 0x00000000 ;# OCTOSPIM_P2CR: disable Port 2

# AF mapping can be found in datasheet. For h7b0, see DS13196, page 54
# PB02: OCSPI1_CLK, PB06: OCSPI1_NCS, PD11: OCSPI1_IO0, PD12: OCSPI1_IO1, PE2: OCSPI1_IO2, PD13: OCSPI1_IO3
# Generate the GPIO config: perl resources/gpio_gen.pl -c "PB06:AF10:V, PB02:AF09:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PE02:AF09:V"

# mmw command: "memory modify word, modify only given bits"
# usage: mmw "address setbits clearbits"

# PB06:AF10:V, PB02:AF09:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PE02:AF09:V
# Port B: PB06:AF10:V, PB02:AF09:V
mmw 0x58020400 0x00002020 0x00001010 ;# MODER
mmw 0x58020408 0x00003030 0x00000000 ;# OSPEEDR
mmw 0x5802040C 0x00000000 0x00003030 ;# PUPDR
mmw 0x58020420 0x0A000900 0x05000600 ;# AFRL
# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V
mmw 0x58020C00 0x0A800000 0x05400000 ;# MODER
mmw 0x58020C08 0x0FC00000 0x00000000 ;# OSPEEDR
mmw 0x58020C0C 0x00000000 0x0FC00000 ;# PUPDR
mmw 0x58020C24 0x00999000 0x00666000 ;# AFRH
# Port E: PE02:AF09:V
mmw 0x58021000 0x00000020 0x00000010 ;# MODER
mmw 0x58021008 0x00000030 0x00000000 ;# OSPEEDR
mmw 0x5802100C 0x00000000 0x00000030 ;# PUPDR
mmw 0x58021020 0x00000900 0x00000600 ;# AFRL

# OCTOSPI1: Use 1-1-1 read and 0x03 read data command
mww 0x52005000 0x3040000B ;# OCTOSPI_CR: FMODE=01, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0
mww 0x52005008 0x00160100 ;# OCTOSPI_DCR1: MTYP=0x0, FSIZE=0x16=22=2^(22+1), CSHT=01, CKMODE=0, DLYBYP=0
mww 0x5200500C 0x00000001 ;# OCTOSPI_DCR2: WRAPSIZE=0, PRESCALER=0+1

mww 0x52005100 0x01002101 ;# OCTOSPI_CCR: SIOO=0, DMODE=001, ABSIZE=00, ABMODE=000, ADSIZE=10, ADMODE=001, ISIZE=0x0, IMODE=001
mww 0x52005108 0x00000000 ;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0
mww 0x52005110 0x00000003 ;# OCTOSPI_IR: INSTR=ReadData, 0x03

sleep 1

flash probe $a ;# load configuration from CR, TCR, CCR, IR register values
}

$_CHIPNAME.cpu0 configure -event reset-init {
global OCTOSPI1
global OCTOSPI2

mmw 0x52002000 0x00000004 0x0000000B ;# FLASH_ACR: 4 WS for 64MHZ HCLK

mmw 0x58024400 0x00000001 0x00000018 ;# RCC_CR: HSIDIV=1, HSI on
mww 0x58024418 0x00000040 ;# RCC_CDCFGR1: CDCPRE=1, CDPPRE=2, HPRE=1
mww 0x5802441C 0x00000440 ;# RCC_CDCFGR2: CDPPRE2=2, CDPPRE1=2
mww 0x58024420 0x00000040 ;# RCC_SRDCFGR: SRDPPRE=2
mww 0x58024428 0x00404040 ;# RCC_PLLCKSELR: DIVM3=4, DIVM2=4, DIVM1=4, PLLSRC=HSI
mww 0x5802442C 0x01ff0ccc ;# RCC_PLLCFGR: PLLxRGE=8MHz to 16MHz, PLLxVCOSEL=wide
mww 0x58024430 0x01010207 ;# RCC_PLL1DIVR: 64MHz: DIVR1=2, DIVQ1=2, DIVP1=2, DIVN1=8
mww 0x58024438 0x01010207 ;# RCC_PLL2DIVR: 64MHz: DIVR2=2, DIVQ2=2, DIVP2=2, DIVN2=8
mww 0x58024440 0x01010207 ;# RCC_PLL3DIVR: 64MHz: DIVR3=2, DIVQ3=2, DIVP3=2, DIVN3=8
mmw 0x58024400 0x01000000 0 ;# RCC_CR: PLL1ON=1
sleep 1
mmw 0x58024410 0x00000003 0 ;# RCC_CFGR: PLL1 as system clock
sleep 1

adapter speed 4000

if { $OCTOSPI1 } {
octospi_init 0
}
}

修改完成后我们可以烧录一次试试,如果不成功就烧录一下下载算法

下载QSPI算法

去百度或者去反客科技的客服要资料,参考例程里面有下载算法,直接烧录即可(对于hal的烧录下载算法目前无法进行哈)

从外部flash启动

修改板子名_FLASH.ld文件的部分内容,如下所示:

1
2
3
4
5
6
7
8
9
10
MEMORY
{
/* FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K */
FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 8M
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
}

这里是告诉openocd烧录到0x90000000的位置,当然这是qspi规定的哈。

然后修改Core/src/system_stm32h7xx.c的VTOR寄存器位置,这个位置是单片机启动程序的加载位置,大概在299行附近,添加一条语句为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#if defined(DUAL_CORE) && defined(CORE_CM4)
/* Configure the Vector Table location add offset address for cortex-M4 ------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D2 AXI-RAM or in Internal FLASH */
#endif /* USER_VECT_TAB_ADDRESS */

#else
/*
* Disable the FMC bank1 (enabled after reset).
* This, prevents CPU speculation access on this bank which blocks the use of FMC during
* 24us. During this time the others FMC master (such as LTDC) cannot use it!
*/
FMC_Bank1_R->BTCR[0] = 0x000030D2;

/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D1 AXI-RAM or in Internal FLASH */
#endif /* USER_VECT_TAB_ADDRESS */
// 这下面这句话是添加的,意思是从0x90000000处启动
SCB->VTOR = 0x90000000;
#endif /*DUAL_CORE && CORE_CM4*/
}

一定要放在第一级的endif内,然后我们需要重新编译(如果编译过需要重新加载cmake项目或删除编译内容)

结语

能用Clion写H7绝对是一件美事,写了一次Keil之后再也不想写了!


使用openocd、clion开发stm32H7
https://blog.minloha.cn/posts/231326b4062ebd2023081320.html
作者
Minloha
发布于
2023年8月13日
更新于
2024年10月10日
许可协议