ES08A舵机,stm32,cubemx,联调记录

舵机的联调
买个模拟舵机,网上好多例子,换了好几个才拼凑明白,所以记录一下,方便查看。看别人的文章终究只能想象,还是自己做一遍,让舵机动起来,才能发自内心的高兴。
主要参考了他的:
STM32-通行闸机2(HAL库)

ES08A 模拟电机,褐色:GND;红色:电源+5V;黄色信号线
黄色信号会根据PWM占空比调整位置。
舵机的控制一般需要一个20ms左右的时基脉冲
0.5ms 0度;
1.0ms 45度;
1.5ms 90度;
2.0ms 135度;
2.5ms 180度;
注意:烧录线一根或数据线一根,电压都不够,所以插两根线,才能让舵机动起来
在这里插入图片描述
配置PWM时候,分频要分一个20ms内的变化的占空比,就可以控制位置了

首先开通串口DMA:
在这里插入图片描述
模式是异步
在这里插入图片描述
全局中断要打开
在这里插入图片描述
添加DMA,收发都添加
在这里插入图片描述
波特率设置9600
在这里插入图片描述
在Timers里设置PWM
在这里插入图片描述
在Channel1里头选PWM产生CH1
在这里插入图片描述
在NVIC设置里,全局打勾
在这里插入图片描述
在参数设置里写分频
在这里插入图片描述
总频率是32MHz,32*10^6
Prescaler写320-1,这样32e6/320 = 1e5Hz,所以周期1e-5s,
配置定时器时,预分频值和period值都要减1,可以确保计时时间准确
Counter Mode上沿检测
Counter Period写2000-1
舵机要20毫秒,20e-3s ,2e-2s, 2e-2/1e-5 = 2000份儿,所以设置2000
auto-reload 不打开。。。不知道为啥,后边都不知道为啥
在这里插入图片描述
总频率32M
在这里插入图片描述
开发环境选MDK-arm,之后就生成
在这里插入图片描述
//PWM初始化时,开启中断
HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);
main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim3;

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart3_rx;
DMA_HandleTypeDef hdma_usart3_tx;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_TIM3_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

uint8_t Stateee=1;
const uint8_t buffersize=10;
uint8_t buffer3[buffersize]; // 3收
uint8_t buffer2[buffersize]; // 2收
uint8_t buffer1[buffersize]; // 1收
#include "string.h"

uint16_t angle;
void Angle_Control(uint16_t angle)
{
	uint16_t pulse;
	pulse=500+(int)(angle*100/9);
	__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,pulse);
}
/*
** Rewrite fputc function and make printf function work
**/

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);
	HAL_UART_Receive_DMA(&huart3,buffer3,buffersize);
	__HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart2,buffer2,buffersize);
	__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart1,buffer1,buffersize);
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
	
	//__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,50); //0度  1/20 * 200
	//	HAL_Delay(1000);
		Stateee = 2;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	//__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,57); //45度  1/20 * 200
	//	HAL_Delay(1000);
		//i=i+div;

//		if(i>=250)
//		{
//			div = -50;
//		}
//		else if(i<=50)
//		{
//			div = 50;
//		}

		//if(Stateee==1)
		//{
		//	__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,150); //0
		//}
		//else if(Stateee==2)
		//{
		//	__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,130); //0
		//}
		HAL_Delay(1000);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 320-1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 2000-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);

}

/**
  * @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 = 9600;
  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_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief USART3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART3_UART_Init(void)
{

  /* USER CODE BEGIN USART3_Init 0 */

  /* USER CODE END USART3_Init 0 */

  /* USER CODE BEGIN USART3_Init 1 */

  /* USER CODE END USART3_Init 1 */
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 9600;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART3_Init 2 */

  /* USER CODE END USART3_Init 2 */

}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
  /* DMA1_Channel3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
  /* DMA1_Channel4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
  /* DMA1_Channel5_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
  /* DMA1_Channel6_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
  /* DMA1_Channel7_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

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

}

/* 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 */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


stm32f1xx_it.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32f1xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
extern uint8_t Stateee;
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */

/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
const uint8_t buffersize2=10;
extern uint8_t buffer1[buffersize2];
extern uint8_t buffer2[buffersize2];
extern uint8_t buffer3[buffersize2];

int fputc(int ch, FILE *f)
{  
	/* 堵塞判断串口是否发送完成 */
  while((USART1->SR & 0X40) == RESET);
	
	/* 串口发送完成,将该字符发送 */
	USART1->DR = (uint8_t)ch;  
	
  return ch;
}

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim3;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_usart3_rx;
extern DMA_HandleTypeDef hdma_usart3_tx;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
/* USER CODE BEGIN EV */

/* USER CODE END EV */

/******************************************************************************/
/*           Cortex-M3 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable interrupt.
  */
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */

  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}

/**
  * @brief This function handles Prefetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */

  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */

  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}

/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */

  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */

  /* USER CODE END SVCall_IRQn 1 */
}

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

