HC32

来自Jack's Lab
2026年1月16日 (五) 11:43Comcat (讨论 | 贡献)的版本

跳转到: 导航, 搜索

默认使用小端 (Little Endian)

目录

1 Overview


  • HC32D391FEUA-TFN32TR 192KB RAM,512KB Flash, up to 200MHz Cortex-M4, QFN32 4x4mm, 1.8-3.6V, 数据计算单元(Data Computing Unit),USB 2.0fs, I2S, 40nm eFlashULP工艺


  • HC32F4A0PITB-LQFP100 516KB RAM, 2048KB Flash, up to 240MHz Cotex-M4, LQFP100 14x14mm All
  • HC32F4A0SGHB-VFBGA176 516KB RAM, 1024KB Flash, up to 240MHz Cortex-M4, VFBGA176 10×10mm, 1.8-3.6V, USB, CAN, I2S, SDIO
  • HC32F4A0SIHB-VFBGA176 516KB RAM, 2048KB Flash, up to 240MHz Cortex-M4, VFBGA176 10×10mm, 1.8-3.6V, USB, CAN, I2S, SDIO




2 HC32L130F8UA

更抗灰、抗潮的封装: HC32L130E8PA (TSSOP-28, 10x7mm), HC32L130J8TA (LQFP-48, 7x7mm)

  • Cortex-M0+, Up to 48MHz
  • 8KB RAM, 64KB Flash
  • UART x2, LPUART x1, SPI x1, I2C x2, PWM x10
  • AES-128, TRNG
  • 0.9μA @3V 深度休眠模式+ RTC 工作
  • 130μA/MHz@3V@24MHz 工作模式:CPU 和外设运行,从 Flash 运行程序
  • -40 ~ 85 'C
  • 1.8 ~ 5.5V
  • QFN32, 4x4mm

HC32L130-QFN32.png


引脚规划参考官方文档:《HC32L130 / HC32L136 / HC32F030 系列硬件开发指南》


  • PB0 - AIN8/VC0_INN10/VC1_INN6/SEG13
  • PB1 - AIN9/EXVREF/VC1_INP6/VC1_INN7/SEG12
  • PB6 - I2C0_SCL (SEL1)
  • PB7 - I2C0_SDA (SEL1)


  • PA04 - SPI0_CS (SEL1)
  • PA05 - SPI0_CLK (SEL1)
  • PA06 - SPI0_MISO (SEL1)
  • PA07 - SPI0_MOSI (SEL1)
  • PA09 - UART0_TXD (SEL1)
  • PA10 - UART0_RXD (SEL1)
  • PA14 - UART0_TXD (SEL2) - SWCLK
  • PA13 - UART0_RXD (SEL2) - SWDIO


  • PB0/PB1, PB4/PB5: I2C1
  • PD0/PD1 as UART1_TX/RX (SEL3) ------------------------> M_RX / M_TX


3 最小系统

HC32L130-mini-sys.png


4 MODE (模式) PIN

在正常情况下,必须通过电阻(推荐 10KΩ)将 MODE Pin (PD03/MD)下拉到 GND。

  • MODE (PD03)为高电平时,Power Reset 或硬件 Reset,则芯片进入在线编程模式(如加上跳帽使 MODE Pin 置位于高电平),通过上位机可以进行在线编程;
  • MODE (PD03)为低电平时,芯片进入用户模式。

PD03/MD 用户可用作输入端口,但是在 NRST 有效期间(即 RESETB 为低电平期间)必须保持低电平,否则 NRST 解除后(即 RESETB 变为高电平),芯片会误进入在线编程模式(Boot Mode)。


  • 当复位时 BOOT0(PD03)管脚为高电平,芯片工作于 ISP 编程模式,可通过 ISP 协议对 Flash 进行编程。
  • 当复位时 BOOT0(PD03)管脚为低电平,芯片工作于用户模式,芯片执行 Flash 内的程序代码,可通过 SWD 协议对 Flash 进行编程。


注意:

- 建议预留 PA9、PA10 作为 ISP 编程接口,如需使用 PA13、PA14 作为 ISP 编程接口请参见 PCN:PCN20191230-1_HC32L130HC32F030HC32L136 提高烧录速度。


5 Toolchain

