STM32F1与STM32CubeIDE编程实例-磁簧开关(Reed Switch)驱动

磁簧开关(Reed Switch)驱动

簧片开关是一种由外加磁场操作的电气开关。 它由列宁格勒电工大学的 Valentin Kovalenkov 教授于 1922 年发明, 后来在 1936 年由 Walter B. Ellwood 在贝尔电话实验室发展成为簧片继电器。

在这里插入图片描述

磁簧开关机构由两个仅相隔几微米的铁磁片组成。 当磁铁接近这些叶片时,两个叶片会相互拉向对方。 一旦接触,铁磁片片就会关闭常开 (NO) 触点,从而使电流流动。 一些簧片开关还包含一个非铁磁触点,形成一个常闭 (NC) 输出。 靠近的磁铁会断开触点并从开关触点上拉开。

触点由多种金属制成,包括钨和铑。 有些品种甚至使用水银,必须保持正确的方向才能正确切换。 一个充满惰性气体(通常是氮气)的玻璃封套在一个大气压下的内部压力下密封触点。 密封隔离触点,从而防止腐蚀和任何可能因触点移动而产生的火花。

1、磁簧开关配置

磁簧开关配置如下:

在这里插入图片描述

保存配置并生成代码。

2、磁簧开关驱动实现

1)基本定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/\*
\* reed\_switch.h
\*
\* Created on: Apr 22, 2022
\* Author: jenson
\*/

#ifndef \_\_REED\_SWITCH\_H\_\_
#define \_\_REED\_SWITCH\_H\_\_

#include <stdio.h>
#include <stm32f1xx\_hal.h>
#include "main.h"

typedef struct {
uint16\_t id;
GPIO_TypeDef \*GPIOx; // 总线端口
uint16\_t GPIO_Pin; // 总线引脚
}reed\_switch\_t;

/\*\*
\*@brief 检查磁簧开关状态
\*@param sensor 开关对象
\*@return 当开关闭合时,返回1;否则,返回0
\*/
uint8\_t reed\_switch\_check(reed\_switch\_t\* sensor);

#endif /\* \_\_REED\_SWITCH\_H\_\_ \*/


2)磁簧开关状态读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/\*
\* reed\_switch.c
\*
\* Created on: Apr 22, 2022
\* Author: jenson
\*/

#include "reed\_switch.h"

uint8\_t reed\_switch\_check(reed\_switch\_t \*sensor) {
// 读取传感器输出电平
if (HAL\_GPIO\_ReadPin(sensor->GPIOx, sensor->GPIO_Pin) == GPIO_PIN_SET) {
return 1;
}
return 0;
}


3)主程序

main.c中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/\* Private includes ----------------------------------------------------------\*/
/\* USER CODE BEGIN Includes \*/
#include <stdio.h>
#include "reed\_switch/reed\_switch.h"
/\* USER CODE END Includes \*/

/\* USER CODE BEGIN PV \*/
reed\_switch\_t sensor;
/\* USER CODE END PV \*/

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 \*/
sensor.id = 1;
sensor.GPIO_Pin = REED_SWITCH_Pin;
sensor.GPIOx = REED_SWITCH_GPIO_Port;
printf("\*\*\*\*STM32CubeIDE:Reed Switch\*\*\*\*\r\n");
/\* USER CODE END 2 \*/

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

/\* USER CODE BEGIN 3 \*/
if(reed\_switch\_check(&sensor)){
printf("Reed Switch Closed\r\n");
}
HAL\_Delay(10);
}
/\* USER CODE END 3 \*/
}


拿一块磁铁靠近磁簧开关,运行结果如下:

在这里插入图片描述

3、磁簧开关中断方式配置

前面的驱动代码是基于循环轮询实现,比较耗CPU。可以通过外部中断方式来对传感器输出信号进行检测。关于外部中断使用,请参考:

传感器的中断方式驱动配置如下:

在这里插入图片描述

在这里插入图片描述

4、磁簧开关中断方式驱动实现

1)基本定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/\*
\* reed\_switch.h
\*
\* Created on: Apr 22, 2022
\* Author: jenson
\*/

#ifndef \_\_REED\_SWITCH\_H\_\_
#define \_\_REED\_SWITCH\_H\_\_

#include <stdio.h>
#include <stm32f1xx\_hal.h>
#include "main.h"

/\*\*
\* @brief 磁簧开关中断回调函数
\* @param sensor\_id 开关ID
\*/
typedef void (\*reed_switch_callback)(uint16\_t sensor_id);

typedef struct {
uint16\_t id;
GPIO_TypeDef \*GPIOx; // 总线端口
uint16\_t GPIO_Pin; // 总线引脚
reed_switch_callback callback; //回调
}reed\_switch\_t;


#endif /\* \_\_REED\_SWITCH\_H\_\_ \*/


2)中断服务实现

stm32f1xx_it.c文件中,对中断服务实现,添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/\* Private includes ----------------------------------------------------------\*/
/\* USER CODE BEGIN Includes \*/
#include "reed\_switch/reed\_switch.h"
/\* USER CODE END Includes \*/

/\* Private variables ---------------------------------------------------------\*/
/\* USER CODE BEGIN PV \*/
extern reed\_switch\_t sensor;
/\* USER CODE END PV \*/

/\* USER CODE BEGIN 1 \*/
void HAL\_GPIO\_EXTI\_Callback(uint16\_t GPIO_Pin) {
if(GPIO_Pin == sensor.GPIO_Pin){
if(sensor.callback){
sensor.callback(sensor.id);
}
}
}
/\* USER CODE END 1 \*/

3)主程序

main.c文件中,添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/\* Private includes ----------------------------------------------------------\*/
/\* USER CODE BEGIN Includes \*/
#include <stdio.h>
#include "reed\_switch/reed\_switch.h"
/\* USER CODE END Includes \*/

/\* USER CODE BEGIN PV \*/
reed\_switch\_t sensor;
/\* USER CODE END PV \*/

/\* USER CODE BEGIN PFP \*/
void on\_reed\_switch\_callback(uint16\_t sensor_id);
/\* USER CODE END PFP \*/

/\* Private user code ---------------------------------------------------------\*/
/\* USER CODE BEGIN 0 \*/
void on\_reed\_switch\_callback(uint16\_t sensor_id){
printf("Reed switch %d toggled\r\n",sensor_id);
}
/\* USER CODE END 0 \*/

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 \*/
sensor.id = 1;
sensor.GPIO_Pin = REED_SWITCH_Pin;
sensor.GPIOx = REED_SWITCH_GPIO_Port;
sensor.callback = on_reed_switch_callback;
printf("\*\*\*\*STM32CubeIDE:Reed Switch\*\*\*\*\r\n");
/\* USER CODE END 2 \*/

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

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

拿一块磁铁靠近磁簧开关,运行结果如下:

在这里插入图片描述

文章来源: https://iotsmart.blog.csdn.net/article/details/125352134