要结合电路设计对电机控制,控制有4种情况:正转、反转、制动、停止;
正转:CHx 输出PWM 时,CHxN输出低电平;
反转:CHxN 输出PWM 时,CHx输出低电平;
制动:CHxN 和CHx输出高电平;
停止:CHxN 和CHx输出低电平;
代码用到 RT-Thread 部分函数,使用 rt_pwm_disable 禁用CHxN或CHx时都是输出高电平,网上很多使用下面几个函数实现:
TIM_Cmd(TIM3 ,DISABLE);//关闭PWM输出
TIM_ForcedOC1Config(TIM3, TIM_ForcedAction_InActive);//将PWM输出强制为低
TIM_SelectOCxM(TIM3, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM3, TIM_Channel_1, TIM_CCx_Enable);
TIM_Cmd(GENERAL_TIM, ENABLE);//使能TIMER3,开始产生PWM
但是没法达到目的,主要是比较寄存器和计数寄存器是共用的;
经过测试对比后,直接采用设置引脚功能的方式,代码简单延时少,下面是代码:
typedef enum{
_e_up_down_motor_stop = 0, //!< _e_up_down_motor_stop
_e_up_down_motor_forward, //Forward 前进
_e_up_down_motor_reverse, //Reverse 倒车
_e_up_down_motor_up=_e_up_down_motor_forward, //!< _e_up_down_motor_up
_e_up_down_motor_down=_e_up_down_motor_reverse,//!< _e_up_down_motor_down
_e_up_down_motor_brake //Brake 制动
} MOTOR_UP_DOWN_CTRL;//
/**
*升降电机
* @param channel 0~3
* @param ud
* @return
*/
int rc1000::up_dowm_ctrl( rt_uint8_t channel, MOTOR_UP_DOWN_CTRL ud )
{
/** TB67H450FNG\TB67H451FNG\DRV8870\DRV8871\DRV8872
* IN1 IN2 OUT1 OUT2 Mod
* L L OFF (Hi-Z) OFF (Hi-Z) Stop, Standby mode after 1 ms
* H L H L Forward
* L H L H Reverse
* H H L L Brake
**/
const int i=0;
MOTOR_CTRL_UP_DOWN_CONF *motor = &motor_ctrl_up_down_config[ channel ];
auto _set_pin=[]( uint32_t Pin ) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = Pin;// GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;//GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
};
rt_pin_mode( motor->up, PIN_MODE_OUTPUT_OD );
rt_pin_mode( motor->dowm, PIN_MODE_OUTPUT_OD );
if(ud==_e_up_down_motor_up) { //Forward 前进
rt_pin_write( motor->up, PIN_LOW );
rt_pin_write( motor->dowm, PIN_LOW );
_set_pin( 0x01 <<( motor->dowm - GET_PIN(E, 0) ) );
} else if(ud==_e_up_down_motor_down){ //Reverse 倒车
rt_pin_write( motor->up, PIN_LOW );
rt_pin_write( motor->dowm, PIN_LOW );
_set_pin( 0x01 <<( motor->up - GET_PIN(E, 0) ) );
}else if(ud==_e_up_down_motor_brake){ //Brake 制动
rt_pin_write( motor->up, PIN_HIGH );
rt_pin_write( motor->dowm, PIN_HIGH );
} else { //Stop, Standby 停止
rt_pin_write( motor->up, PIN_LOW );
rt_pin_write( motor->dowm, PIN_LOW );
}
return 0;
}