基于TRGO硬件触发COM事件的6步换相法驱动BLDC

前言

在阅读野火的《电机应用开发实战指南—基于STM32》无刷直流电机章节时,突然想基于ST官方手册高级定时器章节相关内容进行BLDC相关实验。在此做一个开发调试记录。
由于本文大量引用ST官方手册内容,篇幅较长,有不尽或不对之处敬请指正。

本试验开发环境:
1、电路板:野火407骄阳电机控制板+BLDC驱动板;
2、IDE:STM32CubeMX 6.4.0 + KEIL5.36.0.0;
3、电机:时代超群(57BL75S10-230TF9,不带编码器)。

BLDC驱动电路及换相等基础知识在此不再赘述,推荐下面两篇博文供参考。
1、【零基础玩转BLDC系列】基于霍尔传感器的无刷直流电机控制原理
2、有霍尔传感器BLDC换向原理

1、HALL接口定时器配置

1.1、ST手册定时器相关内容及其理解

HALL接口定时器涉及《STM32F4中文手册》14.3.18 连接霍尔传感器、14.3.5 捕获/比较通道以及“STM32定时器总纲”——高级定时器框图。

1.1.1、连接霍尔传感器

在这里插入图片描述

可通过用于生成电机驱动 PWM 信号的高级控制定时器(TIM1 或 TIM8)以及图 114中称为 “接口定时器”的另一个定时器 TIMx(TIM2、TIM3、TIM4 或 TIM5),实现与霍尔传感器 的连接。3 个定时器输入引脚(TIMx_CH1、TIMx_CH2 和 TIMx_CH3)通过异或门连接到 TI1 输入通道(通过将 TIMx_CR2 寄存器中的 TI1S 位置 1 来选择),并由“接口定时器” 进行捕获。

a、HALL_A、HALL_B、HALL_C分别接入某个通用定时器(TIM2、TIM3、TIM4或TIM5)的TIMx_CH1、TIMx_CH2 和 TIMx_CH3,该通用定时器称作HALL的“接口定时器”。
b、将“接口定时器”的TIMx_CR2 寄存器中的 TI1S 位置 1 :TIMx_CH1、CH2 和 CH3 引脚连接到 TI1 输入(异或组合)。
c、“接口定时器”将对TI1通道进行捕获。详情见本文1.1.2、捕获/比较通道小节。

“从模式控制器配置为复位模式;从输入为 TI1F_ED。这样,每当 3 个输入中有一个输入发生 切换时,计数器会从 0 开始重新计数。这样将产生由霍尔输入的任何变化而触发的时基。”

a、“接口定时器”的从模式控制器配置为复位模式。
b、“接口定时器”的从模式控制器的触发源配置为TI1F_ED。

“在“接口定时器”上,捕获/比较通道 1 配置为捕获模式,捕获信号为 TRC(请参见第 344 页的图 97:捕获/比较通道(例如:通道 1 输入阶段))。捕获值对应于输入上两次变化的 间隔时间,可提供与电机转速相关的信息。”

a、“接口定时器”的TIMx_CH1 配置为捕获模式,捕获信号为 TRC。详情见本文1.1.2、捕获/比较通道小节。
b、“捕获值对应于输入上两次变化的 间隔时间”的意思是,捕获值是6步换相中每一相持续的时间,以便计算电机转速。

““接口定时器”可用于在输出模式下产生脉冲,以通过触发 COM 事件更改高级控制定时器(TIM1 或 TIM8)各个通道的配置。TIM1 定时器用于生成电机驱动 PWM 信号。为此,必 须对接口定时器通道进行编程,以便在编程的延迟过后产生正脉冲(在输出比较或 PWM 模 式中)。该脉冲通过 TRGO 输出发送到高级控制定时器(TIM1 或 TIM8)。”

a、“接口定时器”通过配置成主输出模式,产生脉冲TRGO,来触发高级定时器的COM 事件。也可以不配置成输出模式,采用软件方式触发高级定时器的COM事件。 高级定时器的COM 事件同时刻更改其各个通道的配置。
b、当“接口定时器”通过配置成主输出模式,产生脉冲TRGO时,可以通过设置脉冲宽度参数"编程的延迟过后产生正脉冲"。
c、产生的脉冲TRGO输出到高级定时器(TIM1 或 TIM8)。

1.1.2、捕获/比较通道

在这里插入图片描述

上图97是定时器最全的捕获/比较通道内部框图,红框区域代表的手册中图71中“输入滤波器和边沿检测器”。上图中手动绘制的TI1P2(指TI1FP2)边沿信号进入TIMX_CH2通道中。
结合1.1.1节内容,可以知道,HALL_A、HALL_B、HALL_C异或后接入TIMX_CH1通道,成为图97中的TI1。TI1经过滤波器和边沿检测器后,通过或门变成TI1F_ED信号,去触发“接口定时器”的从模式控制器,进而使“接口定时器”产生TRGO输出信号。以上就是HALL触发的信号路径。

