目录

ACM32F403RE 国产 MCU 试用笔记

前言

现在很多公司要求应用芯片国产化,于是找来一家国产单片机厂家(上海爱信诺航芯电子科技有限公司(简称:上海航芯)),有幸拿到厂家的一块 MCU 为 ACM32F403RET8 开发板(资料:开发工具/开发板/ACM32F403RET7_NUCLEO_V1.0),用于前期技术验证。目前只是简单试用了一下,没有深入研究,不过其驱动库比 STM32F 单片机简单很多,很容易上手。本文只是记录初次使用时遇到的一些问题,没详细介绍如何使用,关于具体使用方法可参考官方文档。ACM32F403RE 基于 ARMv8-M 架构,支持 Cortex-M33 和 Cortex-M4F 指令集,最高支持 180MHz 系统工作频率,支持浮点运算和 DSP。如此强劲的内核,当然不会“裸跑”,直接上 rt-thread 实时操作运行测试。

基于 rt-thread 的 acm32f4xx-nucleo 工程初次调试

1、安装 IDE 芯片支持包及下载工程

时间2022-03-15
软件Keil MDK V5.33
版本rt-thread v4.1.0-beta
工程rt-thread\bsp\acm32f4xx-nucleo
网址开发工具/IDE支持包/Aisinochip.ACM32F4.Keil.packrt-thread(版本 v4.1.0-beta)
下载安装操作完成后,就可以打开软件工程了。还有一点必须注意:工程配置那里必须重新选择 MCU 型号!

2、安装厂家调试器驱动不成功问题

时间2022-03-15
系统Windows 7 旗舰版
驱动ACM32-在线编程器\USB转SPI-I2C驱动\AisinochipUSBDriver.exe

问题

无法成功安装 AISINOCHIP CMSIS-DAP 调试器驱动:
../img/20220315_001.jpg

解决

1、首先安装 USB 转 SPI-I2C 驱动:ACM32-在线编程器\USB转SPI-I2C驱动\AisinochipUSBDriver.exe
2、再安装 AISINOCHIP CMSIS-DAP 调试器驱动:
../img/20220315_002.jpg

3、编译工程提示有两个函数未定义

时间2022-03-15
软件Keil MDK V5.33
版本rt-thread v4.1.0-beta
工程rt-thread\bsp\acm32f4xx-nucleo

问题

编译工程提示出错:
.\build\keil\ACM32F4XX.axf: Error: L6218E: Undefined symbol System_EnableIAccelerate (referred from system_acm32f4.o).
.\build\keil\ACM32F4XX.axf: Error: L6218E: Undefined symbol HAL_EFlash_Init_Para (referred from hal_eflash.o).

分析

1、未定义System_EnableIAccelerate()函数,应该是缺少System_Accelerate.c文件;
2、未定义HAL_EFlash_Init_Para()函数,应该是缺少HAL_EFlash_EX.c文件;
3、实际上这两个源文件厂家提供的是没开源的.lib库文件,由于 rt-thread 仓库项目过滤规则.gitignore过滤了.lib文件,厂家应该没留意,造成没有推送这两个源文件到 github 远程仓库。

解决

1、从官网下载演示源码 开发工具/SDK驱动库/Nucleo_ModulesDemo_Rev1.0.8
2、复制ModulesDemo_Rev1.0.8\ModulesDemo\Core_Drivers\Device\System_Accelerate.librt-thread\bsp\acm32f4xx-nucleo\libraries\Device\
3、复制ModulesDemo_Rev1.0.8\ModulesDemo\Core_Drivers\HAL_Driver\Src\HAL_EFlash_EX.librt-thread\bsp\acm32f4xx-nucleo\libraries\HAL_Driver\Src\
4、最后把它们加入项目工程:
../img/20220315_003.jpg

4、单步运行与源文件代码对应不上

时间2022-03-16
硬件ACM32F403RET7_NUCLEO_V1.1
软件Keil MDK V5.33
版本rt-thread v4.1.0-beta
工程rt-thread\bsp\acm32f4xx-nucleo

问题

进入调试后,先全速再单步运行代码,发现执行与源文件代码对应不上,貌似执行的是另一源文件另一段代码。

原因

因配置重新选择了另一款调试器,造成调试器相关配置重置。

解决

