步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。每输入一个脉冲信号,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。因此,步进电动机又称脉冲电动机
详见百度百科:点击
种类 | 直流电机 | 步进电机 |
---|---|---|
性质 | 将直流电能转换为机械能的电动机 | 将电脉冲信号转变为角位移或线位移的开环控制电机 |
原理 | 当直流电源通过电刷向电枢绕组供电时,电枢表面的N极下导体可以流过相同方向的电流,根据左手定则导体将受到逆时针方向的力矩作用;电枢表面S极下部分导体也流过相同方向的电流,同样根据左手定则导体也将受到逆时针方向的力矩作用 | 通常电机的转子为永磁体,当电流流过定子绕组时,定子绕组产生一矢量磁场。该磁场会带动转子旋转一角度,使得转子的一对磁场方向与定子的磁场方向一致。当定子的矢量磁场旋转一个角度。转子也随着该磁场转一个角度 |
主要不同 | 直流电机内部有随电机转动而自动换向的绕组转换zhi机构 | 步进电机的内部是没有绕组换向机构的 |
功能 | 引脚 |
---|---|
TIM3 _ch2 | PB5 |
按键 | PA0 \PC13 |
灯泡 | PB0 |
本设计是采用TIM3->CH2通道 PB5 ,通过改变PB5的频率 从而达到变速设置。两个按键一个是加速、一个是减速。
注!!!!:
1.步进电机通电后不会转
2.步进电机驱动器有一个保护就是速度过大会自动停止电机
3.如果发出怪声音是频率问题
4.步进电机是改变频率不是改变占空比调速
所以调速就改变计时器的输出频率就ok了
5.此版本是测试版本,只是简单实现了加速和减速功能,后续会优化加速减速功能,比如缓冲停车,加速分档等等
下面展示一些 寄存器初始化
。
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;
}
下面展示一些 内联代码片
。
// 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;
}
}
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
关注公众号:媒想到叭。 然后回复: 步进电机