《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器

3.1 理论分析

3.1.1继电器概述

继电器(relay)是一种电控制器件,是当输入量(激励量)的变化达到规定要求时,在电气输出电路中使被控量发生预定的阶跃变化的一种电器。它具有控制系统(又称输入回路)和被控制系统(又称输出回路)之间的互动关系。通常应用于自动化的控制电 路中,它实际上是用小电流去控制大电流运作的一种“自动开关”。故在电路中起着自动调节、安全保护、转换电路等作用。

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第1张图片

图1继电器

3.1.2继电器原理

电磁式继电器一般由铁芯、线圈、衔铁、触点簧片等组成的。只要在线圈两端加上一定的电压,线圈中就会流过一定的电流,从而产生电磁效应,衔铁就会在电磁力吸引的作用下克服返回弹簧的拉力吸向铁芯,从而带动衔铁的动触点与静触点(常开触点)吸合。当线圈断电后,电磁的吸力也随之消失,衔铁就会在弹簧的反作用力返回原来的位置,使动触点与原来的静触点(常闭触点)释放。

这样吸合、释放,从而达到了在电路中的导通、切断的目的。对于继电器的“常开、常闭”触点,可以这样来区分:继电器线圈未通电时处于断开状态的静触点,称为“常开触点”;处于接通状态的静触点称为“常闭触点”。

继电器的控制原理很简单:

当控制端没电流流过或电流不够大时,继电器线圈就不吸合,常闭触点闭合,常开触点断开;当控制端有足够的电流流过时,继电器线圈就吸合,电磁感应使衔铁与永久磁铁产生吸引和排斥力矩,常闭触点断开,常开触点闭合。

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第2张图片

图2继电器原理

3.1.3继电器驱动方式

1.晶体管驱动
当晶体管用来驱动继电器时,必须将晶体管的发射极接地。具体电路如下:

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第3张图片

图3晶体管驱动电路

NPN 晶体管驱动时:当晶体管 T1基极被输入高电平时,晶体管饱和导通,集电极变为低电平,因此继电器线圈通电,触点 RL1吸合;当晶体管 T1 基级被输入低电平时,晶体管截止,继电器线圈断电,触电 RL1 断开。

PNP 晶体管驱动电路刚好和 NPN 驱动相反,即低电平时继电器导通,高电平时继电器断开。
电路中各元器件的作用:晶体管 T1可视为控制开关,一般选取 VCBO≈VCEO≥24V,放大倍数β一般选择在120~240之间,如 9013 、8050 等。电阻 R1 主要起限流作用,降低晶体管 T1 功耗,阻值为2 KΩ。电阻 R2使晶体管 T1可靠截止,阻值为5.1KΩ。二极管 D1 作用是关断时为线圈提供反向续流,一般选1N4148即可。

三极管驱动在插座、开关等电工产品中应用会比较多。

2.集成电路驱动
目前已使用多个驱动晶体管集成的集成电路,使用这种集成电路能简化驱动多个继电器的印制板的设计过程。驱动继电器的集成电路主要有TD62003AP、ULB2003等。

根据集成电路驱动器2003的输入输出特性,有人把它简称叫“驱动器”“反向器”“放大器”等。当2003输入端为高电平时,对应的输出口输出低电平,继电器线圈通电,继电器触点吸合;当2003输入端为低电平时,继电器线圈断电,继电器触点断开;在2003内部已集成起反向续流作用的二极管,因此可直接用它驱动继电器。

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第4张图片

图4集成电路2003驱动继电器

3.光耦隔离驱动
光耦亦称光电隔离器或光电耦合器,简称光耦。它是以光为媒介来传输电信号的器件,通常把发光器(红外线发光led)与受光器(光敏半导体管)封装在同一管壳内。当输入端加电信号时发光器发出光线,受光器接受光线之后就产生光电流,从输出端流出,从而实现了"电-光-电"转换。以光为媒介把输入端信号耦合到输出端的光电耦合器。

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第5张图片

图5 1路光耦隔离继电器

主要电路设计如下图:

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第6张图片

图6路继电器光耦隔离电路图

该继电保护主要隔离应用的是EL817光耦芯片。该芯片无需供电,通过光耦二极管上拉5v电源输出即可正常工作,有效隔离了输出侧对主回路的电磁影响。

