电机驱动板原理介绍:
参考链接:
BuildIts in Progress: Mini Cheetah Clone Teardown



主控芯片:
GD32F303RET6

GD32F303RET6-MCU选择器-兆易创新 GigaDevice | 官方网站
编码器方案:
电机端编码器:AS5047磁编码器
输出端编码器:六个线性HALL传感器阵列,搭配三对极磁环,输出正弦信号,通过解析该正弦信号获得位置
这里线性HALL传感器阵列的电路板电气上通过一个10PIN的接插件和主板相连,HALL板和主板接插件序号1-10定义:VCC (1 -- TP11) ; GND (3、5、7 -- TP23、TP18) ; HALL线序、测试点、传感器丝印、MCU引脚(2 --TP12 -- U6 -- PA4 、4 -- TP13 -- U7 -- PA5、6 -- TP14 -- U8 -- PA6、8 -- TP15 -- U9 -- PA7、9 -- TP17 -- U11 -- PC5、10 -- TP16 -- U10 -- PC4);可以看到在六个HALL芯片的的VCC和GND之间一共有两个二极管(藏在HALL PCB的下面),可能是TVS(单向或双向):用于抑制静电和浪涌,或齐纳二极管:用于过压保护或检测;

可以看到在磁编芯片的VCC和GND之间有个二极管,可能是TVS(单向或双向):用于抑制静电和浪涌,或齐纳二极管:用于过压保护或检测;


同时发现线性HALL传感器阵列的电路板结构上通过三根支撑柱fix1、fix2、fix3和主板焊接相连,可以用电烙铁加热拆下来,建议拆的时候先慢慢掰开fix1、fix2两个点位,等这两个点位差不多焊下来传感器阵列电路板可以微微左右晃动的时候再加热fix3点位,将整块小板取下,取下后如图:

工作原理示例:


这里我使用的是一个IIC通讯的AS5600磁编码器云台电机,由于六个线性HALL在电路板背面都有对应的测试点(2 --TP12 -- U6 -- PA4 、4 -- TP13 -- U7 -- PA5、6 -- TP14 -- U8 -- PA6、8 -- TP15 -- U9 -- PA7、9 -- TP17 -- U11 -- PC5、10 -- TP16 -- U10 -- PC4),因此这里将线性HALL小板拆下来后随便选取两个测试点,将对应IO口配置为软件IIC后,使用软件IIC读取AS5600磁编码器角度,驱动代码如下:
AS5600 驱动(HAL库400K硬件IIC+DMA、1MHZ软件IIC)_hal iic+dma-CSDN博客
AS5600驱动: 关于AS5600驱动以及软件IIC实现 - Gitee.com
驱动+电流采样:
DRV8323S 电机驱动芯片 40pin
MOS管:6个ST的STL140N6F7,60 V, 2.4 mΩ typ., 140 A;这里和别人的拆解结果有点不同,可能黑色电路板版本的MOS管和绿色电路板版本的不同?

驱动代码如下:
DRV8323/8353驱动_drv8323和drv8353驱动程序区别-CSDN博客
GD32F303 HAL库配置
HAL库版本:6.15.0
启用FPU浮点计算单元:
(1)生成工程

(2)Keil中选择对应的GD32芯片型号

(3)配置FPU参数

在下述函数开头加入:(*(volatile uint32_t *)(0xE000ED88)) |= (15 << 20);

4、消除报错:编译发现有关于FPU的报错,找到报错位置直接注释,报错消失


5、验证FPU是否启用
发现程序的汇编中出现了VMUL.F32这个浮点指令,且执行该指令后系统无异常,运算结果也正确,则说明FPU已成功启用;

启用DSP库:
1、添加
先勾选DSP选项

然后在下面图片中加入对应自己单片机内核的宏定义,这里我是M4内核就是写入ARM_MATH_CM4;(其他还有宏ARM_MATH_CM7或ARM_MATH_CM3或ARM_MATH_CM0或ARM_MATH_CM0plus等)

最后在相应c文件中引用 arm_math.h就可以使用dsp库中的所有函数,如下

2、发现报错

参考下面两篇文章,主要是第二篇,发现仍然报错,不过少一些了
在keil中加入DSP库并且使用arm_math.h - 海滩长颈鹿 - 博客园
在Keil中加入DSP库并使用arm_math.h_哔哩哔哩_bilibili

最后灵机一动,把编译器从keil5改为keil6的,就没有出现DSP库相关的报错了,在修改了一些由于编译器版本导致的报错后,成功解决!


CAN初始失败解决:
GD32使用ST HAL库 CAN无法初始化问题_gd32无法初始化-CSDN博客
使用HAL库的MX_CAN_Init();后调试发现进入error_handler(),最后定位在下面这个地方初始化超时,上网查阅后发现ST和GD的CAN外设实现的底层顺序不一样,需要在while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)前增加一句CLEAR_BIT(hcan->Instance->MCR,CAN_MCR_SLEEP);

ADC DMA采样卡死解决:
调用HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_ConvertedValue, 1);后卡死在DMA中断,将规则组采样时间从ADC_SAMPLETIME_7CYCLES_5改为ADC_SAMPLETIME_239CYCLES_5;后解决,这个问题不止在GD芯片上存在,实测ST的芯片上也会出现这个情况,原因暂且不清楚;
通道4无法正常触发ADC中断解决:
由于ADC采样完成中断是由定时器1的通道4触发,我的代码如下:
先调用 HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_4);再调用HAL_TIM_Base_Start_IT(&htim1); // 启动定时器1中断,然后再次调用HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_4);就不能正常触发ADC采样完成中断,但此时如果将HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_4);换成HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_1/2/3);就都可以正常触发,同时将HAL_TIM_Base_Start_IT(&htim1);前面的 HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_4);删掉也可以正常触发了,最终选择删掉一开始多余的HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_4);
main()
{
HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_4);
__HAL_TIM_CLEAR_FLAG( &htim1, TIM_FLAG_BREAK);
HAL_TIM_Base_Start_IT(&htim1); // 启动定时器1中断
Offset_Current_Start();
}
void Offset_Current_Start(void)
{
HAL_TIM_PWM_Stop( &htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop( &htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop( &htim1, TIM_CHANNEL_3);
MotorState.run_state = RUNSTATE_CALIBRATING;
HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_4);
HAL_ADCEx_InjectedStart_IT(&hadc1); //开启FOC运行
HAL_ADCEx_InjectedStart(&hadc2);
HAL_Delay(200);
}
重刷固件:
一开始我用Jlink和驱动板的SWCLK、SWDIO、GND连接,但是发现识别不到芯片,于是又将Jlink的3.3V用于驱动板供电(断开外部供电),再次识别发现识别成功,成功之后将自己的程序烧录进去,后面只连接SWCLK、SWDIO、GND三根线也能识别了;

