直流无刷电机开环调速基于STM32F302R8+X-NUCLEO-IHM07M1(一)


前言

主控板STM32F302R8+驱动板X-NUCLEO-IHM07M1+直流无刷电机WR36BL61,实现电机的开环调速。
关于X-NUCLEO-IHM07M1驱动板的介绍,请阅读:
直流有刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(一)
直流无刷电机的驱动原理,请阅读:
直流无刷电机及Matlab/Simulink驱动仿真
直流无刷电机的六步换相驱动实现,请阅读:
直流无刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(一)

一、直流无刷电机开环调速原理

直流无刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(一)章节,当需要MOS管导通时,直接将电源加载到线圈上,电机很快飙升到最大速度,并以最大速度运行。实际应用中我们以PWM代替高低电平,把连续的开通转变为开/关交替的PWM形式,来实现调速控制。通常使用PWM控制直流无刷电机常见方法有五种:
在这里插入图片描述
本次实验采用第四种PWM控制方式:H_PWM-L_ON,即三相桥臂上管子导通时给PWM信号,下管子导通时给高电平信号,通过控制PWM的占空比即可控制加载到线圈的电压,实现电机的调速。

二、STM32F302R8+X-NUCLEO-IHM07M1直流无刷电机的开环调速

2.1.功能需求

通过按键控制直流无刷电机的转速,由于STM32F302R8控制器只有一个按键,因此只能单方向控制电机的加速或者减速,本次实验为加速实验,每按一次按键,电机的转速将增加。

2.2.硬件设计

在这里插入图片描述
控制板:STM32F302R8
驱动板:X-NUCLEO-IHM07M1
直流无刷电机:WR36BL61,额定功率10W,额定电压24V,额定电流0.5A,转速2000RMP,极对数2。
在这里插入图片描述

2.3.软件设计

2.3.1.STM32CubeMX底层配置

1、RCC设置外接HSE(Crystal/Ceramic Resonator),时钟设置为72MHz
2、PC10、PC11、PC12设置为推挽输出、无上下拉电阻、高速,初始化状态设为0;PB13设置为推挽输出,下拉电阻、高速,初始化状态为0;PC13设置为输入,无上下拉电阻。
3、PA8设置为TIM1_CH1,PA9设置为TIM1_CH2,PA10设置为TIM1_CH3;TIM1设置为内部时钟,TIM1_CH1、TIM1_CH2、TIM1_CH3设置为PWM模式,PSC设置为36-1,向上计数,ARR设置为100-1,频率为:72000000/36/100=20KHz,其余保持默认。
4、PA15设置为TIM2_CH1,PB3设置为TIM2_CH2,PB10设置为TIM2_CH3;TIM2设置为内部时钟,TIM2设置为XOR ON/Hall Sensor Mode模式,PSC设置为72-1,向上计数,ARR值设置为1000-1频率为1KHz,Hall Sensor时钟不分频,双边沿触发(注CubeMX只能选择上升沿或者下降沿触发,生成代码后手动修改为双边沿触发),输入滤波值设置为10,不开启软件延时;开启TIM2全局中断,中断优先级设置为1,0
5、使能USART2,异步模式,波特率115200,8位数据位,1位停止位,无奇偶校验位
6、IDE设置为MDK-RAM,在Keil环境中编写应用层程序
**
**
在这里插入图片描述
**
**
在这里插入图片描述
**
**
在这里插入图片描述
**
**
在这里插入图片描述
**
**
在这里插入图片描述

2.3.2.应用层开发

在Keil环境中编写应用层程序,实现功能需求。
主函数:

int main(void)
{
  /* USER CODE BEGIN 1 */
  uint8_t count=0;
  /* 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_TIM1_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);  //开启TIM1 PWM输出
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
  
  __HAL_TIM_ENABLE_IT(&htim2,TIM_IT_TRIGGER);  //开启TIM2触发中断
  __HAL_TIM_CLEAR_IT(&htim2,TIM_IT_TRIGGER);   //清除触发中断标志位
  
  HAL_TIMEx_HallSensor_Start(&htim2);  //开启霍尔传感器功能

  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
	  if(Key_Scany(KEY_GPIO_Port,KEY_Pin)==1)  //调节占空比
	  {
		  Duty+=10;
		  
		  if(Duty>100)
			  Duty=100;
	  }
	  
	  if(Hall_InterruptFlag==0)  //开启电机时未进入触发中断,此时直接驱动电机
	  {
		  BLDC_Driver(1);
	  }
	  
	  HAL_Delay(10);
	  count++;
	  if(count%50==0)
	  {
		  count=0;
		  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);  //程序运行指示灯
	  }
	  
		  
  }
  /* USER CODE END 3 */
}

中断函数,每次霍尔状态发生变化进行电机换相驱动:

