新手入门
- 积分
- 12
- 金钱
- 12
- 注册时间
- 2023-4-19
- 在线时间
- 2 小时
|
1金钱
各位大佬,小弟使用STM32F103的定时器编码器接口模式来驱动编码器,想要实现的目的是当TIM_GetCounter(TIM3)==15000时电机反向,代码如下,现象是当到达15000时MOTOR_DIR_PIN控制方向的引脚只有一瞬间切换高低电平,电机不反向,这是什么原因呢?
电机的代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
/* 定义GPIO引脚,用于控制电机的方向和使能 */
#define MOTOR_DIR_PIN GPIO_Pin_12
#define MOTOR_EN_PIN GPIO_Pin_14
#define MOTOR_GPIO GPIOB
// 定义电机的运动状态
enum MotorDirectionState {
MOTOR_FORWARD,
MOTOR_BACKWARD,
MOTOR_STOPPED
};
volatile enum MotorDirectionState DR_State = MOTOR_FORWARD;
void Motor_Init(void)
{
// 电机方向控制引脚配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStruct.GPIO_Pin = MOTOR_DIR_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_SetBits(MOTOR_GPIO, MOTOR_DIR_PIN);
}
int16_t encoder_count = 0;
void TIM3_IRQHandler(void) {
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
int16_t current_count = (int16_t)TIM_GetCounter(TIM3);
int16_t count_diff = current_count - encoder_count;
encoder_count = current_count;
if (count_diff >= 0)
{
if(DR_State == MOTOR_FORWARD) // 修改点1: 如果电机的方向是前进,则反转。
{
DR_State = MOTOR_BACKWARD;
GPIO_ResetBits(MOTOR_GPIO, MOTOR_DIR_PIN); // 设置电机的方向引脚为低电平
}
else if (DR_State == MOTOR_BACKWARD) {
DR_State = MOTOR_FORWARD;
GPIO_SetBits(MOTOR_GPIO, MOTOR_DIR_PIN);
}
} else if (count_diff < 0)
{
if(DR_State == MOTOR_BACKWARD) // 修改点2: 如果电机的方向是倒退,则将电机方向设为前进
{
DR_State = MOTOR_FORWARD;
GPIO_SetBits(MOTOR_GPIO, MOTOR_DIR_PIN); // 设置电机的方向引脚为高电平
}
else if (DR_State == MOTOR_FORWARD) {
DR_State = MOTOR_BACKWARD;
GPIO_ResetBits(MOTOR_GPIO, MOTOR_DIR_PIN);
}
}
TIM_SetCounter(TIM3, 0);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
}
定时器代码
#include "stm32f10x.h" // Device header
/* 定义编码器引脚 */
#define ENCODER_A_PIN GPIO_Pin_6
#define ENCODER_B_PIN GPIO_Pin_7
#define ENCODER_GPIO GPIOA
#define ENCODER_COUNT__PIN GPIO_Pin_13
#define ENCODER_COUNT_GPIO GPIOB
void Encoder_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // GPIO_Mode_IN_FLOATING GPIO_Mode_IPU
GPIO_InitStruct.GPIO_Pin = ENCODER_A_PIN | ENCODER_B_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ENCODER_GPIO, &GPIO_InitStruct);
TIM_ICInitTypeDef Tim_ICInitStruct;
TIM_ICStructInit(&Tim_ICInitStruct);
Tim_ICInitStruct.TIM_Channel = TIM_Channel_1;
Tim_ICInitStruct.TIM_ICFilter = 0xF;
TIM_ICInit(TIM3, &Tim_ICInitStruct);
Tim_ICInitStruct.TIM_Channel = TIM_Channel_2;
Tim_ICInitStruct.TIM_ICFilter = 0xF;
TIM_ICInit(TIM3, &Tim_ICInitStruct);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = 15000; // 0xFFFF
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitTypeDef NVIC_InitStructer;
NVIC_InitStructer.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructer.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructer.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructer.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructer);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_SetCounter(TIM3, 0);
TIM_Cmd(TIM3, ENABLE);
}
|
|