FOC开发-结合HALL传感器进行方波控制

使用器件:

电机:三相八线霍尔无刷

主控:stm32f103rct6

12V可调电源

示波器

参考文章:

https://blog.csdn.net/qlexcel/article/details/95227991

https://blog.csdn.net/qq_39587650/article/details/121323671

第一步:

配置HALL引脚,通过位操作读取扇区值,之后自行通过显示屏显示出霍尔状态值看是否正确,代码如下:

void Hall_Init(void) //初始化引脚
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
 
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	   
    GPIO_Init(GPIOA, &GPIO_InitStructure);

}

uint8_t Hall_read(void) //读取霍尔状态值
{
	uint8_t state;
    //U
    //if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2) != 0)
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) != 0)
    {
        state |= 0x01 << 2;
    }
    //V
    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) != 0)
    {
        state |= 0x01 << 1;
    }
    //W
    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) != 0)
    {
        state |= 0x01 << 0;
    }
    return state;
}

第二步:配置PWM模块

void PWMGPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB| 
    RCC_APB2Periph_TIM1, ENABLE);
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //H1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //H2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //H3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_PinLockConfig(GPIOA, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 );    //防止后面误修改
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //L1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //L2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //L3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void TIM1_Mode_Config(void) //¶¨Ê±Æ÷ÅäÖÃ
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
	
    TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD;                 //装载值
    TIM_TimeBaseStructure.TIM_Prescaler = PWM_PRSC;                //分频
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;        //
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; //中间对齐模式
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 1;        //触发设置
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
 
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;              //PWM1模式
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //使能
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//使能
    TIM_OCInitStructure.TIM_Pulse = 800;                           //
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;      //达到比较值时输出高电平
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;    //与正通道形成互补输出,电平绝对值一致,但反向
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;   //初始为低,关闭高侧mos
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;   //打开低侧mos,锁死电机

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);                     
 
    TIM_OCInitStructure.TIM_Pulse = 800;                         
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);                      
 
    TIM_OCInitStructure.TIM_Pulse = 800;                         
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);                     

    TIM_CtrlPWMOutputs(TIM1, ENABLE);                      
    //TIM_CtrlPWMOutputs(TIM1, DISABLE)	
    TIM_Cmd(TIM1, ENABLE);    
}

第三步:

通过示波器,检测PWM是否正常工作

第四步:

结合HALL检测到的状态值,进行六步方波控制。

对比SVPWM缺点: 噪声大  效率低                   优点:操作简单

代码如下:

void fanbo_ctrl(void)
{
	int Tu,Tv,Tw;
    state_sector=Hall_read(); //读取扇区
    OLED_ShowNum(4,1,state_sector,1);  //显示扇区值
	switch(state_sector)
	{
		case 1: //扇区1
			Tu = fanbo_pwm; //fanbo_pwm自行设定
			Tv = fanbo_pwm;
			Tw = 0;
			break;
		case 2: //扇区2
			Tu = fanbo_pwm;
			Tv = 0;
			Tw = fanbo_pwm;
			break;
		case 3: //扇区3
			Tu = fanbo_pwm;
			Tv = 0;
			Tw = 0;
			break;
		case 4: //扇区4
			Tu = 0;
			Tv = fanbo_pwm;
			Tw = fanbo_pwm;
			break;
		case 5: //扇区5
			Tu = 0;
			Tv = fanbo_pwm;
			Tw = 0;
			break;
		case 6: //扇区6
			Tu = 0;
			Tv = 0;
			Tw = fanbo_pwm;
			break;
		default: //other
			Tu = 0;
			Tv = 0;
			Tw = 0;
	}
	TIM1->CCR1 = Tu;
	TIM1->CCR2 = Tv;
	TIM1->CCR3 = Tw;
}

对应扇区的Tu、Tv、Tw如何配置,结合六个扇区中,每相对转子产生的电磁力矢量叠加起来的总矢量,该总矢量的方向将对转子产生直接作用。

最后一步:

给电机输出对应PWM值,电机转起来了!!!!!!

开环六步方波驱动成功,后面将进入电流环调试。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值