HC32
(→LP Timer) |
(→Low Power) |
||
| (未显示1个用户的40个中间版本) | |||
| 第1行: | 第1行: | ||
| + | 默认使用'''小端''' (Little Endian) | ||
| + | |||
== Overview == | == Overview == | ||
| 第6行: | 第8行: | ||
| − | * [https://hdsc.com.cn/Category83-1590 HC32D391FEUA-TFN32TR] 192KB RAM,512KB Flash, up to 200MHz Cortex-M4, QFN32 4x4mm, 1.8-3.6V, | + | * [https://hdsc.com.cn/Category83-1590 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工艺 |
| + | |||
| + | |||
* [https://www.hdsc.com.cn/Category83-1499?All=1 HC32F4A0PITB-LQFP100] 516KB RAM, 2048KB Flash, up to 240MHz Cotex-M4, LQFP100 14x14mm [https://www.hdsc.com.cn/Category82?All=1 All] | * [https://www.hdsc.com.cn/Category83-1499?All=1 HC32F4A0PITB-LQFP100] 516KB RAM, 2048KB Flash, up to 240MHz Cotex-M4, LQFP100 14x14mm [https://www.hdsc.com.cn/Category82?All=1 All] | ||
* [https://hdsc.com.cn/Category83-1501 HC32F4A0SGHB-VFBGA176] 516KB RAM, 1024KB Flash, up to 240MHz Cortex-M4, VFBGA176 10×10mm, 1.8-3.6V, USB, CAN, I2S, SDIO | * [https://hdsc.com.cn/Category83-1501 HC32F4A0SGHB-VFBGA176] 516KB RAM, 1024KB Flash, up to 240MHz Cortex-M4, VFBGA176 10×10mm, 1.8-3.6V, USB, CAN, I2S, SDIO | ||
| 第14行: | 第18行: | ||
* [http://product.sitimechina.com/uploadfile/images/202103/202103231149138817.pdf SiT1630] <-----> SiT1533 | * [http://product.sitimechina.com/uploadfile/images/202103/202103231149138817.pdf SiT1630] <-----> SiT1533 | ||
* [http://product.sitimechina.com/product_list.php?id=1 32.768KHz 抗振动] | * [http://product.sitimechina.com/product_list.php?id=1 32.768KHz 抗振动] | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
<br><br> | <br><br> | ||
== HC32L130F8UA == | == HC32L130F8UA == | ||
| + | |||
| + | 更抗灰、抗潮的封装: HC32L130E8PA (TSSOP-28, 10x7mm), HC32L130J8TA (LQFP-48, 7x7mm) | ||
* Cortex-M0+, Up to 48MHz | * Cortex-M0+, Up to 48MHz | ||
| 第177行: | 第105行: | ||
** libstdc++.a | ** libstdc++.a | ||
** libm.a | ** libm.a | ||
| + | |||
| + | <br> | ||
| + | |||
| + | === Debug === | ||
| + | |||
| + | 查看生成的变量地址: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ ../../../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 | ||
| + | </source> | ||
| + | |||
| + | 查看 .data .bss 段大小: | ||
| + | <source lang=bash> | ||
| + | $ ../../../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 | ||
| + | </source> | ||
| + | |||
| + | * .data:初始值存储在 Flash 中,启动时复制到 RAM | ||
| + | * .bss:只需要记录大小信息,不需要在 Flash 中存储 0 值。(Block Started by Symbol)段存放: | ||
| + | ** '''未初始化'''的'''全局变量''' | ||
| + | ** '''未初始化'''的静态变量 | ||
| + | ** '''初始化为 0''' 的变量(包括静态变量) | ||
| + | |||
| + | <source lang=bash> | ||
| + | FLASH 存储器: | ||
| + | +---------------+ | ||
| + | | .text (代码) | | ||
| + | +---------------+ | ||
| + | | .rodata (常量)| | ||
| + | +---------------+ | ||
| + | | .data (初始值)| | ||
| + | +---------------+ | ||
| + | | ... | | ||
| + | +---------------+ | ||
| + | |||
| + | RAM 存储器: | ||
| + | +---------------+ | ||
| + | | .data (副本) | ← 从 Flash 复制过来 | ||
| + | +---------------+ | ||
| + | | .bss | ← 启动时清零 | ||
| + | +---------------+ | ||
| + | | 堆 (heap) | | ||
| + | +---------------+ | ||
| + | | 栈 (stack) | | ||
| + | +---------------+ | ||
| + | </source> | ||
| + | |||
<br> | <br> | ||
=== Uploader === | === Uploader === | ||
| + | |||
| + | ==== J-Link ==== | ||
| + | |||
| + | 从 https://github.com/hdscmcu/pack 获取 HDSC.HC32L130.1.0.1.pack,这是个 zip 包,改名为 L130.zip 后 unzip 解压: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ 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 | ||
| + | </source> | ||
| + | |||
| + | 将 FlashHC32L130_64K.FLM 改名为 HC32L130_64K.FLM,放在: | ||
| + | <source lang=bash> | ||
| + | $ find /c/Program\ Files\ \(x86\)/SEGGER/JLink/Devices/HDSC/ | ||
| + | /c/Program Files (x86)/SEGGER/JLink/Devices/HDSC/HC32L130_64K.FLM | ||
| + | </source> | ||
| + | |||
| + | |||
| + | /c/Program\ Files\ \(x86\)/SEGGER/JLink/JLinkDevices.xml 增加: | ||
| + | |||
| + | <source lang=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> | ||
| + | </source> | ||
| + | |||
| + | 则可使用 J-Flash 烧写: | ||
| + | |||
| + | * MCU 选 HC32L130,SWD 4000KHz | ||
| + | * Target -> Connect | ||
| + | * Target -> Production Programming(快捷键 F7) | ||
| + | * Target -> Manual Programming -> Start Application(快捷键 F9) | ||
| + | |||
| + | |||
| + | JLink 命令行方式: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ 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. | ||
| + | </source> | ||
| + | |||
| + | 或者: | ||
| + | <source lang=bash> | ||
| + | $ cat up.cmd | ||
| + | device HC32L130 | ||
| + | si SWD | ||
| + | speed 4000 | ||
| + | connect | ||
| + | erase | ||
| + | loadfile build/main.hex | ||
| + | r | ||
| + | exit | ||
| + | |||
| + | $ /c/SEGGER/JLink/JLink.exe -CommanderScript ./up.cmd | ||
| + | </source> | ||
| + | |||
| + | <br> | ||
==== UART ==== | ==== UART ==== | ||
| 第188行: | 第325行: | ||
<br> | <br> | ||
| − | ==== STLINK | + | ==== STLINK ==== |
* [http://www.51hei.com/bbs/dpj-194723-1.html pyOCD] | * [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> | <br> | ||
| 第236行: | 第377行: | ||
<br> | <br> | ||
| + | |||
| + | == Bare Metal == | ||
| + | |||
| + | === Reset Handler === | ||
| + | |||
| + | hc32/variants/hc32l130f8ua/hc32l130f8ua.ld (Link Script) : | ||
| + | |||
| + | <source lang=python> | ||
| + | ENTRY(Reset_Handler) | ||
| + | |||
| + | SECTIONS | ||
| + | { | ||
| + | .text : | ||
| + | { | ||
| + | KEEP(*(.vectors)) | ||
| + | __Vectors_End = .; | ||
| + | __Vectors_Size = __Vectors_End - __Vectors; | ||
| + | __end__ = .; | ||
| + | *(.text*) | ||
| + | ...... | ||
| + | ...... | ||
| + | </source> | ||
| + | |||
| + | hc32/common/startup_hc32l13x.c: | ||
| + | |||
| + | <source lang=cpp> | ||
| + | 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(); | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | <br> | ||
| + | |||
| + | === SystemInit() === | ||
| + | |||
| + | '''位于 hc32/common/system_hc32l13x.c:''' | ||
| + | |||
| + | <source lang=cpp> | ||
| + | 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(); | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | <br> | ||
| + | |||
| + | === Makefile === | ||
| + | |||
| + | <source lang=bash> | ||
| + | -D__START=main | ||
| + | </source> | ||
| + | |||
| + | <br> | ||
| + | |||
== SystemInit() == | == SystemInit() == | ||
| 第253行: | 第473行: | ||
<br> | <br> | ||
| − | === 系统时钟 === | + | === 系统时钟 (SystemClk) === |
HC32L13x 支持以下五种时钟源作为系统时钟: | HC32L13x 支持以下五种时钟源作为系统时钟: | ||
| 第277行: | 第497行: | ||
内部高速时钟 RCH 从启动到稳定仅需 4us。为了在深度休眠模式下能快速响应中断,建议进入深度休眠模式前将系统时钟切换为 RCH。 | 内部高速时钟 RCH 从启动到稳定仅需 4us。为了在深度休眠模式下能快速响应中断,建议进入深度休眠模式前将系统时钟切换为 RCH。 | ||
| + | |||
| + | RCL 默认启用 RCL_CR_TRIM_32768_VAL (32.768kHz),可通过设置 RCL_CR 其为 RCL_CR_TRIM_38400_VAL (38.4kHz) | ||
| + | |||
| + | <br> | ||
| + | |||
| + | === HCLK 时钟 === | ||
| + | |||
| + | 主供 CPU 核心。位于SYSCTRL 的 SYSCTRL0 寄存器 | ||
| + | |||
| + | '''HCLK 时钟来源选择:''' | ||
| + | |||
| + | <pre> | ||
| + | 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 | ||
| + | </pre> | ||
| + | |||
| + | <br> | ||
| + | |||
| + | === PCLK 时钟 === | ||
| + | |||
| + | 主供外设。位于SYSCTRL 的 SYSCTRL0 寄存器 | ||
| + | |||
| + | '''PCLK 时钟来源选择:''' | ||
| + | <pre> | ||
| + | 00: HCLK /* reset value */ | ||
| + | 01: HCLK/2 | ||
| + | 10: HCLK/4 | ||
| + | 11: HCLK/8 | ||
| + | </pre> | ||
| + | |||
<br> | <br> | ||
| 第358行: | 第614行: | ||
* 中断状态寄存器 Px_STAT 地址分别为: 0x200, 0x240, 0x280, 0x2C0 (PA_STAT, PB_STAT, PC_STAT, PD_STAT) | * 中断状态寄存器 Px_STAT 地址分别为: 0x200, 0x240, 0x280, 0x2C0 (PA_STAT, PB_STAT, PC_STAT, PD_STAT) | ||
* 中断清除寄存器 Px_ICLR 地址分别为: 0x210, 0x250, 0x290, 0x2D0 | * 中断清除寄存器 Px_ICLR 地址分别为: 0x210, 0x250, 0x290, 0x2D0 | ||
| + | |||
| + | <br> | ||
| + | |||
| + | == Low Power == | ||
| + | |||
| + | === __WFI() === | ||
| + | |||
| + | Wait For Interrupt, 指令执行后,MCU 挂起,直到下一个中断出现。。。 | ||
| + | |||
| + | <source lang=cpp> | ||
| + | /* Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs */ | ||
| + | __attribute__((always_inline)) __STATIC_INLINE void __WFI(void) | ||
| + | { | ||
| + | __ASM volatile ("wfi"); | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | 中断出现、继续执行,下一条指令位于 __WFI() 之后,即返回 wfi 指令之所在 | ||
| + | |||
| + | <br> | ||
| + | |||
| + | === Sleep Mode === | ||
| + | |||
| + | CPU 核心不运行,其他外设都运行,aeco-goxp v1.2 约 200uA | ||
| + | |||
| + | <source lang=cpp> | ||
| + | void Lpm_GotoSleep(boolean_t bOnExit) | ||
| + | { | ||
| + | SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; | ||
| + | SCB->SCR |= 1u<<bOnExit; | ||
| + | __WFI(); | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | <br> | ||
| + | |||
| + | === DeepSleep Mode === | ||
| + | |||
| + | 少量外设运行,aeco-goxp v1.2 约 2uA | ||
| + | |||
| + | * XTL | ||
| + | * RCL | ||
| + | * RESET | ||
| + | * WDT | ||
| + | * RTC | ||
| + | * LPUART0-1 | ||
| + | * GPIO | ||
| + | * VC0-1 | ||
| + | |||
| + | * CLKTRIM | ||
| + | * LPTIM | ||
| + | * POR/BOR | ||
| + | * PCNT | ||
| + | * LVD | ||
| + | * LCD | ||
| + | |||
| + | <source lang=cpp> | ||
| + | void Lpm_GotoDeepSleep(boolean_t bOnExit) | ||
| + | { | ||
| + | SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; | ||
| + | SCB->SCR |= 1u<<bOnExit; | ||
| + | __WFI(); | ||
| + | } | ||
| + | </source> | ||
<br> | <br> | ||
| 第382行: | 第702行: | ||
Low Power Timer 低功耗计时器 | Low Power Timer 低功耗计时器 | ||
| − | * | + | LPTimer 的定时器支持两种工作模式,通过设置定时器控制寄存器(CR)中 MD 选择工作模式: |
| − | * | + | * 模式 1 为 16 bit 自由计数模式 |
| + | * 模式 2 是 16 bit 重载模式 | ||
| + | |||
| + | LPTimer 启动时会自动装载重载寄存器 ARR 的值到计数器中。 | ||
| + | |||
| + | |||
| + | * '''计数功能''':用于测定某个事件发生的次数。计数到最大值会溢出并且产生中断。计数器在每个相应的输入时钟的下降沿累加一次。输入信号被内部的计数时钟采样,因此外部输入时钟频率不能超过系统的计数时钟。 | ||
| + | * '''定时功能''':用于产生间隔定时。在定时功能中,定时器一个时钟累加一次,计数到最大值会溢出并且产生中断。 | ||
<br> | <br> | ||
2026年1月16日 (五) 15:26的最后版本
默认使用小端 (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
- SiT1630 <-----> SiT1533
- 32.768KHz 抗振动
[编辑] 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 / 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 最小系统
[编辑] 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)
JLink 命令行方式:
$ 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.
或者:
$ cat up.cmd device HC32L130 si SWD speed 4000 connect erase loadfile build/main.hex r exit $ /c/SEGGER/JLink/JLink.exe -CommanderScript ./up.cmd
[编辑] 5.3.2 UART
[编辑] 5.3.3 STLINK
- https://www.cnblogs.com/milton/p/16586831.html
- https://github.com/IOsetting/hc32l110-template
- https://gitcode.com/open-source-toolkit/8cb1a
[编辑] 5.4 Linker Script
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)的初始值位于第一个入口:
中断号定义于 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 Low Power
[编辑] 11.1 __WFI()
Wait For Interrupt, 指令执行后,MCU 挂起,直到下一个中断出现。。。
/* Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs */
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
中断出现、继续执行,下一条指令位于 __WFI() 之后,即返回 wfi 指令之所在
[编辑] 11.2 Sleep Mode
CPU 核心不运行,其他外设都运行,aeco-goxp v1.2 约 200uA
void Lpm_GotoSleep(boolean_t bOnExit)
{
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
SCB->SCR |= 1u<<bOnExit;
__WFI();
}
[编辑] 11.3 DeepSleep Mode
少量外设运行,aeco-goxp v1.2 约 2uA
- XTL
- RCL
- RESET
- WDT
- RTC
- LPUART0-1
- GPIO
- VC0-1
- CLKTRIM
- LPTIM
- POR/BOR
- PCNT
- LVD
- LCD
void Lpm_GotoDeepSleep(boolean_t bOnExit)
{
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
SCB->SCR |= 1u<<bOnExit;
__WFI();
}
[编辑] 12 UART
《HC32L130 / HC32L136 / HC32F030 系列硬件开发指南》:
- PA09 --- UART0_TX
- PA10 --- UART0_RX
[编辑] 13 I2C
[编辑] 14 SPI
[编辑] 15 LP Timer
Low Power Timer 低功耗计时器
LPTimer 的定时器支持两种工作模式,通过设置定时器控制寄存器(CR)中 MD 选择工作模式:
- 模式 1 为 16 bit 自由计数模式
- 模式 2 是 16 bit 重载模式
LPTimer 启动时会自动装载重载寄存器 ARR 的值到计数器中。
- 计数功能:用于测定某个事件发生的次数。计数到最大值会溢出并且产生中断。计数器在每个相应的输入时钟的下降沿累加一次。输入信号被内部的计数时钟采样,因此外部输入时钟频率不能超过系统的计数时钟。
- 定时功能:用于产生间隔定时。在定时功能中,定时器一个时钟累加一次,计数到最大值会溢出并且产生中断。
[编辑] 16 RTC
[编辑] 17 ADC
HC32L130F8UA 含有 8 个 12bit ADC
https://bbs.21ic.com/icview-2817282-1-1.html
[编辑] 18 Reference
- https://www.hdsc.com.cn/list/71/35.htm
- https://hdsc.com.cn/cn/index/listView/catid/94/cdk/56a757q!57yW56iL
- HC32L130_HC32L136系列数据手册Rev1.9.pdf
- HC32L130_硬件开发指南.pdf
- HC32L130_HC32L136系列用户手册Rev2.31.pdf
- "Bare Metal" STM32 Programming
- Memory Layout of C Programs


