STM32驱动无刷直流电机学习(2)

17 篇文章 0 订阅
6 篇文章 17 订阅

stm32 通过 IRS2101S 将驱动io 升压,再驱动 N沟道MOS管 IRF540NS

N沟道MOS管是通过 高电平导通 低电平禁止的

PWM1H PWM2H PWM3H 分别接 PA8 PA9 PA10 对应的是 TIM1的pwm 输出

PWM1L PWM2L PWM3L 分别接 PB13 PB14 PB15 对应的是 TIM1的pwm的互补 输出

本代码 采用 H_PWM L_ON 的驱动模式  就是 上臂管 采用 PWM 进行驱动 下臂管 直接打开或者关闭

TIM1的初始化,采用 PWM1 模式,有效电平为低电平,则每个pwm 周期 先低电平 后高电平, 高电平导通 mos管

#define H_PWM_L_ON		0
#define H_PWM_L_PWM		1
#ifndef _MOTOR_DRV_MODE_
#define _MOTOR_DRV_MODE_ H_PWM_L_ON
#endif

#define MOTORU	PerpheralBit(GPIOB->ODR,13)		//D11
#define MOTORV	PerpheralBit(GPIOB->ODR,14)		//D10
#define MOTORW	PerpheralBit(GPIOB->ODR,15)		//D10


void Tim1PwmGPIOInit(void)
{
	SetPinState(GPIOA,GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10,GPIO_Mode_AF_PP);
#if(_MOTOR_DRV_MODE_==H_PWM_L_ON)
	SetPinState(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15,GPIO_Mode_Out_PP);
	MOTORU=0;
	MOTORV=0;
	MOTORW=0;
#endif
#if(_MOTOR_DRV_MODE_==H_PWM_L_PWM)
	SetPinState(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15,GPIO_Mode_AF_PP);
#endif
}


void DcMotorTim1Init(INT32U pwm_period,INT32U frequency)
{
 	NVIC_InitTypeDef NVIC_InitStructure;  
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_BDTRInitTypeDef 	TIM_BDTRInitStructure;

	Tim1PwmGPIOInit(); 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能 TIMx 外设
	TIM_DeInit(TIM1);

	TIM_TimeBaseStructure.TIM_Period = pwm_period-1; 							//设置自动重装载周期值
	TIM_TimeBaseStructure.TIM_Prescaler =TMRNCLK/frequency/pwm_period-1; 		//设置预分频值 不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 								//设置时钟分割:TDTS = Tck_tim			这里是 32M
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 				//向上计数
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);								//初始化 TIMx
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_Pulse =0;									   		//PWM占空比
	
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;			   		//上桥臂
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low ;			   		//下桥臂

	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
	
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);						 			
	TIM_OC2Init(TIM1, &TIM_OCInitStructure);
	TIM_OC3Init(TIM1, &TIM_OCInitStructure);
	
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);				
	TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
	TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
	
	TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
	TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
	TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
		   
	TIM_BDTRInitStructure.TIM_DeadTime = 0x6A;									//死区1.8us	
	TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
	TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;		  
	TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
	TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
	  
	TIM_ClearFlag(TIM1, TIM_FLAG_Update);  
	TIM_ClearITPendingBit(TIM1, TIM_IT_Update);							 //清中断标志位
	TIM_ITConfig(TIM1,TIM_IT_Update ,ENABLE);							   //打开中断 
	
	TIM_Cmd(TIM1, ENABLE);
	TIM_CtrlPWMOutputs(TIM1, ENABLE);

#if 0	
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
#endif

}

通过串口 输入 字符 '0','1','2'...'5' 可以看到电机进i行转动一定的角度

#define PWM_TEST	60
void DemoTask(void *pt)
{
	INT32U d=0,hall;
	INT8U err;
	SysTick_CounterCmd(SysTick_Counter_Enable);								//系统时钟开始计数	
	DcMotorTim1Init(256,1000);
	SetPinState(GPIOC,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8,GPIO_Mode_IPU);
	OSQPost(OSQDebug,(void*)'0');
	do{
		hall=(GPIOC->IDR>>6)&0x07;
		printf("按键:%d\r\n",hall);
		d=(INT32U)OSQPend(OSQDebug,0,&err);
		switch(d)
		{
			case '0':
				MOTORU=MOTORV=MOTORW=0;
				TIM1->CCR1=PWM_TEST;			
				TIM1->CCR2=0;
				TIM1->CCR3=0;
				MOTORV=1;
				break;
			case '1':
				MOTORU=MOTORV=MOTORW=0;
				TIM1->CCR1=PWM_TEST;
				TIM1->CCR2=0;
				TIM1->CCR3=0;
				MOTORW=1;
				break;
			case '2':
				MOTORU=MOTORV=MOTORW=0;
				TIM1->CCR1=0;
				TIM1->CCR2=PWM_TEST;
				TIM1->CCR3=0;
				MOTORW=1;
				break;
			case '3':
				MOTORU=MOTORV=MOTORW=0;
				TIM1->CCR1=0;
				TIM1->CCR2=PWM_TEST;
				TIM1->CCR3=0;
				MOTORU=1;
				break;
			case '4':
				MOTORU=MOTORV=MOTORW=0;
				TIM1->CCR1=0;
				TIM1->CCR2=0;
				TIM1->CCR3=PWM_TEST;
				MOTORU=1;
				break;
			case '5':
				MOTORU=MOTORV=MOTORW=0;
				TIM1->CCR1=0;
				TIM1->CCR2=0;
				TIM1->CCR3=PWM_TEST;
				MOTORV=1;
				break;
			default:
				TIM1->CCR1=0;
				TIM1->CCR2=0;
				TIM1->CCR3=0;
				MOTORU=MOTORV=MOTORW=0;
				break;
		}
		MOTORU=MOTORV=MOTORW=0;
		OSTimeDly(OS_TICKS_PER_SEC/30);
		TIM1->CCR1=0;
		TIM1->CCR2=0;
		TIM1->CCR3=0;
		MOTORU=MOTORV=MOTORW=0;
	}while(1);
}

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值