3.2 实验详解

3.2.1实验目的

通过实验掌握STM32 芯片GPIO 的配置方法 掌握继电器模块的使用

3.2.2实验设备

硬件:PC 机一台;STM32开发板一套; 继电器模块一个
软件:Windows 10系统,Keil5集成开发环境

3.2.3硬件连接

本文使用的1路继电器,如图6所示。LED1是信号输入指示灯,LED2是电源指示灯。P1接控制器,P3接单片机。当IN1输入为低电平,继电器的公共端常开,LED1指示灯亮起,当IN1输入为高电平时,继电器的公共端常闭,LED1指示灯熄灭。另外笔者这里的IN1接到单片的PC5。

本文将通过按键来控制继电器的状态,按键电路如下:

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第7张图片

图7按键电路

3.2.4 Lib_V3.5.0库实现

继电器的控制相对来说比较简单,和LED类似,只需设置高低电平即可控制继电器。本文通过KEY1来打开控制继电器的常开,KEY2来控制继电器的常闭开关。

关于按键的部分这里就不讲了,另外还用了串口和滴答定时器,看笔者以前的文章吧。

Systick系统定时器
按键
串口通信

继电器的部分很简单。

1.初始化GPIO

/**
  * @brief  继电器IO引脚初始化
  * @param  None
  * @retval None
  */
void RELAY_GPIO_Init(void)
{
     
   /* 定义IO硬件初始化结构体变量 */
  GPIO_InitTypeDef GPIO_InitStructure;
	
	/* 使能(开启)继电器引脚对应IO端口时钟 */  
  RELAY_RCC_CLOCKCMD(RELAY_RCC_CLOCKGPIO, ENABLE);

  /* 设定继电器对应引脚IO编号 */
  GPIO_InitStructure.GPIO_Pin = RELAY_GPIO_PIN;  
  /* 设定继电器对应引脚IO最大操作速度 :GPIO_Speed_50MHz */
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  /* 设定继电器对应引脚IO为输出模式 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
  /* 初始化继电器对应引脚IO */
  GPIO_Init(RELAY_GPIO, &GPIO_InitStructure);
 
  /* 设置引脚输出为低电平,此时继电器(公共端——常闭) */
  RELAY_ON;    
}

笔者这里使用的是PC5,当然你也可以自行更换引脚。

2.控制继电器

控制继电器是通过宏定义的方式实现的。

#if 0         /* 调用标准库函数方法 */

#define RELAY_ON                       GPIO_ResetBits(RELAY_GPIO,RELAY_GPIO_PIN)    //输出低电平,继电器(公共端——常开)
#define RELAY_OFF                      GPIO_SetBits(RELAY_GPIO,RELAY_GPIO_PIN)      //输出高电平,继电器(公共端——常闭) 
#define RELAY_TOGGLE                   {
       RELAY_GPIO->ODR ^=RELAY_GPIO_PIN;}          //输出反转,继电器状态改变

#else       /* 直接操作寄存器方法 */

#define RELAY_ON                       {
       RELAY_GPIO->BRR=RELAY_GPIO_PIN;}           //输出低电平,继电器(公共端——常开)
#define RELAY_OFF                      {
       RELAY_GPIO->BSRR=RELAY_GPIO_PIN;}          //输出高电平,继电器(公共端——常闭) 
#define RELAY_TOGGLE                   {
       RELAY_GPIO->ODR ^=RELAY_GPIO_PIN;}         //输出反转,继电器状态改变

#endif

当然也可可以封装成库函数。函数如下:

/**
  * @brief  设置板载继电器的状态
  * @param  tate:设置继电器的状态。
  *             可选值:RELAYState_OFF:继电器(公共端——常闭)
  *             可选值:RELAYState_ON: 继电器(公共端——常开)
  * @retval None
  */
void RELAY_SetState(RELAYState_TypeDef state)
{
     
  /* 检查输入参数是否合法 */
  assert_param(RELAYState_TypeDef(state));
  
  /* 判断设置的继电器状态,如果设置为继电器常开 */
  if(state==RELAYState_ON)
  {
     
    RELAY_ON;   
  }
  else  /* state=RELAYState_OFF:设置继电器(公共端——常开)  */
  {
     
    RELAY_OFF;   
  }
}

