STM32驱动步进电机(最全的版本寄存器+HAL库实现)

步进电机

  • 1 简介
    • 1.1 什么是步进电机
    • 1.2 步进电机和直流电机区别
    • 1.3 器材与配置
      • 1.3.1 步进电机
      • 1.3.2 驱动器
      • 1.3.3 引脚
  • 2 定时器的
  • 3 驱动代码
    • 3.1 初始化
    • 3.2 控制
  • 4. HAL库版本
    • 4.1 源码
  • 工程源码

1 简介

1.1 什么是步进电机

步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。每输入一个脉冲信号,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。因此,步进电动机又称脉冲电动机
详见百度百科:点击

1.2 步进电机和直流电机区别

种类 直流电机 步进电机
性质 将直流电能转换为机械能的电动机 将电脉冲信号转变为角位移或线位移的开环控制电机
原理 当直流电源通过电刷向电枢绕组供电时,电枢表面的N极下导体可以流过相同方向的电流,根据左手定则导体将受到逆时针方向的力矩作用;电枢表面S极下部分导体也流过相同方向的电流,同样根据左手定则导体也将受到逆时针方向的力矩作用 通常电机的转子为永磁体,当电流流过定子绕组时,定子绕组产生一矢量磁场。该磁场会带动转子旋转一角度,使得转子的一对磁场方向与定子的磁场方向一致。当定子的矢量磁场旋转一个角度。转子也随着该磁场转一个角度
主要不同 直流电机内部有随电机转动而自动换向的绕组转换zhi机构 步进电机的内部是没有绕组换向机构的

1.3 器材与配置

1.3.1 步进电机

STM32驱动步进电机(最全的版本寄存器+HAL库实现)_第1张图片

1.3.2 驱动器

1.3.3 引脚

功能 引脚
TIM3 _ch2 PB5
按键 PA0 \PC13
灯泡 PB0

2 定时器的

3 驱动代码

本设计是采用TIM3->CH2通道 PB5 ,通过改变PB5的频率 从而达到变速设置。两个按键一个是加速、一个是减速。
注!!!!
1.步进电机通电后不会转
2.步进电机驱动器有一个保护就是速度过大会自动停止电机
3.如果发出怪声音是频率问题
4.步进电机是改变频率不是改变占空比调速
所以调速就改变计时器的输出频率就ok了
5.此版本是测试版本,只是简单实现了加速和减速功能,后续会优化加速减速功能,比如缓冲停车,加速分档等等

3.1 初始化

下面展示一些 寄存器初始化

void TIM3_Configuration( void)
{
     
	
	RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
	RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
	AFIO->MAPR = AFIO_MAPR_TIM3_REMAP_1; //部分映像
	GPIOB->CRL = (GPIOB->CRL & 0XFF0FFFF0) | 0XB00003;
	TIM3->ARR = 9;
	TIM3->PSC =71;
	TIM3->RCR = 1;
	TIM3->CR1 = TIM_CR1_CKD& 0X0000;
	TIM3->CR1 &=~TIM_CR1_DIR;
	TIM3->CCMR1 |= TIM_CCMR1_OC2M |( TIM_CCMR1_CC2S&0x0000)| TIM_CCMR1_OC2PE;
	TIM3->CR1 |= TIM_CR1_ARPE;
	TIM3->CCR2 = 9/2;
	TIM3->CCER |= TIM_CCER_CC2P | TIM_CCER_CC2E;
	TIM3->EGR |= TIM_EGR_UG;
	TIM3->CR1 |= TIM_CR1_CEN;
	TIM3->BDTR |= TIM_BDTR_MOE;
	//电机
	GPIOB->CRH = (GPIOB->CRH & 0X0FFFFFFF) | 0X30000000;
	
}

3.2 控制

下面展示一些 内联代码片

// An highlighted block
int main()

