19-CubeMx+Keil+Proteus仿真STM32 - 直流电动机

本文例子参考《STM32单片机开发实例——基于Proteus虚拟仿真与HAL/LL库》
源代码:https://github.com/LanLinnet/STM32F103R6

项目要求

理解H桥电路的工作原理,结合前面几个项目学习过的PWMEXTI串口通讯等,要求通过5个按钮控制直流电动机的运行状态,包括:电动机正转、电动机反转、电动机停止、电动机加速和电动机减速,其中电动机加速/减速以10%的PWM信号宽度占空比为递增/递减量。

硬件设计

  1. 第一节的基础上,在Proteus中添加电路如下图所示。其中我们添加了一个直流电动机H桥芯片L298,一个直流电动机MOTOR-DC

    此外,我们还添加了一个虚拟仪表:虚拟终端VIRTUAL TERMINAL,将其波特率设置为19200bits/s。

  2. 直流电动机和H桥电路:直流电动机是一种常见的动力源,很多情况下需要用直流电动机带动执行机构做各种复杂动作。直流电动机与H桥电路如下图所示。

    • 当开关A、D闭合时,电动机左侧接通驱动电源正极,右侧接通驱动电源负极,直流电动机正转;
    • 当开关B、C闭合时,电动机左侧接通驱动电源负极,右侧接通驱动电源正极,直流电动机反转;
    • 当只有开关A、C闭合或只有开关B、D闭合时,电动机左、右侧短路,直流电动机能耗制动,对于某些大功率直流电动机,还需要在短路回路中串联制动电阻,防止能耗制动过程中电流过大。
  3. 双H桥芯片L298
    1)简介:L298是意法半导体公司出品的双H桥芯片,片内集成2个独立的H桥,可同时驱动2个最大电压为46V、最大电流为2A的直流电动机。
    2)引脚:L298控制信号为5VTTL电平,驱动电压为5-46V,故在使用STM32控制时应当选用具备“FT”特性的GPIO引脚,并将引脚设为开漏输出模式,同时外接上拉电阻到5V电源正极。控制电路由VSS供电,驱动电路由VS供电,芯片引脚和常用电路如下图所示。

    • ENx:H桥A/B的使能引脚,高电平有效,往往与PWM信号相连,用于调节H桥A/B控制的直流电动机转速。
    • ISENx:H桥A/B的驱动检测引脚,用于进行过流检测,并将检测结果反馈给控制器以形成闭环控制,一般不用,可直接接地。
    • IN1-IN4:方向控制信号输入端,其中IN1、IN2控制H桥A,其中IN3、IN4控制H桥B,具体如下表所示。
    • OUT1-OUT4:2个H桥的输出端,用来连接2个直流电动机,其中OUT1、OUT2用来连接Motor1,OUT3、OUT4用来连接Motor2。
    • D1-D8:8个整流二极管,由于直流电动机为感性负载,为了避免L298在电动机转换方向时受到反向电流的冲击,加入整流二极管进行泄流。
  4. 打开CubeMX,建立工程。这一项目有很多设置都与前面涉及的项目相似,若不熟悉可以进行回顾。

    • 首先,设置具有“FT”功能的GPIO管脚PC8PC9GPIO_Output,设置GPIO mode为开漏输出模式Output Open DrainGPIO Pull-up/Pull-down为不需要内部上拉和下拉电阻No pull-up and no pull-down,因为已经在电路中通过外部电阻上拉到+5V。
    • 随后,设置PWM,可参考链接PWM,配置如下图所示。
    • 然后,设置串口,可参考链接串口通讯,配置如下图所示。
    • 最后,设置外部中断,并将NVIC中的中断使能都勾选上,可参考链接EXTI,配置如下图所示。
  5. 点击“Generator Code”生成Keil工程。

软件编写

点击“Open Project”在Keil中打开工程,打开“main.c”,添加代码如下。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"		//引入标准输入输出库头文件
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
uint16_t cmpv = 80;		//捕获比较值,即CRR2的设定值
uint8_t rf = 0;		//中断标志位
/* USER CODE END PV */
/* USER CODE BEGIN 1 */
char str[4];		//用于存放CRR2值转换的字符串
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);		//定时器3运行并在通道2输出PWM函数
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, cmpv);		//给定时器3设定通道2的捕获比较寄存器值(CRR2)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);		
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
  if(rf == 1)
  {
    HAL_UART_Transmit(&huart1, (uint8_t *)&"PWM:", 4, 4);		//串口发送字符串(PWM比较寄存器值,值越大转速越快)
    sprintf(str, "%d", cmpv);
    HAL_UART_Transmit(&huart1, (uint8_t *)str, 3, 3);
    HAL_UART_Transmit(&huart1, (uint8_t *)&"\n\r", 2, 2);
    rf = 0;		//标志位清零
  }
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
/* USER CODE BEGIN 4 */
//外部中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_0)		//正转按钮
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET);
    rf = 1;
  }
  else if(GPIO_Pin == GPIO_PIN_1)		//反转按钮
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);
    rf = 1;
  }
  else if(GPIO_Pin == GPIO_PIN_2)		//停止按钮
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
  }
  else if(GPIO_Pin == GPIO_PIN_3)		//加速按钮(增加PWM信号波形占空比)
  {
    if(cmpv<100) cmpv+=10;
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, cmpv);		//给定时器3设定通道2的捕获比较寄存器值(CRR2)
    rf = 1;
  }
  else if(GPIO_Pin == GPIO_PIN_4)		//减速按钮(减小PWM信号波形占空比)
  {
    if(cmpv>0) cmpv-=10;
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, cmpv);		//给定时器3设定通道2的捕获比较寄存器值(CRR2)
    rf = 1;
  }
}
/* USER CODE END 4 */

联合调试

  1. 点击运行,生成HEX文件。
  2. 在Proteus中加载相应HEX文件,点击运行。按下不同的按键,可以看到电动机转速的变化,并且在虚拟终端中可以看到PWM占空比的设定值。
posted @ 2022-06-01 13:42  Sheepeach  阅读(4102)  评论(7编辑  收藏  举报