/* USER CODE BEGIN 1 */
void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim)
{
	Hall_InterruptFlag=1;
	BLDC_Driver(1);
}
/* USER CODE END 1 */

按键扫描函数Key_Scany():

/* USER CODE BEGIN 2 */
uint8_t Key_Scany(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
	if(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)==0)
	{
		while(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)==0);
		return 1;
	}
	else 
		return 0;
}
/* USER CODE END 2 */

无刷电机驱动函数BLDC_Driver()

/**************************************************/
/**WR36BL61的换相表,不同于正常直流无刷电机两两导通的
换相表,为尽大可能的利用资源,WR36BL61的换相表为每时刻
三个桥臂均有一个管子开启,厂家提供的换相表如下*******/
/*电机正转换相表**T为1代表桥臂上开下闭,T为0表示桥臂上闭下开*/
/*
 H1  H2  H3  T1  T2  T3
  0   0   1   1   0   1
  1   0   1   1   0   0
  1   0   0   1   1   0
  1   1   0   0   1   0
  0   1   0   0   1   1
  0   1   1   0   0   1
*************************************************/
/*电机反转换相表******
  0   0   1   0   1   0
  1   0   1   0   1   1
  1   0   0   0   0   1
  1   1   0   1   0   1
  0   1   0   1   0   0
  0   1   1   1   1   0
**************************************************/


void BLDC_Driver(uint8_t Dirction)  //根据获取的霍尔状态值进行采用六步换相法实现电机驱动
{
	uint8_t Hall_State=0;
	Hall_State=Get_HallState();
	
	HAL_GPIO_WritePin(GPIOC, EN1_Pin, GPIO_PIN_SET);  //使能三个桥臂
	HAL_GPIO_WritePin(GPIOC, EN2_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC, EN3_Pin, GPIO_PIN_SET);
	
	TIM1->CCR1=0;  //三路PWM的占空比设置为0,即三路桥臂均上闭下开
	TIM1->CCR2=0;
	TIM1->CCR3=0;
	
	if(Dirction==1)  //Direction为1 电机正转 否则 电机反转
	{
		switch(Hall_State)
		{
			case 1:
				TIM1->CCR1=Duty;
				TIM1->CCR2=0;
				TIM1->CCR3=Duty;
			break;
			
			case 5:
				TIM1->CCR1=Duty;
				TIM1->CCR2=0;
				TIM1->CCR3=0;
			break;
			
			case 4:
				TIM1->CCR1=Duty;
				TIM1->CCR2=Duty;
				TIM1->CCR3=0;
			break;
			
			case 6:
				TIM1->CCR1=0;
				TIM1->CCR2=Duty;
				TIM1->CCR3=0;
			break;
			
			case 2:
				TIM1->CCR1=0;
				TIM1->CCR2=Duty;
				TIM1->CCR3=Duty;
			break;
			
			case 3:
				TIM1->CCR1=0;
				TIM1->CCR2=0;
				TIM1->CCR3=Duty;
			break;
			
			default:
				break;		
		}
	}
	else
	{
		switch(Hall_State)
		{
			case 1:
				TIM1->CCR1=0;
				TIM1->CCR2=Duty;
				TIM1->CCR3=0;
			break;
			
			case 5:
				TIM1->CCR1=0;
				TIM1->CCR2=Duty;
				TIM1->CCR3=Duty;
			break;
			
			case 4:
				TIM1->CCR1=0;
				TIM1->CCR2=0;
				TIM1->CCR3=Duty;
			break;
			
			case 6:
				TIM1->CCR1=Duty;
				TIM1->CCR2=0;
				TIM1->CCR3=Duty;
			break;
			
			case 2:
				TIM1->CCR1=Duty;
				TIM1->CCR2=0;
				TIM1->CCR3=0;
			break;
			
			case 3:
				TIM1->CCR1=Duty;
				TIM1->CCR2=Duty;
				TIM1->CCR3=0;
			break;
			
			default:
				break;
		}
	}
}

霍尔状态函数Get_HallState():

uint8_t Get_HallState(void)  //获取霍尔状态值
{
	uint8_t HallState=0;
	
	HallState=HAL_GPIO_ReadPin(H1_GPIO_Port, H1_Pin);
	HallState<<=1;
	HallState|=HAL_GPIO_ReadPin(GPIOB, H2_Pin);
	HallState<<=1;
	HallState|=HAL_GPIO_ReadPin(GPIOB, H3_Pin);
	
	return HallState;
}

2.4.编译下载观察试验现象

PWM占空比设置为10时A相的电压:
在这里插入图片描述
PWM占空比设置为20时的A相电压:
在这里插入图片描述
PWM占空比设置为50时的A相电压:
在这里插入图片描述

总结