{
     
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPCEN;
	GPIOA->CRL |= (GPIOA->CRL & 0XFFFFFFF0) | 0X4;
	GPIOC->CRH |= (GPIOC->CRH & 0XFF0FFFFF) | 0X400000;
	TIM3_Configuration();
	int i = 1;
	GPIOB->ODR |= GPIO_ODR_ODR0;
	while(1)
	{
     
		
		int i; 
		for(i = 0; i < 60; i++)
		{
     
			delay_ms(10);
			TIM2->CCR3 = i*5;
		}
		for(i = 60; i> 0; i--)
		{
     
			delay_ms(10);
			TIM2->CCR3 = i*5;
		}
		//减速
		if(GPIOA->IDR & GPIO_IDR_IDR0)
		{
     
			delay_ms(1000);
			GPIOB->ODR &=~GPIO_ODR_ODR0;
	
			if(GPIOA->IDR & GPIO_IDR_IDR0)
			{
     
				delay_ms(1000);
				i++;
				TIM3->ARR = i*50;
	
			}
		}
		//加速
		if(GPIOC->IDR & GPIO_IDR_IDR13)
		{
     
			delay_ms(1000);
			GPIOB->ODR |= GPIO_ODR_ODR0;
			if(GPIOA->IDR & GPIO_IDR_IDR13)
			{
     
				delay_ms(1000);
				i--;
				TIM3->ARR = i*5;
			}
		}
		if(i > 10 || i <= 1)
			i = 1;
	}

}

4. HAL库版本

4.1 源码

HAL库的初始化笔者直接在STM32Cube.mx中生成的,这里给出生成的代码,和控制代码

main.c

// An highlighted block
#include <stm32f1xx.h>
#include <stdio.h>
UART_HandleTypeDef huart1;
TIM_HandleTypeDef timhandle;
TIM_OC_InitTypeDef timoc;
void Error_Handler(void);
int i = 79;
void led_init()
{
     
	GPIO_InitTypeDef gpio = {
     0};
	gpio.Mode = GPIO_MODE_OUTPUT_PP;
	gpio.Pin = GPIO_PIN_1 |GPIO_PIN_0;
	gpio.Pull = GPIO_NOPULL;
	gpio.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB, &gpio);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1| GPIO_PIN_0 ,GPIO_PIN_RESET);
	
}
void pwm_init()
{
     
	/*PB5*/
	GPIO_InitTypeDef gpio = {
     0};
	gpio.Mode = GPIO_MODE_AF_PP;
	gpio.Pin = GPIO_PIN_5;
	gpio.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB, &gpio);
	
	/*TIM3 CH2*/
	__HAL_RCC_TIM3_CLK_ENABLE();
	__HAL_RCC_AFIO_CLK_ENABLE();
	__HAL_AFIO_REMAP_TIM3_PARTIAL();

	timhandle.Init.Period = i;
	timhandle.Init.Prescaler = 25;
	timhandle.Init.CounterMode = TIM_COUNTERMODE_UP;
	timhandle.Instance=TIM3;
	HAL_TIM_PWM_Init(&timhandle);

	timoc.Pulse = 4;
	timoc.OCMode = TIM_OCMODE_PWM2;
	HAL_TIM_PWM_ConfigChannel(&timhandle,&timoc,TIM_CHANNEL_2);//配置TIM3通道2    
	HAL_TIM_PWM_Start(&timhandle,TIM_CHANNEL_2);//开启PWM通道2


}
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
     
  GPIO_InitTypeDef GPIO_InitStruct = {
     0};
  if(huart->Instance==USART1)
  {
     
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }

}
/**
* @brief UART MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
     
  if(huart->Instance==USART1)
  {
     
  /* USER CODE BEGIN USART1_MspDeInit 0 */

  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();
  
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

  /* USER CODE BEGIN USART1_MspDeInit 1 */

  /* USER CODE END USART1_MspDeInit 1 */
  }

}
/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{
     

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_MultiProcessor_Init(&huart1, 0, UART_WAKEUPMETHOD_IDLELINE) != HAL_OK)
  {
     
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
     
  GPIO_InitTypeDef GPIO_InitStruct = {
     0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();


  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);

  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

}


/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
     
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}
int main(void)
{
     

	HAL_Init();
	HAL_UART_MspDeInit(&huart1);
	MX_USART1_UART_Init();
	MX_GPIO_Init();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_USART1_CLK_ENABLE();
	led_init();
	pwm_init();
	
	while(1){
     
	if(i <20  && i > 7199)
		i = 500;
	
	}
}


void EXTI0_IRQHandler(void)
{
     
	i -= 20;
//	timhandle.Init.Period = i*10;
	TIM3->ARR = 500;
  /* USER CODE BEGIN EXTI0_IRQn 0 */
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */
}

void EXTI15_10_IRQHandler(void)
{
     
	i += 100;
//	timhandle.Init.Period = i*10;
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
	TIM3->ARR = 10;
  /* USER CODE END EXTI15_10_IRQn 0 */
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}

工程源码

1.csdn:点击
2.在微信搜索:MeiXiangDao2020 关注公众号:媒想到叭。 然后回复: 步进电机

你可能感兴趣的:(STM32学习笔记,单片机,stm32,驱动程序)