0%

柠檬FOC解构

0x00 电路原理图分析

邮票孔原理图

img

A、电压采样

img  输入电压VM为外接DC12V供电,分压电阻为18k和1k,即AD采集到的电压值为x时,实际电压y=x*19。主控连接VBUS_S的IO为PA0配置为ADC0的CH0。(确定嘛?)

B、温度采样

img  输入电压为3.3V,分压电阻为10k热敏电阻和3.3k电阻。热敏电阻型号为NCP18XH103F03RB,查阅数据手册得知其B值为3380。其中B值计算公式如下:
$B = \frac{(T_2 \times T_1)}{(T_2 - T_1)} \times \ln\left(\frac{R_2}{R_1}\right)$
  其中$T_1$和$T_2$是两个不同的温度,$R_1$是温度$T_1$下的电阻值,$R_2$是温度$T_2$下的电阻值。主控连接M0_TEMP的IO为PB0配置为ADC1的CH2。(确定嘛?)

C、晶振电路

img  无源8M晶振,外壳接地,两个引脚分别接OSCIN和OSCOUT。

D、主控电路

img  主控芯片使用GD32C103TBU6,具体详情可以参考相应数据手册。需要注意的是3.3V电源过100nf滤波电容后接入,该接地的接地。NRST接100nf到地,BOOT0接10k电阻到地,设置从片上FLASH启动。

E、电流采样

img  主要元件电流感应放大器使用的是TP181A1,根据数据手册得知,其GAIN为50。输出电压$V_{OUT} = \left(I_{LOAD}\timesR{SHUNT}\right)GAIN + V_{REF}$其内部电路原理图如下图所示。img  可以看到FOC电路原理图中,REF是3.3V通过两个1k电阻分压取得,可知其值为1.65V。两个TP181A1的输出分别接在主控的PA1和PA2上,分别采集B、C两路的电流值(因为三相电机定子的线圈为星形连接,通过基尔霍夫电流定律可以算出A路的电流大小,所以只需要采集两路电流即可)。两个TP181A1的输入IN+和IN-则是通过10mΩ的电阻分压电机驱动电路的PGND输出得到。

F、5V-3.3V

img  利用线性稳压器5V转3.3V。输入输出端接滤波电容,EN可以直接接IN。

G、电机驱动

img  AT8313是三路半桥集成驱动芯片,很多问题不需要自己考虑,比如低电压小电流的控制信号和高电压大电流的驱动信号如何隔离,三相电机的驱动电路如何设计,器件参数如何匹配等。芯片的外部电路可以参考数据手册搭建。示例如下图所示。img  可以看出,先前的PGND输出为BLDC的电流输出端,根据数据手册描述,AT8313包含三路半H桥驱动器,半H桥的下管MOSFET的S端为各自独立管脚(PGND1、PGND2、PGND3),这样就可接3个独立的检流电阻。如果使用检流电阻,请保证此3管脚(PGND1、PGND2、PGND3)的电压不超过±500mV。电流采样电路中,检流电阻为10mΩ,考虑电机的额定电流到不了50A,基本可以保证PGND电压不会超过±500mV。AT8313的其他管脚描述如下图所示。imgimg  根据管脚描述,除了必要外围电路,控制部分将三个EN引脚拉高,使能半H桥,然后将三个IN引脚接主控芯片,主控芯片通过输出高低电位可以控制半H桥的逻辑输出。V3P3是AT8313的一个3.3V电压输出引脚,直接和NSLEEP和NRESET连接,保证芯片正常工作。OUT1、OUT2、OUT3三个引脚接BLDC的三相线。IN1、IN2、IN3分别接主控芯片的PA8、PA9、PA10。VM输入通过两个100nf和一个100uf的电容并联滤波后送入。

H、24V-5V

img  主要器件使用JW5026电源芯片,为DC-DC芯片。支持5V1A输出,数据手册指导外围电路如下所示。根据外围电路参数搭建即可。img