有关捕获/比较通道的更为详细的内容,推荐下面博文仅供参考。
TIM输入捕获。

1.1.3、高级控制定时器框图

在这里插入图片描述
结合1.1.1和1.1.2得到上图所示的“接口定时器”内部信号路径图。
a、红色是HALL触发“接口定时器”的从模式控制器路径,使“接口定时器”复位;
b、蓝色是TRC触发“接口定时器”的捕获功能,获取BLDC单相持续的时间。此时间也可从其TIMX_CH3、TIMX_CH4通道获取。但是HAL库默认配置为了TIMX_CH1。
c、绿色是“接口定时器”触发输出信号TRGO产生的路径。
以上路径均在HAL库调用时配置好,无需开发人员再次配置。

1.2、STM32CubeMX配置HALL接口

本实验接口定时器使用TIM5。具体配置如下图。注意事项图中已标明。
参数配置
在这里插入图片描述
中断配置。
在这里插入图片描述
引脚配置。
在这里插入图片描述

1.3、STM32CubeMX生成HALL接口代码

生成代码后,在main.c文件主函数中可以看到MX_TIM5_Init()函数,进入后可以看到调用了下面的函数。

HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef *sConfig)

此函数将STM32CubeMX中配置的参数配置完毕。也完成了ST手册中下段表述的配置。
在这里插入图片描述
感兴趣的可以进入HAL_TIMEx_HallSensor_Init()函数体自行查阅。

此外,主函数中初始化“接口定时器”后,需要加入下面代码,开启比较输出中断并开启定时器HALL功能。

__HAL_TIM_ENABLE_IT(&htim5, TIM_IT_CC2);				//开启比较输出中断
HAL_TIMEx_HallSensor_Start(&htim5);					  	//开启接口定时器

比较输出中断回调函数(或PWM完成中断回调函数)用于获取HALL状态,并根据HALL状态配置高级定时器通道进行换相。
PWM完成中断回调函数定义如下:

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	uint8_t step = 0;
	if(htim == &htim5)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
		{
			step = Hall_Get_State();		//获取当前时刻HALL状态值
			
			PWM_CW_Control(step, 1);		//根据HALL状态值配置高级定时器各通道参数。

			HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
		}
	}
}

2、电机驱动 PWM 信号的高级控制定时器配置

本实验采用TIM8作为生成电机驱动 PWM 信号的高级控制定时器。采用互补通道输出PWM,三相全桥采用H-PWM_L-ON控制方式。

2.1STM32CubeMX配置高级定时器

从模式控制器、时钟源、通道、时基配置以及刹车寄存器配置如下图,触发输出及PWM通道采用默认。
在这里插入图片描述
在这里插入图片描述
PWM引脚配置为高速。
在这里插入图片描述

2.2STM32CubeMX生成高级定时代码

生成代码后,在MX_TIM8_Init()函数后面添加并配置如下函数:

HAL_TIMEx_ConfigCommutEvent(&htim8, TIM_TS_ITR3, TIM_COMMUTATION_TRGI);

该函数配置 TIMx_CR2 寄存器的CCPC=1, CCUS=1。对应ST手册中下面一段话。
在这里插入图片描述

3、6步换相代码的实现

3.1、6步换相理论参考

1、ST手册中14.3.14章节 生成 6 步 PWM
2、参考博文:STM32 - 定时器的设定 - 基础- 07 - 6-step PWM generation - 6步长PWM的产生 - COM Event的解释
3、ST手册中14.3.18章节 连接霍尔传感器
在这里插入图片描述

3.2、6步换相代码实现

1、BLDC变相时序如下图
在这里插入图片描述
上表中,正转/反转的定义:俯视电机输出轴逆时针为正转,顺时针为反转。
顺时针HALL值:264513,便于记忆:“二流子上武夷山”;
逆时针HALL值与顺时针顺序相反:315462。
由上表可知,顺时针与逆时针在三相全桥通断状态相同的情况下,两种转向的HALL值相加等于7。

2、代码生成后加入如下代码
在main.c的main()函数初始化定时器后加入下面代码

PWM_Pulse_Set(speed);						//设置PWM占空比
MOTOR_ENABLE;								//是能MOS驱动电路
PWM_CW_Control(Hall_Get_State(), 0);		//获取HALL值并设置PWM通道
Hall_Time_Enable();							//开启接口定时器,产生一次TRGO信号触发COM事件
											//将PWM占空比及其他配置更新到高级定时器中,启动电机。

代码采用强制模式及PWM1模式,具体如下:

/**
 * @description: 定时器通道模式设置
 * @param {TIM_HandleTypeDef } htim	定时器句柄指针
 * @param {uint32_t } Channel		定时器通道
 * @param {uint32_t } Channel		通道模式
 * @return {*}
 */