主控板STM32F302R8+驱动板X-NUCLEO-IHM07M1+直流无刷电机WR36BL61,实现了直流无刷电机的开环调速,为后续章节的分析奠定基础。

<think>嗯,用户的问题是关于STM32中XOR/ON霍尔传感器模式的配置和使用方法。首先,我需要回忆STM32的定时器模块,特别是高级控制定时器(如TIM1、TIM8)或者通用定时器,这些定时器通常支持霍尔传感器接口。霍尔传感器常用于无刷电机控制,检测转子的位置,所以用户可能是在做电机控制相关的项目。 霍尔传感器模式通常有三种模式:XOR、ON和OFF。用户提到的XOR/ON可能是指其中的两种模式,或者可能是指某种组合配置。需要查阅STM32的参考手册,特别是定时器章节中的霍尔传感器接口部分。例如,在TIMx_CR2寄存器中,可能有相关的位域来控制霍尔传感器的模式,比如TI1S位,用于选择是否将输入滤波后的TI1输入连接到三个霍尔传感器通道的XOR组合。 接下来,配置步骤应该包括:GPIO初始化,将霍尔传感器的三个输入连接到相应的定时器通道;定时器配置,设置时基参数,比如预分频器和自动重载值;霍尔传感器接口配置,选择XOR或ON模式;中断或DMA的启用,以处理信号变化;最后启动定时器。 在XOR模式下,三个霍尔传感器信号通过异或逻辑组合,任何信号变化都会触发捕获事件。而ON模式可能是指当所有三个信号都为高电平时触发,或者某种特定的组合。需要确认具体的模式定义,可能不同的模式对应不同的触发条件,影响计数器的重置或触发信号。 用户可能需要知道如何设置TIMx_CR2寄存器中的相关位,以及如何配置输入通道和极性。此外,应用场景方面,XOR模式适合需要快速响应任何传感器变化的场合,而ON模式可能用于特定的位置检测。注意事项包括信号消抖、中断处理以及不同STM32系列之间的配置差异。 最后,生成相关问题时,需要考虑用户可能的后续疑问,比如与其他模式的比较、具体寄存器配置、中断处理代码示例,以及常见问题排查等。确保引用正确的参考手册部分,比如RM0008或对应系列的文档,可能需要提示用户查阅具体型号的手册以确认细节。</think>### STM32中XOR/ON霍尔传感器模式配置方法 在STM32中,霍尔传感器模式主要用于电机控制领域,通过检测霍尔传感器信号实现转子位置解码。XOR(异或)和ON模式是两种特殊配置方式,属于定时器霍尔传感器接口(Hall Sensor Interface)功能的部分[^1]。 #### 、配置步骤 1. **GPIO初始化** - 将霍尔传感器输出信号连接到TIMx_CH1/CH2/CH3对应的GPIO引脚 - 配置为输入模式(通常使用浮空输入或上拉输入) 2. **定时器配置** ```c TIM_HandleTypeDef htim; htim.Instance = TIM1; htim.Init.Prescaler = 0; htim.Init.CounterMode = TIM_COUNTERMODE_UP; htim.Init.Period = 0xFFFF; htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim.Init.RepetitionCounter = 0; ``` 3. **霍尔传感器接口配置** ```c TIM_HallSensor_InitTypeDef HallSensor_Config; HallSensor_Config.IC1Polarity = TIM_ICPOLARITY_RISING; // 输入极性 HallSensor_Config.IC1Prescaler = TIM_ICPSC_DIV1; // 输入预分频 HallSensor_Config.IC1Filter = 0x0F; // 输入滤波器 HallSensor_Config.Commutation_Delay = 0; // 换向延迟 HAL_TIMEx_HallSensor_Init(&htim, &HallSensor_Config); ``` 4. **XOR/ON模式选择** - 通过`TIMx_CR2`寄存器的`TI1S`位控制- `TI1S=0`: 标准模式(单个输入) - `TI1S=1`: XOR模式(三个输入异或组合) 5. **启用中断/DMA** ```c HAL_TIMEx_HallSensor_Start_IT(&htim); // 启用中断模式 ``` #### 二、模式特点对比 | 模式 | 触发条件 | 应用场景 | |--------|------------------------------|------------------------| | XOR | H1^H2^H3信号变化触发 | 高速电机控制 | | ON | H1&H2&H3同时有效时触发 | 精确位置检测 | #### 三、应用示例 ```c void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM1){ uint16_t position = TIM1->CCR1; // 获取捕获值 // 执行换相逻辑 } } ``` #### 四、注意事项 1. 必须使能`TIMx_CCMR1`中的输入捕获功能 2. 建议使用至少4μs的消抖滤波器[^1] 3. 不同STM32系列(F1/F4/H7)存在寄存器差异
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值