I、剩余原理图

img  2.54mm排母部分对应提供给外界的引脚封装,USB串口和SWD对应两个供调试用的插座。MCU的PB6、PB7分别接USART1的TX和RX。SHA、SHB、SHC分别接AT8313的三路输出。SPI1_CS1、SPI1_SCK、SPI1_MISO、SPI1_MOSI分别接PA4、PA5、PA6、PA7。VM为电机驱动供电。

编码器及电机载板

A、柠檬FOC邮票孔

img  柠檬FOC提供给外界的引脚封装。应该是后续设计的取舍,使用的芯片时GD32E103TBU6,该芯片没有CAN,所以原理图中CAN没用上。同时,5V输出没有引出,应该也是多余设计没有删除。MCU的PB6、PB7分别接TX和RX。SHA、SHB、SHC分别接AT8313的三路输出。CS、SCK、MISO、MOSI分别接PA4、PA5、PA6、PA7对应的SPI四个引脚。VIN为电机驱动供电。

B、MT6816编码器

img  除去电源和地,不接OUT,剩下四个引脚接SPI的四个引脚。

0x01 代码分析

A、PWMC_init

1、配置过程

IO配置

  • 打开GPIOA,GPIOB,AF,TIMER0的时钟
  • A8,A9,A10,PB13,PB14,PB15初始化为复用推挽输出,50MHz

TIMER0配置

  • TIMER0恢复到复位后的状态
  • 将TIMER初始化结构体赋值为默认值
  • 预分频为0
  • 中央计数模式,向上计数(上数到计数上限,然后再下数到0,向上计数表示在上溢时触发事件或中断)
  • 设置计数模式为向上计数
  • 自动重装载值设置为PWM_ARR-1
  • 时钟分频值为1,即不分频
  • 不使用重复计数器(即每次计数到上溢都会触发事件或中断)

TIMER0输出通道配置

  • 将TIMER输出通道配置初始化结构体赋值为默认值
  • 输出比较通道使能
  • 输出比较互补通道使能
  • 输出比较通道高电平有效
  • 输出比较互补通道高电平有效
  • 输出比较通道空闲时低电平
  • 输出比较互补通道空闲时低电平
  • 使用结构体初始化TIMER0的0~3四个通道的输出配置
  • 通道0、通道1、通道2自动重装载值设为PWM_ARR的一半(右移一位的结果),通道3重装载值为PWM_ARR-5
  • 设置PWM为PWM模式0
  • 通道0、通道1、通道2使能阴影模式,通道3失能阴影模式

TIMER0刹车配置

  • 禁用运行偏移状态
  • 禁用独立延迟偏移功能
  • 设置死区时间为0
  • 设置刹车输入低电平有效
  • 禁用自动输出功能
  • 关闭比较/捕获通道的保护模式
  • 禁用刹车功能

剩余操作

  • 禁用TIMER0的0,1,2以及对应的三个互补通道
  • 使能TIMER0的主输出功能
  • 使能TIMER0的自动重装载
  • 调用adc0_config和adc1_config
  • 使用systick等待10ms
  • 使能TIMER0

2、分析

  根据GD32C103TBU6数据手册,查阅得到GPIOA用到三个引脚的定义如下图所示。根据图中信息可知,仅使用了TIMER0的CH0,CH1,CH2,所以后续对CH3的操作也是没有意义的。配置中用到的PB13、PB14、PB15在QFN36封装的芯片上是不存在的,该部分配置没有用。
img  其他的就是PWM的基本配置流程,启用GPIO、AF、TIMER的时钟,然后对TIMER进行配置,然后对PWM输出模式进行配置。互补通道和刹车配置最后是禁用,感觉可以不用管。然后使能TIMER的输出功能,使能自动重装载,调用ADC的初始化后,使能TIMER0。

B、ADC

1、配置过程