5.1 Compier

  • toolchain/gcc-arm-none-eabi/bin/
    • arm-none-eabi-gcc
    • arm-none-eabi-g++
    • arm-none-eabi-gdb


  • toolchain/gcc-arm-none-eabi/arm-none-eabi/lib/thumb/v6-m/
    • libc.a
    • libstdc++.a
    • libm.a


5.2 Debug

查看生成的变量地址:

$ ../../../toolchain/gcc-arm-none-eabi/bin/arm-none-eabi-nm -n build/main.elf  | grep k
00000108 T _Z15key_irq_handlerv
00000190 T SystemCoreClockUpdate
000001a0 T systick_init
00000368 W _sbrk
000003a0 T _kill
000003d0 T _lseek
000003f0 T _link
00000958 T Sysctrl_GetHClkFreq
00000a78 T Sysctrl_GetPClkFreq
00000b2c T SysTick_Handler
0000144c T _sbrk_r
00001470 T __malloc_lock
00001472 T __malloc_unlock
00001498 t .udivsi3_skip_div0_test
000015ac t .divsi3_skip_div0_test
20000000 D SystemCoreClock
20000004 d _tx_ok
20000094 B k
200001a8 b secTicks
200001b0 B __malloc_sbrk_start
200001b4 B msTicks_cnt
200001b8 B msTicks
200005c0 ? stack
20001c00 A __StackLimit
20002000 A __stack
20002000 B __StackTop

查看 .data .bss 段大小:

$ ../../../toolchain/gcc-arm-none-eabi/bin/arm-none-eabi-size.exe build/main.elf
   text    data     bss     dec     hex filename
   9740     124     324   10188    27cc build/main.elf

set the global var 'int k = 0':
$ ../../../toolchain/gcc-arm-none-eabi/bin/arm-none-eabi-size.exe build/main.elf
   text    data     bss     dec     hex filename
   9760     120     328   10208    27e0 build/main.elf
  • .data:初始值存储在 Flash 中,启动时复制到 RAM
  • .bss:只需要记录大小信息,不需要在 Flash 中存储 0 值。(Block Started by Symbol)段存放:
    • 未初始化全局变量
    • 未初始化的静态变量
    • 初始化为 0 的变量(包括静态变量)
FLASH 存储器:
    +---------------+
    | .text (代码)  |
    +---------------+
    | .rodata (常量)|
    +---------------+
    | .data (初始值)|
    +---------------+
    | ...           |
    +---------------+

RAM 存储器:
    +---------------+
    | .data (副本)  | ← 从 Flash 复制过来
    +---------------+
    | .bss          | ← 启动时清零
    +---------------+
    | 堆 (heap)     |
    +---------------+
    | 栈 (stack)    |
    +---------------+



5.3 Uploader

5.3.1 J-Link

https://github.com/hdscmcu/pack 获取 HDSC.HC32L130.1.0.1.pack,这是个 zip 包,改名为 L130.zip 后 unzip 解压:

$ find .
./Device/Include/HC32L130E8PA.h
./Device/Include/HC32L130F8UA.h
./Device/Include/HC32L130J8TA.h
./Device/Include/system_hc32l130.h
./Device/Source/ARM/startup_hc32l130.s
./Device/Source/main.c
./Device/Source/system_hc32l130.c
./Flash/FlashHC32L130_64K.FLM
./HDSC.HC32L130.pdsc    # XML 描述文件
./SVD/HC32L130E8PA.sfr
./SVD/HC32L130F8UA.sfr
./SVD/HC32L130J8TA.sfr

将 FlashHC32L130_64K.FLM 改名为 HC32L130_64K.FLM,放在:

  
$ find /c/Program\ Files\ \(x86\)/SEGGER/JLink/Devices/HDSC/
/c/Program Files (x86)/SEGGER/JLink/Devices/HDSC/HC32L130_64K.FLM


/c/Program\ Files\ \(x86\)/SEGGER/JLink/JLinkDevices.xml 增加:

  <!-- Huada (HDSC) -->
  <Device>
    <ChipInfo Vendor="HDSC" Name="HC32L110x4"  WorkRAMAddr="0x20000000" WorkRAMSize="0x800" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash_16K" BaseAddr="0x0" MaxSize="0x4000" Loader="Devices/HDSC/HC32L110B4_C4.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
  <Device>
    <ChipInfo Vendor="HDSC" Name="HC32L110x6"  WorkRAMAddr="0x20000000" WorkRAMSize="0x1000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash_32K" BaseAddr="0x0" MaxSize="0x8000" Loader="Devices/HDSC/HC32L110B6_C6.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>
  <Device>
    <ChipInfo Vendor="HDSC" Name="HC32L130"  WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/>
    <FlashBankInfo Name="Flash_64K" BaseAddr="0x0" MaxSize="0x10000" Loader="Devices/HDSC/HC32L130_64K.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
  </Device>

