STM32 제어 스테퍼 모터: HAL 라이브러리 타이머 인터럽트를 기반으로 하는 폐쇄 루프 스테퍼 모터 드라이브 + 펄스 수의 정밀 제어
1. 스테퍼 모터 폐쇄 루프 드라이버
이 기사에 사용된 스테퍼 모터 폐루프 드라이버는 Emm42_V4.0 스테퍼 모터 폐루프 드라이버입니다. 폐쇄 루프 드라이버에는 토크, 속도 및 위치의 3루프 제어를 실현할 수 있는 자체 FOC 벡터 폐쇄 루프 제어 알고리즘이 있습니다.
아래 그림과 같이 42단 폐루프 모터 드라이버의 A+, A-, B+, B-가 스테퍼 모터에 연결되어 있으며, 스테퍼 모터는 인에이블, 펄스, 인에이블을 통해 구동 및 제어된다. 오른쪽에 방향 터미널이 있습니다.
두 번째, CubeMx 구성
먼저 시계 구성이 필요합니다.
1、시계 구성
클록을 구성하기 전에 먼저 Pinout & Configuration에서 RCC를 열고 Crystal/Ceramic Resonator를 선택하여 외부 수정 발진기를 열어야 합니다.
그런 다음 아래 그림과 같이 마이크로컨트롤러의 외부 수정 발진기 주파수에 따라 매개변수를 설정하십시오.
2. 펄스 단자 타이머 구성
다시 핀아웃 및 구성으로 돌아가 타이머에서 원하는 타이머를 선택합니다. 여기서는 타이머 2를 선택한 다음 내부 시계를 켭니다(클럭 소스: 내부 시계).
채널 기능을 PWM 출력(PWM Generation)으로 구성합니다. 여기서는 4개의 스테퍼 모터를 사용했기 때문에 4개의 채널이 선택되었습니다. (다음 비디오는 스테퍼 모터만 보여주며 다른 스테퍼 모터에도 마찬가지입니다. 배선 및 추가 프로그램은 괜찮습니다.)
그런 다음 NVIC 설정을 열어 타이머 인터럽트를 활성화합니다. 아래 그림과 같이.
다음으로, 이전 단계에서 설정한 시계와 드라이브가 전달할 수 있는 주파수에 따라 타이머의 주파수를 설정합니다.
예를 들어, 내가 사용하는 드라이버의 최대 펄스 주파수는 120KHZ이고 최대 속도는 2200+ 회전입니다. 즉, 최고 속도를 달성하려면 스텝 각도가 1.8°인 스테퍼 모터를 구성하면 됩니다. 16개 분할, 즉 (360 ¼ 1.8) × 16 = 1회전당 3200펄스( 제어 펄스 수는 아래에 언급됨)로 하고 120K ¼ 3200 = 37.5회전/초, 즉 2250회전/초를 사용합니다. 분. 아래 그림과 같이 내 tim2는 APB1에 속해 있으며 시계 설정은 84MHZ입니다.
내가 사용하는 마이크로 컨트롤러는 STM32F407이므로 여기의 APB1 버스는 일반 타이머 tim2 ~ 5, 기본 타이머 tim6, tim7 및 일반 타이머 tim12 ~ 14에 해당합니다. APB2 버스는 고급 타이머 tim1, tim8 및 범용 타이머 tim9 ~ 11에 해당합니다.
따라서 APB1 타이머 클럭 주파수를 APB2 클럭 주파수로 오용하지 않도록 주의하십시오 .
따라서 내 구성을 예로 들면, 84M ¼ 120K = 700을 사용하고, 이 700을 사용하여 아래 그림과 같이 프리스케일러 계수와 카운팅 주기를 할당합니다. 여기서는 추후 PWM 듀티 사이클 설정의 편의를 위해 카운팅 주기를 100으로 설정하고 PSC는 7로 설정한다.
공식: PWM 출력 주파수 = 타이머 클럭 주파수 ¼ ((psc+1) × (arr + 1)).
오실로스코프를 이용하여 주파수와 파형에 문제가 있는지 확인하고, 아래에서 사용된 프로그램을 듀티사이클 50%, 주파수 120KHZ로 자세히 설명하겠습니다.
3. 터미널 핀 구성 활성화 및 방향 지정
아래 그림과 같이 사용하려는 핀을 마우스 왼쪽 버튼으로 클릭하여 출력으로 구성하면 매우 간단합니다. 여기서는 PC0-4를 활성화 단자로 사용하고 PG0-4를 방향 단자로 사용하며, 필요한 기능을 차지하지 않는 핀은 필요에 따라 간단한 하이 레벨 및 로우 레벨 출력 핀으로 선택할 수 있습니다.
그런 다음 프로젝트 관리자에 들어가 프로젝트 이름과 컴파일 환경을 구성하고 .c, .h 파일 등을 생성하면 문제가 없습니다.
세 가지, STM32F407 타이머 인터럽트 제어 스테퍼 모터 프로그램
먼저 핀 구성 다이어그램을 넣으면 프로그램이 좀 더 명확해 보입니다.
0. 핀 구성도
핀 구성은 아래와 같습니다.
1. 사용된 HAL 라이브러리 기능
이 두 기능의 기능은 아래에서 설명됩니다.
HAL_TIM_PWM_Stop(&htimx,TIM_CHANNEL_x);
HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_x);
2. 펄스 트리거 타이머 초기화 구성
CubeMx로 생성된 프로젝트에서는 이전에 설정한 타이머에 따라 초기화 프로그램을 찾은 후 프로그램 마지막에 다음 프로그램을 추가하면 되는데, 구성한 타이머와 채널에 따라 매개변수를 구성해야 합니다 . . 타이머 2로 설정된 경우 Ctrl F를 눌러 MX_TIM2_Init를 검색하세요.
// 添加程序
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
HAL_TIM_PWM_Start 함수는 위 그림과 같이 타이머 2의 4개 채널에 해당하는 PWM 출력을 시작하는 함수입니다. 다음은 HAL 라이브러리를 기반으로 제가 생성한 초기 수정 초기화 함수입니다. 아래의 PWM 설정 함수 작성의 편의를 위해 sConfigOC를 제안했는데 두 단계가 모두 필요합니다.
/* ============================== 步进电机脉冲触发定时器初始化 ============================== */
TIM_HandleTypeDef htim2;
TIM_OC_InitTypeDef Motor_PWM_sConfigOC = {
0};
/* TIM2 init function */
void Motor_PWM_MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {
0};
TIM_MasterConfigTypeDef sMasterConfig = {
0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 100-1;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
Motor_PWM_sConfigOC.OCMode = TIM_OCMODE_PWM1;
Motor_PWM_sConfigOC.Pulse = 0;
Motor_PWM_sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
Motor_PWM_sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
}
3. 스테핑 모터 펄스 설정
아래 그림과 같이 스테핑 모터 1을 예로 들어 타이머 2의 채널 1의 PWM 출력을 먼저 중지한 다음 듀티 사이클을 설정하고 채널을 구성한 후 PWM을 다시 켭니다. HAL_TIM_PWM_Stop은 타이머 x 채널 x의 PWM 출력을 중지하는 함수입니다.
void Motor1_pwm_Set(int motor1_n)
{
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
Motor_PWM_sConfigOC.Pulse = motor1_n;
HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}
4. 스테퍼 모터의 방향을 활성화, 비활성화 및 변경합니다.
아래와 같이 High 레벨과 Low 레벨을 구성합니다.
void Motor1_enable(void) // 电机1使能
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);
}
void Motor1_disable(void) // 电机1失能
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
}
void Motor1_course(char course_mod) // 电机1改变方向
{
if(course_mod == 1){
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_SET);} // 正转
else if(course_mod == 0){
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_RESET);} // 反转
}
5. 스테핑 모터가 main.c 프로그램을 앞으로 회전합니다.
스테퍼 모터 1을 시작하고 듀티 사이클을 50%로 설정한 다음 앞으로 회전합니다.
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
Motor_PWM_MX_TIM2_Init();
Motor_PWM_MX_TIM2_Init(); // 定时器初始化
Motor1_pwm_Set(50); // 设置占空比为50%(50/100)
Motor1_course(1); // 正转
Motor1_enable(); // 使能
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
6. 비디오 효과 시연
스테퍼 모터 제어
4. 폐쇄 루프 스테퍼 모터는 펄스 수를 정확하게 제어합니다.
1. 사용된 HAL 라이브러리 기능
마찬가지로, 이 세 가지 기능의 기능에 대해서는 아래에서 설명합니다.
HAL_TIM_PWM_Start_IT(&htimx, TIM_CHANNEL_x);
HAL_TIM_PWM_Stop_IT(&htimx, TIM_CHANNEL_x);
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim);
2. 스테퍼 모터 드라이브 펄스 주파수 변경
먼저 스테퍼 모터의 세분화 단계 수를 16으로 설정합니다. 아래 그림과 같이 여기서는 스텝 각도가 1.8°인 스테퍼 모터가 사용됩니다. 이 매개변수 구성을 사용하면 1.8° 회전하기 위해 16개의 펄스가 전송되므로 1회전에 필요한 펄스는 (360° ¼ 1.8°) × 16 = 3200 펄스입니다.
위의 스테퍼 모터 드라이버를 기준으로 속도를 5회전/초 정도로 변경하려고 하므로 펄스 주파수를 120KHZ로 변경해야 합니다. 위에서 언급한 회전당 3200펄스를 사용하면 5회전에 16000펄스가 필요하므로 120KHZ를 16KHZ로 변경합니다. 그런 다음 PSC를 다시 계산합니다(84M 16K) 100 = 52.5입니다.
위의 스테퍼 모터 펄스 트리거 타이머 초기화 Motor_PWM_MX_TIM2_Init에서 PSC를 53으로 변경합니다.
htim2.Instance = TIM2;
htim2.Init.Prescaler = 53-1;
동시에 이전 HAL_TIM_PWM_Start() 함수를 삭제해야 합니다. 즉, 다음 프로그램을 삭제해야 합니다.
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
3. 스테퍼 모터 펄스 설정 프로그램 변경
HAL_TIM_PWM_Start 및 HAL_TIM_PWM_Stop을 더 이상 사용하지 않으므로 프로그램 변경 시 이 두 함수도 삭제해야 합니다. 스테핑 모터 1을 예로 들어 다음 프로그램으로 변경합니다.
void Motor1_pwm_Set(int motor1_n)
{
Motor_PWM_sConfigOC.Pulse = motor1_n;
HAL_TIM_PWM_ConfigChannel(&htim2, &Motor_PWM_sConfigOC, TIM_CHANNEL_1);
}
물론 지금 정의한 함수에는 PWM을 중지하는 프로그램이 없으므로 PWM을 변경하기 전에 HAL_TIM_PWM_Stop_IT를 호출하여 타이머 출력 PWM을 끄는 것을 기억해야 합니다 .
4. 타이머 PWM 인터럽트 콜백 기능
타이머 인터럽트를 사용하기 전에 프로그램에서 타이머 콜백 함수를 다시 정의해야 합니다.
선택적으로 stm32f4xx_it.c에 다음 프로그램을 추가하십시오.
/* USER CODE BEGIN 1 */
int PWM_num = 0; // 脉冲数
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance) // 确认是否为步进电机脉冲中断的回调
{
PWM_num ++;
if(PWM_num >= 3200) // 第3200次(一圈)
{
PWM_num = 0;
HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_1); // 停止输出PWM
//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10); // 翻转led灯电平
}
}
}
/* USER CODE END 1 */
위 프로그램에서 PWM_num이 누적되는 것을 볼 수 있으며, 콜백 함수가 호출될 때마다 한 번씩 누적되는 것을 볼 수 있는데, 메인 함수에서 HAL_TIM_PWM_Start_IT 함수를 한 번씩 호출해 보도록 하겠습니다. 함수는 타이머가 PWM을 출력하도록 하는 함수이고, 펄스가 전송될 때마다 콜백 함수가 호출됩니다 .
아래 그림과 같이 화살표가 가리키는 함수 HAL 라이브러리가 작성되었으며 위에서 언급한 인터럽트 콜백 함수를 호출합니다.
5. 스테퍼 모터는 한 원 앞으로 회전하고 폐쇄 루프 main.c 프로그램은
다음은 주요 기능 프로그램입니다:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
Motor_PWM_MX_TIM2_Init();
Motor1_pwm_Set(50);
HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
Motor1_course(1);
Motor1_enable();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
6. 비디오 효과 시연
폐쇄 루프 스테퍼 모터 - 펄스 수의 정밀한 제어
5. 프로그램 링크
프로그램이 패키징되어 csdn 리소스에 업로드되었습니다.
CSDN: HAL 라이브러리 STM32F407 타이머 인터럽트 제어 스테퍼 모터 프로그램
CSDN: HAL 라이브러리 STM32F407 타이머 인터럽트 제어 폐쇄 루프 스테퍼 모터 정밀 제어 펄스 수는
다음 링크를 통해 다운로드할 수도 있습니다.
STM32F407 타이머 인터럽트 제어 스테퍼 모터 프로그램 :
링크: https://pan.baidu.com/s/1svRzVW_7elkHg7wwQ4AN5A
추출 코드: hpzq
STM32F407 타이머 인터럽트 제어 폐쇄 루프 스테퍼 모터 정밀 제어 펄스 번호 :
링크: https://pan .baidu .com/s/1QIyusKAbusqyMl_VTkjKxg
추출 코드: 4rml
저는 학생이고 현재 공부하고 있습니다. 이 글은 저의 공부 노트라고 볼 수 있으니 틀린 부분이 있으면 정정해 주시기 바랍니다.