1、如果使用 CMSIS-DAP 调试器,参考《开发工具/开发板/ACM32F4_FP4_F3系列芯片开发快速上手V0.4.pdf》里面的配置说明;
2、造成上述现象,是因为没勾选:Option for Target → Utilities →Update Target before Debugging选项:
../img/20220315_004.jpg

5、操作系统调试串口不能输入命令

时间2022-03-16
硬件ACM32F403RET7_NUCLEO_V1.1
软件Keil MDK V5.33
版本rt-thread v4.1.0-beta
工程rt-thread\bsp\acm32f4xx-nucleo

问题

rt-thread 系统调试口只能打印数据,不能输入命令。

原因

由于厂家《ACM32F403RET7_NUCLEO_V1.1》开发板的 UART1(PA9、PA10)引脚连接了 ACL16(CMSIS-DAP)调试器芯片,硬件复用冲突。

解决

到《rtconfig.h》修改配置,把调试口移到 UART2(PA2、PA3)即可:
#define RT_CONSOLE_DEVICE_NAME "uart2"
#define BSP_USING_UART2
#define BSP_UART2_RX_USING_DMA(如果屏蔽表示不开 DMA)
#define BSP_UART2_TX_USING_DMA(如果屏蔽表示不开 DMA)

6、操作系统调试串口逻辑结构说明
 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
//<rtconfig.h>配置串行通讯总开关:(由用户配置)
	#define BSP_USING_UART2
	#define BSP_UART2_RX_USING_DMA
	#define BSP_UART2_TX_USING_DMA
	......

//<board.h>定义串口的端口与引脚:(由用户配置)
	#if defined(BSP_USING_UART2)
		#define UART2_TX_PORT           GPIOA
		#define UART2_RX_PORT           GPIOA
		#define UART2_TX_PIN            GPIO_PIN_2
		#define UART2_RX_PIN            GPIO_PIN_3

		#if defined(BSP_UART2_RX_USING_DMA)
			#define UART2_RX_DMA_INSTANCE   DMA_Channel0
			#define UART2_RX_DMA_RCC        BIT12
			#define UART2_RX_DMA_IRQ        DMA_IRQn
	......

//<uart_config.h>串行对象初始值:
	#if defined(BSP_UART2_TX_USING_DMA)
	#if defined(BSP_UART2_RX_USING_DMA)
	#ifndef UART2_DMA_RX_CONFIG
	#define UART2_DMA_RX_CONFIG                                         \
		{                                                               \
			.Instance = UART2_RX_DMA_INSTANCE,                          \
			.dma_rcc  = UART2_RX_DMA_RCC,                               \
			.dma_irq  = UART2_RX_DMA_IRQ,                               \
			.channel  = UART2_RX_DMA_CHANNEL,                           \
			.request  = UART2_RX_DMA_REQUEST,                           \
		}
	#endif /* UART2_DMA_RX_CONFIG */
	#endif /* BSP_UART2_RX_USING_DMA */
	......
	#ifndef UART2_CONFIG
	#define UART2_CONFIG                                                \
		{                                                               \
			.name = "uart2",                                            \
			.Instance = UART2,                                          \
			.irq_type = UART2_IRQn,                                     \
			.enable_id = EN_UART2,                                      \
			.tx_port  = UART2_TX_PORT,                                  \
			.rx_port  = UART2_RX_PORT,                                  \
			.tx_pin   = UART2_TX_PIN,                                   \
			.rx_pin   = UART2_RX_PIN,                                   \
		}
	#endif /* UART2_CONFIG */
	#endif /* BSP_USING_UART2 */
	......

//<drv_uart.c>串行对象初始化:
	static struct acm32_uart_config uart_config[] =
	{
	#ifdef BSP_USING_UART1
		UART1_CONFIG,
	#endif
	#ifdef BSP_USING_UART2
		UART2_CONFIG,
	#endif
	......
	rt_err_t rt_hw_uart_init(void)
	{
		......
		for (int i = 0; i < obj_num; i++)
		{
			uart_obj[i].config          = &uart_config[i];
			......
		}
		......
	}

	......
	acm32_uart_ops = { _uart_configure, ... }
	uart_obj[i].serial.ops = &acm32_uart_ops;
	rt_err_t rt_serial_init() { ... serial->ops->configure(serial, &serial->config) ...}
	_uart_configure(
	HAL_UART_Init(
	......