高级会员
- 积分
- 542
- 金钱
- 542
- 注册时间
- 2017-10-17
- 在线时间
- 118 小时
|
本帖最后由 冯必兴 于 2024-1-19 15:16 编辑
本驱动是基于源自个的基于407上作出修改的,原子哥使用的是HAL库,但是对于使用标准库的人是种罪过,由此就修改了一下,最后不得不说原子哥做的确实稳,后期出FOC
玩BLDC必须要了解一下几个内容
1.硬件,是使用DRV8313等之类的驱动芯片还是 分立元器件搭建的
2.BLDC换相原理 ,换相需要的霍尔信号是怎样的?
3.为什么速度跟PWM占空比有关 ,速度最快占空比为多少
4.速度计算原理
重点:最好看一下原子哥的视频:https://www.bilibili.com/video/B ... Fvp&up_id=394620890
主函数内容:
#include "stm32f4xx.h"
#include "usart.h"
//#include "bldc_tim.h"
//#include "bldc.h"
#include "pid.h"
#include "debug.h"
#include "delay.h"
#include "bldc.h"
#include "bldc_tim.h"
//#include "mcu_time4.h"
//RCC_ClocksTypeDef get_RCC_Clocks;
/*********************************************************************
* 函 数 名: main
* 函数入参: void
* 函数出参: 无
* 返 回 值: void
* 功能描述: 主函数
**********************************************************************/
RCC_ClocksTypeDef RCC_Clocks;
extern float* user_setpoint;
extern float debug_data_temp;
extern int32_t motor_pwm_s;
//extern int32_t temp_pwm1;
//extern int16_t adc_amp_un[3];
//extern float adc_amp_bus;
//extern uint16_t g_adc_value[ADC_CH_NUM * ADC_COLL];
extern uint8_t clc;
uint32_t times = 0;
int main(void)
{
uint8_t debug_cmd = 0; /* 存放上位机指令 */
float current_lpf[4] = {0.0f}; /* 存放三相电流以及母线电流 */
uint8_t key, t;
char buf[32];
float current[3] = {0.0f};
int16_t speed_diplay = 0;
float user_setpoint_temp = 0.0;
//延时函数初始化
delay_init();
usart_init(115200);
LED_Init();
bldc_init(180000 / 18 - 1, 0);
bldc_ctrl(MOTOR_1, CCW, 0); /* 初始无刷电机接口1速度 */
pid_init();
debug_init(); /* PID调试初始化 */
debug_send_motorcode(BLDC_MOTOR); /* 直流电机 */
debug_send_motorstate(IDLE_STATE); /* 电机空闲 */
/* 初始化同步数据(选择第x组PIDX,目标速度地址,P,I,D参数)到上位机 */
debug_send_initdata(TYPE_PID1, (float*)(&g_speed_pid.SetPoint), C_KP, C_KI, C_KD); /* 电流环PID参数(PID1)*/
debug_send_initdata(TYPE_PID2, (float*)(&g_speed_pid.SetPoint), S_KP, S_KI, S_KD); /* 速度环PID参数(PID2)*/
RCC_GetClocksFreq(&RCC_Clocks);
// g_bldc_motor1.pwm_duty = 15000; /* 加速启动速度 */
// start_motor1();
// TIM_SetCompare1(TIM1, 500);
while(1)
{
t++;
if(t % 20 == 0)
{
user_setpoint_temp = (*user_setpoint);
speed_diplay = g_bldc_motor1.speed;
// LED0_TOGGLE(); /* LED0(红灯) 翻转 */
/* 三相电流计算 */
// current[0] = adc_amp_un[0] * ADC2CURT; /*U*/
// current[1] = adc_amp_un[1] * ADC2CURT; /*V*/
// current[2] = adc_amp_un[2] * ADC2CURT; /*W*/
/*一阶数字滤波 滤波系数0.1 用于显示*/
FirstOrderRC_LPF(current_lpf[0], current[0], 0.1f);
FirstOrderRC_LPF(current_lpf[1], current[1], 0.1f);
FirstOrderRC_LPF(current_lpf[2], current[2], 0.1f);
// FirstOrderRC_LPF(current_lpf[3], adc_amp_bus, 0.1f);
if(g_bldc_motor1.run_flag == STOP) /* 停机的电流显示 */
{
current_lpf[0] = 0;
current_lpf[1] = 0;
current_lpf[2] = 0;
current_lpf[3] = 0;
}
}
//#if DEBUG_ENABLE
// /* Debug发送部分 */
// /* 主要显示参数 */
// debug_send_valtage(g_adc_value[0] * ADC2VBUS); /* 发送电压*/
debug_send_speed(g_bldc_motor1.speed); /* 发送速度*/
// debug_send_temp(50, get_temp(g_adc_value[1])); /* 发送电机温度、驱动板温度*/
debug_send_current((float)(current_lpf[0] / 1000), (float)(current_lpf[0] / 1000), (float)(current_lpf[0] / 1000)); /*发送电流*/
/* 电流波形和速度波形 */
debug_send_wave_data(1, (int16_t)g_bldc_motor1.speed); /* 选择通道1 发送实际速度 */
debug_send_wave_data(2, (int16_t)*user_setpoint); /* 选择通道2 发送目标速度 */
debug_send_wave_data(3, current_lpf[0]); /* 选择通道3 发送实际电流U */
debug_send_wave_data(4, current_lpf[1]); /* 选择通道4 发送实际电流V */
debug_send_wave_data(5, current_lpf[2]); /* 选择通道5 发送实际电流W */
debug_send_wave_data(7, current_lpf[3]); /* 选择通道7 发送实际电流 */
debug_send_wave_data(8, g_current_pid.SetPoint); /* 选择通道8 发送目标电流 */
/* Debug接收部分 */
debug_receive_pid(TYPE_PID1, (float*)&g_current_pid.Proportion, /* 查询接收PID助手的PID1参数*/
(float*)&g_current_pid.Integral, (float*)&g_current_pid.Derivative);
debug_receive_pid(TYPE_PID2, (float*)&g_speed_pid.Proportion, /* 查询接收PID助手的PID2参数*/
(float*)&g_speed_pid.Integral, (float*)&g_speed_pid.Derivative);
debug_cmd = debug_receive_ctrl_code(); /* 读取命令 */
if(debug_cmd == HALT_CODE) /* 停机 */
{
pid_init();
g_bldc_motor1.run_flag = STOP; /* 标记停机 */
stop_motor1(); /* 停机 */
g_bldc_motor1.speed = 0;
motor_pwm_s = 0;
g_bldc_motor1.pwm_duty = 0;
}
else if(debug_cmd == RUN_CODE) /* 运行 */
{
g_bldc_motor1.run_flag = RUN; /* 运行标记 */
*user_setpoint = 7200; /* 自动设置目标 */
// g_bldc_motor1.pwm_duty = 15000; /* 加速启动速度 */
debug_data_temp = *user_setpoint;
start_motor1(); /* 启动电机 */
debug_send_motorstate(RUN_STATE); /* 电机运行 */
}
else if(debug_cmd == BREAKED) /* 刹车(电机停止 点击电机运行才可解除) */
{
*user_setpoint = 0; /* 减速直至0 */
debug_send_motorstate(BREAKED_STATE); /* 电机刹车 */
}
//#endif
delay_ms(20);
}
}
/*********************************************END OF FILE**********************/
纠正一下:/*******************************************************************************************
函数名:MotorSpeed_Get
输入:GetCount 计数次数 ,hall_single_sta 霍尔信号时长 ,dir 电机方向,speed_coeff 计算速度
输出:无
返回值:temp_speed_output 计算输出结果
描述:通过霍尔的极性计算速度
第一步:t = C/Ft(其中Ft是计数频率,C为计数次数)
第二步:旋转一圈需要时间 T= 2*C/Ft
第三步:rmp = Ft/(2*C)*60
*********************************************************************************************/
int32_t MotorSpeed_Get(uint32_t *GetCount, uint32_t hall_single_sta, uint8_t dir, uint32_t speed_coeff,int32_t *speed)
{
static uint32_t no_single = 0;
static int16_t temp_speed = 0;
//const int32_t temp_speed_output = 0;
uint8_t hall_sta_edge = uemf_edge(hall_single_sta);
if(hall_sta_edge == 0) /* 统计单个霍尔信号的高电平时间 */
{
/* 计算速度 */
if(dir == CW)
temp_speed = (speed_coeff / *GetCount);
else
temp_speed = -(speed_coeff / *GetCount);
FirstOrderRC_LPF(*speed, temp_speed, 0.2379); //滤波
no_single = 0;
*GetCount = 0;
}else if(hall_sta_edge == 1)
{
no_single = 0;
*GetCount = 0;
}else if(hall_sta_edge == 2) /* 霍尔值一直不变代表未换向 */
{
no_single++; /* 不换相时间累计 超时则判定速度为0 */
if(no_single > 15000)
{
no_single = 0;
*speed = 0; /* 超时换向 判定为停止 速度为0 */
}
}
return 0;//g_bldc_motor1.speed;
}
有个函数需要修改以上这样
文件[/hide]
|
|