IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 直流无刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(一) -> 正文阅读

[嵌入式]直流无刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(一)


前言

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

一、STM32F302R8+X-NUCLEO-IHM07M1驱动直流无刷电机

1.1.功能需求

驱动直流无刷电机转动,并实现直流无刷电机的换向控制;按下一次按键电机正转;再按一次按键电机停止;再按一次按键电机反转;再按一次按键电机停止,以此循环。

1.2.硬件设计

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

1.3.软件设计

1.3.1.STM32CubeMX底层配置

为了更直观简单的实现直流无刷电机的六步换相控制,将所用引脚均设置为普通I/O口模式。
1、RCC设置为外接时钟,72MHz
2、PA8、PA9、PA10、PC10、PC11、PC12设置为推挽输出、无上下拉电阻、高速,初始化状态设为0;PA15、PB3、PB10设置为输入,无上下拉电阻;PB13设置为推挽输出,下拉电阻、高速,初始化状态为0;PC13设置为输入,无上下拉电阻。
3、使能USART2,异步模式,波特率115200,8位数据位,1位停止位,无奇偶校验位
3、IDE设置为MDK-RAM,在Keil环境中编写应用层程序
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3.2.应用层开发

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

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_USART2_UART_Init();
  /* USER CODE BEGIN 2 */

  /* 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)
	  {
		  Mode++;
		  if(Mode>3)
			  Mode=0;
	  }
	  
	  switch(Mode)
	  {
		  case 0:
			  BLDC_Stop();
			  LED_Stop();
		  break;
		  
		  case 1:
			  BLDC_Driver(1);
			  LED_Driver();
		  break;
		  
		  case 2:
			  BLDC_Stop();
			  LED_Stop();
		  break;
		  
		  case 3:
			  BLDC_Driver(0);
		      LED_Driver();
		  break;
	  }
  }
  /* USER CODE END 3 */
}

按键扫描函数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 Direction)
{
	static uint8_t Pre_HallState=0;  //前一个霍尔状态值
	uint8_t HallState;
	HallState=Get_HallState();
	
	if(Pre_HallState!=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);
		
		HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  //三路桥臂的使能输入设置为0(每路桥臂上闭下开)
		HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
		
		if(Direction==1)  //电机正转
		{
			switch(HallState)  //根据霍尔状态值进行电机的换相
			{
				case 1:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
				break;
				
				case 5:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
				break;
				
				case 4:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
				break;
				
				case 6:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
				break;
				
				case 2:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
				break;
				
				case 3:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
				break;
				
				default:
					break;
			}
		}
		else  //电机反转
		{
			switch(HallState)  //根据霍尔状态值进行电机的换相
			{
				case 1:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
				break;
				
				case 5:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
				break;
				
				case 4:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
				break;
				
				case 6:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
				break;
				
				case 2:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
				break;
				
				case 3:
					HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);  
					HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
					HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
				break;
				
				default:
					break;
			}
		}
		Pre_HallState=HallState;
	}	
}

霍尔状态函数Get_HallState()

uint8_t Get_HallState(void) //获取当前霍尔传感器的状态
{
	uint8_t HallState;      //算法为 H1<<2+H2<<1+H3
	    
	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;
}

电机停止函数BLDC_Stop()

void BLDC_Stop(void)
{
	HAL_GPIO_WritePin(GPIOC, EN1_Pin, GPIO_PIN_RESET);  //非能三个桥臂
	HAL_GPIO_WritePin(GPIOC, EN2_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC, EN3_Pin, GPIO_PIN_RESET);
	
	HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);  //三路桥臂的使能输入设置为0(每路桥臂上闭下开)
	HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
}

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

在这里插入图片描述

总结

主控板STM32F302R8+驱动板X-NUCLEO-IHM07M1+直流无刷电机WR36BL61,采用六步换相法实现电机的正反转驱动,为后续章节的分析奠定基础。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:42:58  更:2022-11-05 00:44:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 19:44:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码