/******************************************************************************/
/* STM32F1xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f1xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles DMA1 channel2 global interrupt.
  */
void DMA1_Channel2_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel2_IRQn 0 */

  /* USER CODE END DMA1_Channel2_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart3_tx);
  /* USER CODE BEGIN DMA1_Channel2_IRQn 1 */

  /* USER CODE END DMA1_Channel2_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel3 global interrupt.
  */
void DMA1_Channel3_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel3_IRQn 0 */

  /* USER CODE END DMA1_Channel3_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart3_rx);
  /* USER CODE BEGIN DMA1_Channel3_IRQn 1 */

  /* USER CODE END DMA1_Channel3_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel4 global interrupt.
  */
void DMA1_Channel4_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel4_IRQn 0 */

  /* USER CODE END DMA1_Channel4_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart1_tx);
  /* USER CODE BEGIN DMA1_Channel4_IRQn 1 */

  /* USER CODE END DMA1_Channel4_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel5 global interrupt.
  */
void DMA1_Channel5_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel5_IRQn 0 */

  /* USER CODE END DMA1_Channel5_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart1_rx);
  /* USER CODE BEGIN DMA1_Channel5_IRQn 1 */

  /* USER CODE END DMA1_Channel5_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel6 global interrupt.
  */
void DMA1_Channel6_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */

  /* USER CODE END DMA1_Channel6_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_rx);
  /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */

  /* USER CODE END DMA1_Channel6_IRQn 1 */
}

/**
  * @brief This function handles DMA1 channel7 global interrupt.
  */
void DMA1_Channel7_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel7_IRQn 0 */

  /* USER CODE END DMA1_Channel7_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_tx);
  /* USER CODE BEGIN DMA1_Channel7_IRQn 1 */

  /* USER CODE END DMA1_Channel7_IRQn 1 */
}

/**
  * @brief This function handles TIM3 global interrupt.
  */
void TIM3_IRQHandler(void)
{
  /* USER CODE BEGIN TIM3_IRQn 0 */

  /* USER CODE END TIM3_IRQn 0 */
  HAL_TIM_IRQHandler(&htim3);
  /* USER CODE BEGIN TIM3_IRQn 1 */

  /* USER CODE END TIM3_IRQn 1 */
}

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
	if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!= RESET)
	{
		//清除空闲标志位
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
		HAL_UART_DMAStop(&huart1);
		uint8_t len = buffersize2-__HAL_DMA_GET_COUNTER(huart1.hdmarx);
		
		HAL_UART_Receive_DMA(&huart1,buffer1,buffersize2);
		//HAL_UART_Transmit_DMA(&huart1,buffer1,buffersize2);
		
		uint16_t i=0;
		uint8_t temp=0;
		int temop=0;
		uint8_t tempCou=0;
		for(i=0;i<len;++i)
		{
			temp=buffer1[i]-0x30;
			tempCou = len-i-1;
			while(tempCou--)
			{
				temp=temp*10;
			}
			temop+=temp;
		}
		printf("%d",temop);
		__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,temop);
		
		memset(buffer1,'\0',buffersize2);
	}
	
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
	if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)!= RESET)
	{
		//清除空闲标志位
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);
		HAL_UART_DMAStop(&huart2);
		uint8_t len = buffersize2-__HAL_DMA_GET_COUNTER(huart2.hdmarx);
		
		//HAL_UART_Transmit_DMA(&huart1,buffer2,len);
		HAL_UART_Receive_DMA(&huart2,buffer2,buffersize2);
		if(buffer2[0]=='1')
		{
			Stateee=1;
			//__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,170); //0
		}
		else if(buffer2[0]=='2')
		{
			Stateee=2;
			//__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,130); //0
		}
		
		memset(buffer2,'\0',buffersize2);
	}
	
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

/**
  * @brief This function handles USART3 global interrupt.
  */
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */

  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */


注意这里,设置占空比
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,150); //0度 1/20 * 200

对于0度,0.5/20=0.025,0.025*2000 = 50
但是实际上56比较好
电机正立,最右边是0度,立起来是90度,最左边是180度
56:0度
在这里插入图片描述
100:45度
在这里插入图片描述
150:90度
在这里插入图片描述
程序安排USART1是串口与上位机串口助手通讯,上位机发送数据直接控制PWM脉冲数
重写了printf,所以在这里插入图片描述
这样在串口助手里写 50,150 ,250,就可以控制舵机摆动到在0到180度的位置了。
在这里插入图片描述