3.继电器的状态检测

设置了继电器的开闭,接下来通过检测GPIO的状态来检测继电器的开闭状态。

/**
  * @brief  读取继电器的状态
  * @param  RELAYState_OFF:继电器(公共端——常闭)
  *         RELAYState_ON: 继电器(公共端——常开)
  * @retval None
  */
uint8_t RELAY_GetState(void)
{
     
  uint8_t relay_state=RELAYState_ON;
  
  if((RELAY_GPIO->ODR & RELAY_GPIO_PIN)!= (uint32_t)Bit_RESET)
    relay_state=RELAYState_OFF;
  
  return relay_state;  
}

好了,接下来看看主函数是如何调用的。

/**
  * @brief  mian
  * @param  None
  * @retval int
  */
int main(void)
{
     	
	//滴答定时器初始化
	SysTick_Init();
	
	/* USART1 配置模式为 115200 8-N-1,中断接收 */
	USART1_Config();

	/* 初始继电器IO */
  RELAY_GPIO_Init();
  
  /* 初始化按键 */  
  KEY_GPIO_Init();
  
  printf("继电器\r\n");
  
  /* 无限循环 */
  while (1)
  {
     
    if(KEY1_StateRead()==KEY_DOWN)
    {
     
      RELAY_ON; //输出低电平,继电器(公共端——常开)    
			printf("当前继电器状态为:常闭 \r\n");
    }
    if(KEY2_StateRead()==KEY_DOWN)
    {
     
      RELAY_OFF;//输出高电平,继电器(公共端——常闭)    
			printf("当前继电器状态为:常开 \r\n");
    }
		
    if(RELAY_GetState()==RELAYState_OFF)
		{
     
			Delay_ms(20);
      printf("当前继电器状态为:常闭 \r\n");
    }
		else
    {
       
			printf("当前继电器状态为:常开 \r\n");
			Delay_ms(20);
    }
    Delay_ms(200);
  }
}

先进行一系列的初始化,然后就通过按键来控制继电器的状态,不断检测继电器状态,并点打印输出继电器的状态信息。

3.2.5 HAL库实现

我们在串口的例子的基础上进行配置。
串口通信(HAL库)

这里用到了PA0、PC13和PC5,将PC5配置成输出,KEY1的引脚是PA0,KEY2的引脚是C13,我们将PA0 和PC13的GPIO设置为输入模式。

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第8张图片

图8配置GPIO

生成工程即可。

关于按键的实现可参考笔者以前的博客:

按键

HAL库的实现和标准库一样,只是函数不同罢了。

这里只贴出主函数的代码。完整工程请通过后文提示获取。

/**
  * @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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1);
  /* USER CODE END 2 */
  printf("继电器\r\n");
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
     
    /* USER CODE END WHILE */
		if(KEY1_StateRead()==KEY_DOWN)
    {
     
      RELAY_ON; //输出低电平,继电器(公共端——常开)    
			printf("当前继电器状态为:常闭 \r\n");
    }
    if(KEY2_StateRead()==KEY_DOWN)
    {
     
      RELAY_OFF;//输出高电平,继电器(公共端——常闭)    
			printf("当前继电器状态为:常开 \r\n");
    }
		
    if(RELAY_GetState()==RELAYState_OFF)
		{
     
			HAL_Delay(20);
      printf("当前继电器状态为:常闭 \r\n");
    }
		else
    {
       
			printf("当前继电器状态为:常开 \r\n");
			HAL_Delay(20);
    }
    HAL_Delay(200);

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

3.2.6实验现象

不管是使用何种库,结果都是一样的,每个200ms输出继电器状态,使用按键控制控制继电器状态,串口就会打印继电器的状态信息。

《嵌入式-STM32开发指南》第三部分 外设篇 - 第3章 继电器_第9张图片



欢迎访问我的网站:

BruceOu的哔哩哔哩
BruceOu的主页
BruceOu的博客
BruceOu的CSDN博客
BruceOu的简书

接收更多精彩文章及资源推送,请订阅我的微信公众号:

在这里插入图片描述

你可能感兴趣的:(《嵌入式》STM32开发指南,STM32,HAL,继电器)