项目代码打包链接:https://download.csdn.net/download/qq_35768865/87410231
2023.8.14 更新
后续没写笔记了 ,在部分代码中写了一些注释,不一定准确,但应该有点参考价值,免费下载链接:https://download.csdn.net/download/qq_35768865/88214282
代码阅读思路
搜索chRegSetThreadName观察所编写的线程实体函数,由线程出发检索相关创建、调用流程。
文件介绍
上位机USB配置电机过程
main函数中会调用comm_usb_init初始化USB串口、packet、互斥量、创建串口读取线程和处理线程.
1.串口接收数据到缓冲区后,comm_usb.c文件中的串口处理线程会调用packet.c文件的packet_process_byte()函数,该函数有调用try_decode_packet()函数。
2.try_decode_packet()通过传入的函数指针调用comm_usb.c文件的process_packet()函数,该函数再调用commands_process_packet(data, len, comm_usb_send_packet)进行缓冲区的命令和数据处理(完成配置读写等任务,数据通过comm_usb_send_packet函数发送)。
motor configuration配置出错问题:将confgenerator.h文件替换为vesc tool生成的confgenerator.c和.h文件解决,原因为不同版本上位机对固件的验证签名不同。
虚拟EEPROM实现
虚拟EEPROM用于电机参数、APP参数在FLASH的读写。
虚拟EEPROM在内存中的存储格式如下:每个地址占1个字节
[内存值,内存地址]:
[数据1低字节:数据1高字节, 0x08004000:0x08004001]
[虚拟地址值1低字节:虚拟地址值1高字节, 0x08004002:0x08004003]
存储过程为:首先获取电机参数结构体\APP参数结构体内存首地址,然后按顺序每次取2个字节连同虚拟地址值按小端格式存入FLASH
mc_configuration结构体
用于保存上位机设置的电机参数
1.源码mcconf_default.h文件中的宏定义有对该结构体成员变量的默认值作出解释可帮助理解(设置默认值的函数confgenerator_set_defaults_mcconf位于confgenerator.c)
2.VESC TOOL软件的Developer选项栏中有相关参数编辑的入口以及详细的参数说明
commands_process_packet函数
外设配置
1.TIM
TIM1\TIM8:用于输出PWM控制电机1和电机2
TIM2:更新中断用于TIM1\TIM8产生COM事件进行同步,以及虚拟电机连接时调用virtual_motor_int_handler()
TIM3:更新中断用于编码器数据更新
TIM5:用于mcpwm_foc_adc_int_handler函数运行耗时计算
2.ADC
ADC采集完成后由DMA传输至内存中ADC_Value[15]数组,然后DMA产生中断,在中断OSAL_IRQ_HANDLER(Vector130)【即DMA2_Stream4】中调用mcpwm_foc_adc_int_handler函数进行采样电流计算、编码器计算角度(启用编码器时)、电机运行中(不同控制模式、传感模式的判断,电流控制)、电机未运行时(跟踪反电动势、运行观测器、设置电机相位)、PLL运行、转速估算、跟踪位置控制角度
当使用电位器通过电路板标识为ADC1_2引脚控制时,在adc_thread线程中获取ADC_Value数组中对应通道的ADC采集值进行处理。
PID线程
mcpwm_foc.c文件中pid_thread:判断PID运行状态->判断配置的PID调整频率->计算耗时->位置环、速度环PID控制
参数测量
conf_general.c 文件的conf_general_detect_apply_all_foc函数中
调用measure_r_l_imax函数测量R、L,;
调用conf_general_measure_flux_linkage_openloop函数开环测量弱磁。
通过conf_general_calc_apply_foc_cc_kp_ki_gain计算保存pi增益等
调用conf_general_autodetect_apply_sensors_foc函数检测传感器模式
commands.c文件的blocking_thread线程中
switch语句选择不同功能执行:
COMM_DETECT_MOTOR_PARAM:调用conf_general_detect_motor_param检测电机参数
COMM_DETECT_MOTOR_R_L:调用mcpwm_foc_measure_res_ind检测电阻电感(单个参数识别时调用)
COMM_DETECT_MOTOR_FLUX_LINKAGE:调用conf_general_measure_flux_linkage检测磁链(单个参数识别时调用)
COMM_DETECT_ENCODER \ COMM_DETECT_HALL_FOC:编码器 \ 霍尔传感器检测
COMM_DETECT_APPLY_ALL_FOC:检测所有控制器(USB和CAN总线上发现的)的电机参数(用于自动识别所有参数)
其他:终端命令、CAN的ping、blackmagic控制、IMU校准等
FOC模式初始化电流偏移校准:mcpwm_foc_dc_cal函数
分别测量电机驱动时和未驱动时的相电流、电压偏移,并在计算补偿时判断是否运行再分别取用偏移量计算;
以50%调制驱动电机所有相,此时合成空间矢量相当于处在零矢量点,对3个相分别记录1000次采集到的相电流和电压,求和后计算每相的平均电流Ix、平均电压Ux,保存平均电流作为零矢量点采样的参考电流值。再将3个相的平均电压相加再次平均得到U,用Ux减去U的差值作为U1,U2,U3每相的偏移值,并保存至电机状态结构体变量,
未驱动时,计算每相电压的偏移量误差再取平均值。
电压偏移量最终在update_valpha_vbeta函数中用于补偿计算。
FOC循环运行过程(以电流环,且由ADC控制电流参考量为例)
ADC由TIM2_CH2事件周期触发采样,持续采集通道电压并通过DMA2Stream2传输到内存(ADC_Value数组),每次采集传输完成后触发DMA中断,在该中断中调用mcpwm_foc_adc_int_handler函数运行FOC控制环路。
mcpwm_foc_adc_int_handler详细流程:
1. 判断本次中断是否运行FOC控制环路(每FOC_CONTROL_LOOP_FREQ_DIVIDER个ADC中断运行一次FOC控制回路)
2. 获取TIM5计数值用于计算运行耗时,获取TIM1的计数状态用于后续判断是否进行采样电流计算
3. 获取电机状态结构体变量的句柄,用于后续判断电机状态进行相应计算、控制
4. 获取PWM输出定时器句柄,由电机状态句柄访问SVPWM计算结果,标志位为1即已完成下个载波周期所需定时值计算时,更新三个PWM通道的预装载值寄存器TIMx->CCRx,并清除标志位。(仅高频注入的更新,常规FOC的更新位于control_current函数末尾)
5. 由电机句柄判断是否达到相电流采样时间点(v0还是v0||v7),到达则继续往下执行(否则退出中断),从ADC_Value数组取得三路相电流采样电阻上的电压值,判断采样模式后进行相应计算处理。
6.
APP控制逻辑
上位机设置好app模式由单片机存至flash,每次上电时会读取配置加载,然后判断模式对相应模块进行初始化配置。相关函数(app_set_configuration\conf_general_read_app_configuration)