[综合信息] 华大 MCU 之一 HC32F460 替换 STM32F411 移植记录

[复制链接]
2512|38
 楼主| 我爱台妹mmd 发表于 2021-11-29 13:10 | 显示全部楼层
DMA
  在使用串口 DMA 接收的时候,发现驱动库提供的接口并不能满足实际需要。具体表现为,串口的 DMA 是工作在循环模式下的,这就要求在必要的时候可以获取 DMA 接收的数据长度,不过驱动库貌似没有对应的接口!

DMA 驱动中只有设置接口,没有读取接口! 。无奈自己增加了几个接口!
 楼主| 我爱台妹mmd 发表于 2021-11-29 13:11 | 显示全部楼层
GPIO
华大应该称为 PORT
 楼主| 我爱台妹mmd 发表于 2021-11-29 14:04 | 显示全部楼层
时钟
  貌似,华大 MCU 并不能像 ST MCU 似得,开启或者关闭某个 GPIO 的时钟。所以在配置 IO 时,无需要处理时钟的问题。
 楼主| 我爱台妹mmd 发表于 2021-11-29 14:05 | 显示全部楼层
特殊配置
某些 IO 在上电时默认是用作其他功能的。例如:

PA13,PA14,PA15,PB3,PB4 端口复位后初始状态为 JTAG/SWD 功能有效。
PC14,PC15 端口复位后初始状态为数字功能禁止状态
PA11,PA12 与 USBFS_DM,USBFS_DP 引脚复用,内藏约 400KΩ 的下拉电阻,且一直有效。
端口 PB11 与 MD 复用,为输入专用端口,无输出功能
 楼主| 我爱台妹mmd 发表于 2021-11-29 14:24 | 显示全部楼层
这一点貌似和 STM32F1x 的使用情况是一致的。因此,如果需要将上面的 IO 作为普通 IO 使用,则必须进行特殊配置,然后才能进行正常的 IO 配置!

PA13,PA14,PA15,PB3,PB4 在配置 FSEL[5:0] 选择功能时需要先将寄存器 PSPCR 相应位写 0 无效JTAG/SWD 功能。对应的库函数接口 en_result_t PORT_DebugPortSetting(uint8_t u8DebugPort, en_functional_state_t enFunc);
PC14,PC15 在选择数字功能时需要先将相应寄存器 PCRxy 的 DDIS 位写 0 有效数字功能。这个在进行 IO 配置时,在en_result_t PORT_Init(en_port_t enPort, uint16_t u16Pin, const stc_port_init_t *pstcPortInit); 中就有对应的处理。
当系统运行在高速时钟下,由于 I/O 输入存在延迟,单周期可能无法正确读取输入状态值。此时需要设置寄存器 PCCR.RDWT[1:0],插入若干等待周期。
 楼主| 我爱台妹mmd 发表于 2021-11-29 14:26 | 显示全部楼层
外设引脚映射
  具体见用户手册的 2.2 引脚功能表。在我的项目中,出现了 SPI_CLK 引脚无法映射的问题。
 楼主| 我爱台妹mmd 发表于 2021-11-29 14:30 | 显示全部楼层
程序下载异常
  在使用中发现,在下载程序之后并不能正常启动。我的项目结构是 IAP(在线升级) + APP,每次下载 APP 之后,IAP 就会被清除。一开始没有具体分析错误的原因的情况下,想当然的通过如下解决方法来处理。
8902461a4737403c59.png
 楼主| 我爱台妹mmd 发表于 2021-11-29 14:31 | 显示全部楼层
但是,如上图修改之后,在实际下载的时候,Keil 会提示如下的警告,不过貌似没啥影响
2292861a473d3067c3.png
 楼主| 我爱台妹mmd 发表于 2021-11-29 15:06 | 显示全部楼层
虽然调试没啥影响,但是在生成 .bin 文件时却会出现错误!
 楼主| 我爱台妹mmd 发表于 2021-11-29 15:07 | 显示全部楼层
 楼主| 我爱台妹mmd 发表于 2021-11-29 15:07 | 显示全部楼层
但实际该方法并没有解决根本。通过详细分析,最后发现该问题是由于看门狗的配置导致的。具体:由于 APP 中包含了 看门狗的配置,看门狗的配置其实是 FLASH 中的固定一块空间。我们的 APP 偏移之后,自然没有看门狗部分的操作算法!
 楼主| 我爱台妹mmd 发表于 2021-11-29 15:09 | 显示全部楼层
最终解决方法: 我们不需要上面的更改,只需要将看门狗的配置放到 IAP 中即可! IAP 肯定是从起始地址开始,自然不会有问题!
 楼主| 我爱台妹mmd 发表于 2021-11-29 15:18 | 显示全部楼层
外设反初始化
  我的项目结构是 IAP(在线升级) + APP,外设在 IAP 中工作正常,但是在 APP 中工作不正常。这主要是由于:外设在 IAP 中已经初始化,然而在调整到 APP 之后,这部分外设由于已经被初始化,导致不会再次被初始化。这一点其实对于 ST 的 MCU 同样适用。因此,需要我们来特殊处理!
 楼主| 我爱台妹mmd 发表于 2021-11-29 15:19 | 显示全部楼层
 例如 hc32f46x_interrupts.c/h 中配置的中断,如果在 IAP 中已经被设置,跳转到 APP 后,就无法再正常配置了(全局变量中会检查是否被配置过)
  1. en_result_t enIrqRegistration(const stc_irq_regi_conf_t *pstcIrqRegiConf)
  2. {
  3.     // todo, assert ...
  4.     stc_intc_sel_field_t *stcIntSel;
  5.     en_result_t enRet = Ok;

  6.     //DDL_ASSERT(NULL != pstcIrqRegiConf->pfnCallback);
  7.     DDL_ASSERT(IS_NULL_POINT(pstcIrqRegiConf->pfnCallback));

  8.     /* IRQ032~127 whether out of range */
  9.     if (((((pstcIrqRegiConf->enIntSrc/32)*6 + 32) > pstcIrqRegiConf->enIRQn) || \
  10.         (((pstcIrqRegiConf->enIntSrc/32)*6 + 37) < pstcIrqRegiConf->enIRQn)) && \
  11.         (pstcIrqRegiConf->enIRQn >= 32))
  12.     {
  13.         enRet = ErrorInvalidParameter;
  14.     }
  15.     else
  16.     {
  17.         stcIntSel = (stc_intc_sel_field_t *)((uint32_t)(&M4_INTC->SEL0)         +   \
  18.                                              (4u * pstcIrqRegiConf->enIRQn));
  19.         if (0x1FFu == stcIntSel->INTSEL)        /* 如果已经初始化过,这里将不能再初始化 */
  20.         {
  21.             stcIntSel->INTSEL = pstcIrqRegiConf->enIntSrc;
  22.             IrqHandler[pstcIrqRegiConf->enIRQn] = pstcIrqRegiConf->pfnCallback;
  23.         }
  24.         else
  25.         {
  26.             enRet = ErrorUninitialized;
  27.         }
  28.     }
  29.     return enRet;
  30. }
 楼主| 我爱台妹mmd 发表于 2021-11-29 15:22 | 显示全部楼层
具体方法就是使用 enIrqResign 函数进行重新标记!
sylar^z 发表于 2021-12-3 15:59 | 显示全部楼层
内容很详细,支持一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部