IO配置

  • 配置PA0和PA1为最大输出速度(官方宏定义是:GPIO very high output speed, max speed more than 50MHz)
  • 配置PA2和PB0为最大输出速度

ADC基本配置

ADC0

  • 失能ADC0
  • 启用双ADC模式
  • 启用ADC0的扫描模式
  • 启用ADC0的连续转换模式
  • 设置ADC0的数据对齐方式为右对齐(数据的最低位放在寄存器的最低位)
  • ADC0的规则通道组,指定为1个通道
  • ADC0通道0规则通道采样时间为7.5个ADC时钟周期
  • ADC0的注入通道指定为1个通道
  • ADC0通道1注入通道采样时间为7.5个ADC时钟周期
  • 配置ADC0的注入通道被TIMER0的CH3触发(TIMER0的CH3发生事件时注入通道进行一次转换)
  • 使能ADC0的注入通道触发
  • 配置ADC0规则通道不被外界触发,只被软件触发
  • 使能ADC0的规则通道触发
  • 配置ADC0优先级为最高优先级(抢占优先级和子优先级都是0)
  • 清除EOIC标志位
  • 启用ADC0的EOIC中断(End of Interrupt Conversion,即每次注入通道转换完毕后触发中断)
  • 使能ADC0
  • 等待1ms
  • 使能ADC0校准
  • 使能ADC0规则通道软件触发

ADC1

  • 失能ADC1
  • 设置ADC1的数据对齐方式为右对齐(数据的最低位放在寄存器的最低位)
  • ADC1的注入通道指定为1个通道
  • ADC1通道2注入通道采样时间为7.5个ADC时钟周期
  • 配置ADC1的注入通道被TIMER0的CH3触发(TIMER0的CH3发生事件时注入通道进行一次转换)
  • 使能ADC1的注入通道触发
  • ADC1的规则通道组,指定为1个通道
  • ADC1通道8规则通道采样时间为7.5个ADC时钟周期
  • 配置ADC1规则通道不被外界触发,只被软件触发
  • 使能ADC1的规则通道触发
  • 使能ADC1
  • 等待1ms
  • 使能ADC1校准
  • 使能ADC1注入通道软件触发

2、分析

  根据GD32C103TBU6数据手册,查阅得到PA0和PA1分别对应ADC01_IN0和ADC01_IN1,PA2和PB0分别对应ADC01_IN2和ADC01_IN8
imgimg  配置ADC0和ADC1均为一个规则通道和一个注入通道,两个注入通道都是由TIMER0的CH3触发(PWM中配置的CH3的ARR为PWM_ARR-5),三个PWM输出通道的重装载值均为PWM_ARR>>1。意味着两轮PWM输出差5次计数时,进行一次注入通道的AD转换。  根据电路原理图,PA0接电压采集,PA1和PA2接ISENSB和ISENSC两路电流采集,PB0接温度采集。

C、Encoder_MT6816_init

1、配置过程

  • 使能GPIOA,GPIOB,GPIOC,AF,SPIO的时钟
  • PA4配置为推挽输出50MHz
  • PA5和PA7配置为复用推挽输出50MHz
  • PA6配置为浮空输入50MHz
  • 逆初始化SPI0,然后配置spi初始化结构体为默认值
  • 设置SPI为全双工模式
  • 设置设备为主模式
  • 配置数据帧大小为16位
  • 设置时钟极性位高,时钟相位为第二时钟边沿(SPI模式3)
  • 配置NSS信号由软件控制
  • SPI时钟8分频
  • 数据传输高位字节在前(MSB)
  • 使用结构体进行初始化
  • 使能SPI0
  • 等待10ms
  • 作者自定义的一些变量的初始化

2、分析

  主要就是使用SPI与MT6816编码芯片进行通信。img根据MT6816的数据手册可以得知,读取编码器角度信息的地址是0x03和0x04。角度计算公式也如图中所示。