<think>好的,用户之前让我帮忙写了一个基于STM32F103C8T6控制松甲科技舵机的模块化代码,现在他问的是关于“zx15s舵机”的介绍。我需要先确定zx15s舵机的具体型号和品牌,可能用户提到的zx15s是某个特定厂家生产的型号,比如辉盛或者银燕之类的常见品牌。不过用户可能拼写有误,比如可能是SG90或者MG995之类的常见型号,但zx15s也可能是某个特定型号,需要先查证。 首先,我应该回忆常见的舵机型号,比如Tower Pro的SG90、MG996R,或者银燕的ES08MA等。但zx15s不太常见,可能需要推测。假设用户可能指的是辉盛舵机的某个型号,比如HX15S,或者是其他品牌。也有可能用户提到的松甲科技之前的问题中的舵机型号可能有误,或者zx15s是他们特定的型号。如果找不到相关信息,可能需要基于常见的参数进行介绍,同时建议用户确认型号。 接下来,我需要考虑用户的需求。用户之前在做舵机控制,现在询问zx15s,可能是想了解该舵机的参数,以便调整代码中的PWM参数,比如脉冲宽度、周期等。或者他们可能在使用过程中遇到了问题,需要根据舵机规格调整代码。因此,我的回答需要包括舵机的基本参数,如工作电压、扭矩、速度、尺寸、重量,以及PWM信号的要求,如周期、脉冲范围等。 另外,用户可能需要知道如何将之前的代码适配到zx15s舵机上,所以需要说明如果参数不同,应该如何修改代码中的MIN_PULSE和MAX_PULSE,或者检查周期是否符合。例如,如果zx15s的脉冲范围是500-2500微秒,那么之前的代码是适用的,否则需要调整。 还要注意用户可能的错误,比如接线问题,电源不足,或者舵机角度控制不准确,所以回答中需要包含注意事项,比如独立供电,避免堵转,以及机械安装方面的建议。 如果zx15s的信息确实难以找到,可能需要指出这一点,并建议用户查阅产品手册或联系供应商,同时基于常见舵机的参数给出一般性指导。这样既保证了准确性,又提供了实用的建议。 最后,保持回答结构清晰,分点说明,确保用户能够根据回答调整他们的代码和硬件连接,确保舵机正常工作。同时提醒用户注意安全,避免电流过大损坏单片机舵机。</think>以下是关于 **ZX15S舵机** 的技术介绍与使用说明(基于常见舵机参数,具体以实际型号手册为准): --- ### **一、ZX15S舵机核心参数** 1. **基本规格** - **工作电压**:$4.8V \sim 6.8V$(典型值5V) - **堵转扭矩**:$15kg\cdot cm$(6V电压下) - **动作速度**:$0.15sec/60^{\circ}$(6V无负载) - **转动角度**:$0^{\circ} \sim 180^{\circ}$(可定制范围) - **接口类型**:3线制(信号+电源+GND) 2. **PWM信号要求** - **周期**:$$T = 20ms \quad (f = 50Hz)$$ - **脉冲宽度**: $$0.5ms \leq t \leq 2.5ms \quad \text{对应} \quad 0^{\circ} \sim 180^{\circ}$$ - **线性关系**: $$angle = \frac{(t - 500)}{2000} \times 180^{\circ} \quad (t \text{单位:微秒})$$ --- ### **二、与STM32的适配要点** 1. **硬件连接** - **信号线**:接STM32 PWM输出引脚(如PA0-TIM2_CH1) - **电源线**:需外接独立电源(避免MCU供电不足) - **推荐电路**: ```plaintext STM32 PWM引脚 → 舵机信号线 外部5V电源 → 舵机+VCC STM32 GND ↔ 外部电源GND ↔ 舵机GND(共地) ``` 2. **代码调整建议** 在之前提供的舵机驱动代码中,需确认以下参数匹配: ```c #define PWM_PERIOD 20000 // 20ms周期(1MHz时基) #define MIN_PULSE 500 // 0度脉冲宽度(ZX15S可能需要调整) #define MAX_PULSE 2500 // 180度脉冲宽度 ``` **验证方法**:通过实际测试校准角度与脉冲的对应关系。 --- ### **三、常见问题处理** 1. **舵机抖动** - 检查PWM信号稳定性(示波器观察波形) - 确保电源功率足够(瞬时电流可达$500mA \sim 1A$) 2. **角度偏差** - 使用`Servo_SetAngle(90)`测试中位,微调脉冲值 - 机械安装需留出活动余量(避免物理限位卡死) 3. **多舵机控制** - 同一定时器的不同通道可输出多路PWM - 例:TIM2_CH1(PA0)、TIM2_CH2(PA1)可独立控制2个舵机 --- ### **四、选型对比** | 特性 | ZX15S | SG90(常见微型舵机) | |------------|-----------------|---------------------| | 扭矩 | 15kg·cm(6V) | 1.8kg·cm(4.8V) | | 速度 | 0.15s/60° | 0.12s/60° | | 适用场景 | 机械臂、足式机器人 | 摄像头云台、小负载结构 | | 价格 | 中高(¥40-60) | 低(¥10-20) | --- ### **五、注意事项** 1. 避免长时间堵转(可能烧毁电机) 2. 金属齿轮型号需定期润滑 3. 信号线长度不宜超过1米(防止干扰) 如需进一步优化控制,可研究**角度闭环控制**(通过电位器反馈)或使用串行总线舵机(如UART/RS485协议)。建议结合具体应用场景选择舵机型号!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胸毛男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值