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);
}