static	void TIM_OCMode_Set(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t OCMode)
{
	uint32_t tmpccmrx;
	
	switch(Channel)
	{
		case	TIM_CHANNEL_1:
			tmpccmrx = htim->Instance->CCMR1;
			tmpccmrx &= ~TIM_CCMR1_OC1M;
			tmpccmrx |= OCMode;
			htim->Instance->CCMR1 = tmpccmrx;
			break;
		case	TIM_CHANNEL_2:
			tmpccmrx = htim->Instance->CCMR1;
		  tmpccmrx &= ~TIM_CCMR1_OC2M;
			tmpccmrx |= OCMode << 8;
			htim->Instance->CCMR1 = tmpccmrx;
			break;
		case	TIM_CHANNEL_3:
			tmpccmrx = htim->Instance->CCMR2;
		  tmpccmrx &= ~TIM_CCMR2_OC3M;
			tmpccmrx |= OCMode;
			htim->Instance->CCMR2 = tmpccmrx;
			break;
		case	TIM_CHANNEL_4:
			tmpccmrx = htim->Instance->CCMR2;
			tmpccmrx &= ~TIM_CCMR2_OC4M;
			tmpccmrx |= OCMode << 8;
			htim->Instance->CCMR2 = tmpccmrx;
			break;
		default:
			break;
	}
	
}
/**
 * @description: 顺时针运行
 * @param {uint8_t} Step		当前HALL位置
 * @param {uint8_t} Trgl_en		COM事件硬触发 1-硬触发,0-软触发
 * @return {*}
 */
void	PWM_CW_Control(uint8_t	Step, uint8_t Trgl_en)
{	
	if (Trgl_en == 1)
	{
		if(Step == 2)  Step = 6;
		else if(Step == 6)  Step = 4;
		else if(Step == 4)  Step = 5;
		else if(Step == 5)  Step = 1;
		else if(Step == 1)  Step = 3;
		else if(Step == 3)  Step = 2;
	}

	switch(Step)
	{
		case	1:	//W+U-   
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_1);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);		
			break;
		case	2:	//U+V-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_2);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);
			break;
		case	3:	//W+V-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_2);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);	
			break;
		case	4:	//V+W-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_3);
			break;
		case	5:	//V+U-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_1);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);
			break;
		case	6:	//U+W-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_3);
			break;
		default:
			break;
	}
}

/**
 * @description: 逆时针运行
 * @param {uint8_t} Step		当前HALL位置
 * @param {uint8_t} Trgl_en		COM事件硬触发 1-硬触发,0-软触发
 * @return {*}
 */
void	PWM_CCW_Control(uint8_t	Step, uint8_t Trgl_en)
{
	if (Trgl_en == 1)
	{
		if(Step == 3)  Step = 1;
		else if(Step == 1)  Step = 5;
		else if(Step == 5)  Step = 4;
		else if(Step == 4)  Step = 6;
		else if(Step == 6)  Step = 2;
		else if(Step == 2)  Step = 3;
	}	
	
	switch(Step)
	{
		case	1:	//U+W-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_3);
			break;
		case	2:	//V+U-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_1);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);
			break;
		case	3:	//V+W-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_3);
			break;
		case	4:	//W+V-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_2);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);	
			break;
		case	5:	//U+V-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_1);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_2);
		
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);
			break;
		case	6:	//W+U-
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_1, TIM_OCMODE_FORCED_ACTIVE);
			HAL_TIM_PWM_Stop(&htim8,TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_1);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_2, TIM_OCMODE_FORCED_INACTIVE);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_2);
			
			TIM_OCMode_Set(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM1);
			HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3);
			HAL_TIMEx_PWMN_Stop(&htim8, TIM_CHANNEL_3);	
			break;
		default:
			break;
	}
}

3.3、6步换相硬触发注意事项

1、启动电机前获取HALL当前值,并根据当前HALL值对应的MOS导通表配置互补的PWM;
2、启动电机后,在“接口定时器”PWM完成中断回调函数中再次获取当前HALL值,并根据当前HALL值的下一步值对应的MOS导通表配置互补的PWM。

另外,如果是软件触发COM事件,则无需注意以上两点,直接在main()函数初始化后调用软件触发COM事件函数即可启动电机,同时在换相函数中也调用软件触发COM事件函数。软件触发COM事件函数如下:

HAL_TIM_GenerateEvent(&htim8, TIM_EVENTSOURCE_COM);

3、PWM完成中断回调函数定义如下

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	uint8_t step = 0;
	if(htim == &htim5)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
		{
			step = Hall_Get_State();
			
			#if(MOTOR_DIR == 0)
			PWM_CW_Control(step, 1);
			#else
			PWM_CCW_Control(step, 1);
			#endif

			HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
		}
	}
}

uint8_t Hall_Get_State(void)
{
	uint8_t temp = 0;
	
	temp = (GPIOH->IDR >> 10) & 0x07;   //bit0: hall_U-PH10, bit1: hall_V-PH11, bit2: hall_W-PH12.			//TIM5
	
	return temp;
}

4、参考代码

本实验参考代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值