则可使用 J-Flash 烧写:

  • MCU 选 HC32L130,SWD 4000KHz
  • Target -> Connect
  • Target -> Production Programming(快捷键 F7)
  • Target -> Manual Programming -> Start Application(快捷键 F9)

命令行方式:

$ cat  ../../toolchain/jlink-flash.cmd
erase
loadfile build/main.hex
r
exit

$ /c/SEGGER/JLink/JLink.exe -device HC32L130 -if swd -speed 4000 -CommanderScript ../../toolchain/jlink-flash.cmd
SEGGER J-Link Commander V6.72c (Compiled May  8 2020 17:22:54) DLL version V6.72c, compiled May  8 2020 17:21:59

J-Link Command File read successfully.
Processing script file...

J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: J-Link V9 compiled Dec 13 2019 11:14:50
Hardware version: V9.30
S/N: 36310083
License(s): RDI, GDB, FlashDL, FlashBP, JFlash
VTref=3.300V
Target connection not established yet but required for command.
Device "HC32L130" selected.

Connecting to target via SWD
Found SW-DP with ID 0x0BC11477
Unknown DP version. Assuming DPv0
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x04770031)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410CC601. Implementer code: 0x41 (ARM)
Found Cortex-M0 r0p1, Little endian.
FPUnit: 4 code (BP) slots and 0 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB008 SCS
ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 000BB00A DWT
ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 000BB00B FPB
Cortex-M0 identified.
Erasing device...
J-Link: Flash download: Total time needed: 0.189s (Prepare: 0.110s, Compare: 0.000s, Erase: 0.075s, Program: 0.000s, Verify: 0.000s, Restore: 0.003s)
Erasing done.

Downloading file [build/main.hex]...
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (10752 bytes)
J-Link: Flash download: Total time needed: 1.095s (Prepare: 0.017s, Compare: 0.134s, Erase: 0.299s, Program: 0.570s, Verify: 0.060s, Restore: 0.012s)
O.K.

Reset delay: 0 ms
Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.

Script processing completed.
<br>

==== UART ====

* https://github.com/kicer/hc32flash

<br>

==== STLINK ====

* [http://www.51hei.com/bbs/dpj-194723-1.html pyOCD]

* https://www.cnblogs.com/milton/p/16586831.html
* https://github.com/IOsetting/hc32l110-template
* https://gitcode.com/open-source-toolkit/8cb1a

<br>

=== Linker Script ===

<source lang=python>
MEMORY
{
    FLASH ( rx )      : ORIGIN = 0x00000000, LENGTH = 64K
    RAM ( rxw )       : ORIGIN = 0x20000000, LENGTH = 8K
}

.vectors (Vector Table) 位于 Flash 开始处,Flash 上代码段 .text 之前:

ENTRY(Reset_Handler)

SECTIONS
{
  .text :
  {
    KEEP(*(.vectors))
    __Vectors_End = .;
    __Vectors_Size = __Vectors_End - __Vectors;
    __end__ = .;
......
......

arch/hc32/common/startup_hc32l13x.c:

/*----------------------------------------------------------------------------
  Exception / Interrupt Vector table
 *----------------------------------------------------------------------------*/
const pFunc __Vectors[] __attribute__ ((section(".vectors"))) = {
    /* Cortex-M Exception Handlers */
    (pFunc)&__StackTop,                       /*      Initial Stack Pointer     */
    Reset_Handler,                            /*      Reset Handler             */
......
......


6 Bare Metal

6.1 Reset Handler

hc32/variants/hc32l130f8ua/hc32l130f8ua.ld (Link Script) :

ENTRY(Reset_Handler)

SECTIONS
{
  .text :
  {
    KEEP(*(.vectors))
    __Vectors_End = .;
    __Vectors_Size = __Vectors_End - __Vectors;
    __end__ = .;
    *(.text*)
......
......

hc32/common/startup_hc32l13x.c:

void Reset_Handler(void) {

    uint32_t *pSrc, *pDest;
    uint32_t *pTable __attribute__((unused));

    SystemInit();

    /*
     * Single section scheme.
     *
     *  The ranges of copy from/to are specified by following symbols
     *    __etext: LMA of start of the section to copy from. Usually end of text
     *    __data_start__: VMA of start of the section to copy to
     *    __data_end__: VMA of end of the section to copy to
     *
     *  All addresses must be aligned to 4 bytes boundary.
    */
    pSrc  = &__etext;
    pDest = &__data_start__;

    for ( ; pDest < &__data_end__ ; ) {
        *pDest++ = *pSrc++;
    }
    __START();
}


6.2 SystemInit()

位于 hc32/common/system_hc32l13x.c:

void SystemInit(void)
{
    M0P_SYSCTRL->RCL_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C22ul)));
    M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C08ul)));
    SystemCoreClockUpdate();
    _HidePinInit();
}


