步进电机控制
#include "./stepper/bsp_stepper_init.h"
#include "./delay/core_delay.h"
#include "stm32f4xx.h"
void TIM_SetTIMxCompare(TIM_TypeDef *TIMx,uint32_t channel,uint32_t compare);
void TIM_SetPWM_period(TIM_TypeDef* TIMx,uint32_t TIM_period);
TIM_HandleTypeDef TIM_TimeBaseStructure;
__IO uint16_t OC_Pulse_num = 200; //比较输出的计数值
/**
* @brief 中断优先级配置
* @param 无
* @retval 无
*/
static void TIMx_NVIC_Configuration(void)
{
/* 外设中断配置 */
HAL_NVIC_SetPriority(MOTOR_PUL_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(MOTOR_PUL_IRQn);
}
/**
* @brief 配置TIM复用输出PWM时用到的I/O
* @param 无
* @retval 无
*/
static void Stepper_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*开启Motor相关的GPIO外设时钟*/
MOTOR_DIR_GPIO_CLK_ENABLE();
MOTOR_PUL_GPIO_CLK_ENABLE();
MOTOR_EN_GPIO_CLK_ENABLE();
/*选择要控制的GPIO引脚*/
GPIO_InitStruct.Pin = MOTOR_DIR_PIN;
/*设置引脚的输出类型为推挽输出*/
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull =GPIO_PULLUP;
/*设置引脚速率为高速 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
/*Motor 方向引脚 初始化*/
HAL_GPIO_Init(MOTOR_DIR_GPIO_PORT, &GPIO_InitStruct);
/*Motor 使能引脚 初始化*/
GPIO_InitStruct.Pin = MOTOR_EN_PIN;
HAL_GPIO_Init(MOTOR_EN_GPIO_PORT, &GPIO_InitStruct);
/* 定时器通道1功能引脚IO初始化 */
/*设置输出类型*/
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
/*设置引脚速率 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
/*设置复用*/
GPIO_InitStruct.Alternate = MOTOR_PUL_GPIO_AF;
/*设置复用*/
GPIO_InitStruct.Pull =GPIO_PULLUP;
/*选择要控制的GPIO引脚*/
GPIO_InitStruct.Pin = MOTOR_PUL_PIN;
/*Motor 脉冲引脚 初始化*/
HAL_GPIO_Init(MOTOR_PUL_PORT, &GPIO_InitStruct);
}
/*
* 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
* 另外三个成员是通用定时器和高级定时器才有.
*-----------------------------------------------------------------------------
* TIM_Prescaler 都有
* TIM_CounterMode TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_Period 都有
* TIM_ClockDivision TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器)
*-----------------------------------------------------------------------------
*/
void TIM_PWMOUTPUT_Config(void)
{
TIM_OC_InitTypeDef TIM_OCInitStructure;
/*使能定时器*/
MOTOR_PUL_CLK_ENABLE();
TIM_TimeBaseStructure.Instance = MOTOR_PUL_TIM;
/* 累计 TIM_Period个后产生一个更新或者中断*/
//当定时器从0计数到TIM_PERIOD-1,即为TIM_PERIOD次,为一个定时周期
TIM_TimeBaseStructure.Init.Period = TIM_PERIOD-1;
// 通用控制定时器时钟源TIMxCLK = HCLK=168MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=1MHz
TIM_TimeBaseStructure.Init.Prescaler = 168-1;
/*计数方式*/
TIM_TimeBaseStructure.Init.CounterMode = TIM_COUNTERMODE_UP;
/*采样时钟分频*/
TIM_TimeBaseStructure.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
TIM_TimeBaseStructure.Init.RepetitionCounter = 0 ;
/*初始化定时器*/
HAL_TIM_OC_Init(&TIM_TimeBaseStructure);
/*PWM模式配置--这里配置为输出比较模式*/
TIM_OCInitStructure.OCMode = TIM_OCMODE_TOGGLE;
/*比较输出的计数值*/
TIM_OCInitStructure.Pulse = OC_Pulse_num;
/*当定时器计数值小于CCR1_Val时为高电平*/
TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
/*设置互补通道输出的极性*/
TIM_OCInitStructure.OCNPolarity = TIM_OCNPOLARITY_LOW;
/*快速模式设置*/
TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
/*空闲电平*/
TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_RESET;
/*互补通道设置*/
TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
HAL_TIM_OC_ConfigChannel(&TIM_TimeBaseStructure, &TIM_OCInitStructure, MOTOR_PUL_CHANNEL_x);
/* 确定定时器 */
HAL_TIM_Base_Start(&TIM_TimeBaseStructure);
/* 启动比较输出并使能中断 */
HAL_TIM_OC_Start_IT(&TIM_TimeBaseStructure,MOTOR_PUL_CHANNEL_x);
/*使能比较通道*/
TIM_CCxChannelCmd(MOTOR_PUL_TIM,MOTOR_PUL_CHANNEL_x,TIM_CCx_ENABLE);
}
/**
* @brief 定时器中断函数
* @note 无
* @retval 无
*/
void MOTOR_PUL_IRQHandler(void)
{
HAL_TIM_IRQHandler(&TIM_TimeBaseStructure);
}
/**
* @brief 定时器比较中断
* @param htim:定时器句柄指针
* @note 无
* @retval 无
*/
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
__IO uint16_t count;
/*获取当前计数*/
count=__HAL_TIM_GET_COUNTER(htim);
/*设置比较数值*/
__HAL_TIM_SET_COMPARE(htim, MOTOR_PUL_CHANNEL_x, count + OC_Pulse_num);
}
/**
* @brief 设置TIM通道的占空比
* @param channel 通道 (1,2,3,4)
* @param compare 占空比
* @note 无
* @retval 无
*/
void TIM8_SetPWM_pulse(int channel,int compare)
{
switch(channel)
{
case 1: __HAL_TIM_SET_COMPARE(&TIM_TimeBaseStructure,TIM_CHANNEL_1,compare);break;
case 2: __HAL_TIM_SET_COMPARE(&TIM_TimeBaseStructure,TIM_CHANNEL_2,compare);break;
case 3: __HAL_TIM_SET_COMPARE(&TIM_TimeBaseStructure,TIM_CHANNEL_3,compare);break;
case 4: __HAL_TIM_SET_COMPARE(&TIM_TimeBaseStructure,TIM_CHANNEL_4,compare);break;
}
}
/**
* @brief 引脚初始化
* @retval 无
*/
void stepper_Init()
{
/*电机IO配置*/
Stepper_GPIO_Config();
/*定时器PWM输出配置*/
TIM_PWMOUTPUT_Config();
/*中断配置*/
TIMx_NVIC_Configuration();
}
#ifndef __BSP_STEP_MOTOR_INIT_H
#define __BSP_STEP_MOTOR_INIT_H
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
/*宏定义*/
/*******************************************************/
//Motor 方向
#define MOTOR_DIR_PIN GPIO_PIN_1
#define MOTOR_DIR_GPIO_PORT GPIOE
#define MOTOR_DIR_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
//Motor 使能
#define MOTOR_EN_PIN GPIO_PIN_0
#define MOTOR_EN_GPIO_PORT GPIOE
#define MOTOR_EN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
//Motor 脉冲
#define MOTOR_PUL_IRQn TIM8_CC_IRQn
#define MOTOR_PUL_IRQHandler TIM8_CC_IRQHandler
#define MOTOR_PUL_TIM TIM8
#define MOTOR_PUL_CLK_ENABLE() __TIM8_CLK_ENABLE()
#define MOTOR_PUL_PORT GPIOI
#define MOTOR_PUL_PIN GPIO_PIN_5
#define MOTOR_PUL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
#define MOTOR_PUL_GPIO_AF GPIO_AF3_TIM8
#define MOTOR_PUL_CHANNEL_x TIM_CHANNEL_1
// 定义定时器周期,输出比较模式周期设置为0xFFFF
#define TIM_PERIOD 0xFFFF
extern void TIMx_Configuration(void);
extern void TIM8_SetPWM_pulse(int channel,int compare);
/************************************************************/
#define HIGH GPIO_PIN_SET //高电平
#define LOW GPIO_PIN_RESET //低电平
#define ON LOW //开
#define OFF HIGH //关
#define CW HIGH //顺时针
#define CCW LOW //逆时针
//控制使能引脚
/* 带参宏,可以像内联函数一样使用 */
#define MOTOR_EN(x) HAL_GPIO_WritePin(MOTOR_EN_GPIO_PORT,MOTOR_EN_PIN,x)
#define MOTOR_PLU(x) HAL_GPIO_WritePin(MOTOR_PUL_GPIO_PORT,MOTOR_PUL_PIN,x)
#define MOTOR_DIR(x) HAL_GPIO_WritePin(MOTOR_DIR_GPIO_PORT,MOTOR_DIR_PIN,x)
extern void stepper_Init(void);
extern void stepper_turn(int tim,float angle,float subdivide,uint8_t dir);
#endif /* __STEP_MOTOR_INIT_H */