6.3 Makefile

-D__START=main



7 SystemInit()

位于 hc32/common/system_hc32l13x.c:

void SystemInit(void)
{
    M0P_SYSCTRL->RCL_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C22ul)));
    M0P_SYSCTRL->RCH_CR_f.TRIM = (*((volatile uint16_t*) (0x00100C08ul)));
    SystemCoreClockUpdate();
    _HidePinInit();
}


7.1 系统时钟 (SystemClk)

HC32L13x 支持以下五种时钟源作为系统时钟:

SysctrlClkRCH  = 0u,       // 内部 RC 高速时钟,输出频率为 4~24MHz
SysctrlClkXTH  = 1u,       // 外部晶振高速时钟,XTH 可以不接晶振,直接从 PD00 引脚输入 4~32MHz 的时钟信号
SysctrlClkRCL  = 2u,       // 内部 RC 低速时钟,可选频率:38.4K 与 32.768K。当系统进入 DeepSleep,此低速时钟不会自动关闭,超低功耗外设模块可以选择 RCL 作为其时钟。
SysctrlClkXTL  = 3u,       // 外部晶振低速时钟,XTL 可以不接晶振,直接从 PC14 引脚输入 32.768KHz 的时钟信号。当系统进入 Deep Sleep,此低速时钟不会自动关闭。超低功耗模式下工作的
                           // 外设模块可以选择 XTL 作为其时钟。
SysctrlClkPLL  = 4u,       // 锁相环 PLL 时钟


还有两个辅助时钟:

  • 内部低速 10K 时钟;仅供 WatchDog 和 CLKTRIM 模块使用。
  • 内部 150K 时钟:仅供 LVD 和 VC 模块使用。


芯片上电或复位后的默认时钟源为 4MHz 的内部 RCH 时钟;当系统进入 Deep Sleep,此高速时钟会自动关闭。

更改寄存器 RCH_CR[10:0]的数值即可调整 RCH 的输出频率。寄存器数值每增加 1 则 RCH 的输出频率增加约 0.2%,总调整范围为 4~24MHz。更改 RCH 输出频率需要按照特定的更改时序,详见系统时钟切换章节。

内部高速时钟 RCH 从启动到稳定仅需 4us。为了在深度休眠模式下能快速响应中断,建议进入深度休眠模式前将系统时钟切换为 RCH。

RCL 默认启用 RCL_CR_TRIM_32768_VAL (32.768kHz),可通过设置 RCL_CR 其为 RCL_CR_TRIM_38400_VAL (38.4kHz)


7.2 HCLK 时钟

主供 CPU 核心。位于SYSCTRL 的 SYSCTRL0 寄存器

HCLK 时钟来源选择:

000: SystemClk         /* reset value */
001: SystemClk/2 
010: SystemClk/4 
011: SystemClk/8 
100: SystemClk/16 
101: SystemClk/32 
110: SystemClk/64 
111: SystemClk/128 


7.3 PCLK 时钟

主供外设。位于SYSCTRL 的 SYSCTRL0 寄存器

PCLK 时钟来源选择:

00: HCLK         /* reset value */
01: HCLK/2 
10: HCLK/4 
11: HCLK/8



8 SysTick 定时器

SysTick 为 24 位的定时器,向下计数。定时器的计数减到 0 后,就会重新装载一个可编程的数值,同时产生 SysTick 异常(异常编号为 15)


9 GPIO

MCU 的 GPIO 是通过 CMOS 的 PMOS 输出高电平,NMOS 输出低电平。

内部上拉电阻也是一个 PMOS,引脚输出时,PMOS 或 NMOS 工作在线性区域,其等效导通电阻随着 MCU 的 VCC 变化而变化。到 MCU 工作下限电压附近时,其导通电阻会急剧变化,表象上看就是驱动能力急剧下降,上拉电阻也变大


芯片复位后端口为高阻输入,目的是防止芯片被异常复位时,对外部器件产生异常动作。但为了避免高阻输入而产生的漏电,用户要在芯片启动之后对端口进行相应的配置(配置成内部拉高/拉低输入或者输出)。


10 Interrupt

嵌套向量中断控制器 (NVIC) ,支持 32 个外部中断请求(IRQ), 1 个不可屏蔽中断(NMI)

Cortex-M0+ 的中断向量表,位于存储器空间的开始位置,注意主栈指针(MSP)的初始值位于第一个入口:

Cortex-m0plus-int-vec-table.png


中断号定义于 arch/hc32/common/hc32l13x.h:

/* Interrupt Number Definition */
typedef enum IRQn
{
    NMI_IRQn            = -14, /*  2 Non Maskable                            */
    HardFault_IRQn      = -13, /*  3 Hard Fault                              */
    SVC_IRQn            = -5,  /* 11 SV Call                                 */
    PendSV_IRQn         = -2,  /* 14 Pend SV                                 */
    SysTick_IRQn        = -1,  /* 15 System Tick                             */

    PORTA_IRQn          = 0 ,
    PORTB_IRQn          = 1 ,
    PORTC_IRQn          = 2 ,
    PORTD_IRQn          = 3 ,
    DMAC_IRQn           = 4 ,
    TIM3_IRQn           = 5 ,
    UART0_IRQn          = 6 ,
    UART1_IRQn          = 7 ,
    LPUART0_IRQn        = 8 ,
    LPUART1_IRQn        = 9 ,
    SPI0_IRQn           = 10,
    SPI1_IRQn           = 11,
    I2C0_IRQn           = 12,
    I2C1_IRQn           = 13,
    TIM0_IRQn           = 14,
    TIM1_IRQn           = 15,
    TIM2_IRQn           = 16,
    LPTIM_IRQn          = 17,
    ADTIM4_IRQn         = 18,
    ADTIM5_IRQn         = 19,
    ADTIM6_IRQn         = 20,
    PCA_IRQn            = 21,
    WDT_IRQn            = 22,
    RTC_IRQn            = 23,
    ADC_IRQn            = 24,
    PCNT_IRQn           = 25,
    VC0_IRQn            = 26,
    VC1_IRQn            = 27,
    LVD_IRQn            = 28,
    LCD_IRQn            = 29,
    FLASH_RAM_IRQn      = 30,
    CLKTRIM_IRQn        = 31,
} IRQn_Type;

PortA, B, C, D 为 GPIO 中断处理入口

四个口的对应寄存器:

  • 中断状态寄存器 Px_STAT 地址分别为: 0x200, 0x240, 0x280, 0x2C0 (PA_STAT, PB_STAT, PC_STAT, PD_STAT)
  • 中断清除寄存器 Px_ICLR 地址分别为: 0x210, 0x250, 0x290, 0x2D0


11 UART

《HC32L130 / HC32L136 / HC32F030 系列硬件开发指南》:

  • PA09 --- UART0_TX
  • PA10 --- UART0_RX


12 I2C


13 SPI


14 LP Timer

Low Power Timer 低功耗计时器

LPTimer 的定时器支持两种工作模式,通过设置定时器控制寄存器(CR)中 MD 选择工作模式:

  • 模式 1 为 16 bit 自由计数模式
  • 模式 2 是 16 bit 重载模式

LPTimer 启动时会自动装载重载寄存器 ARR 的值到计数器中。


  • 计数功能:用于测定某个事件发生的次数。计数到最大值会溢出并且产生中断。计数器在每个相应的输入时钟的下降沿累加一次。输入信号被内部的计数时钟采样,因此外部输入时钟频率不能超过系统的计数时钟。
  • 定时功能:用于产生间隔定时。在定时功能中,定时器一个时钟累加一次,计数到最大值会溢出并且产生中断。


15 RTC


16 ADC

HC32L130F8UA 含有 8 个 12bit ADC

https://bbs.21ic.com/icview-2817282-1-1.html


17 Reference


个人工具
名字空间

变换
操作
导航
工具箱