【STM32】STM32之限位开关


一、简介

本文介绍如何在STM32上使用限位开关。


二、实验平台

库版本:STM32F10x_StdPeriph_Lib_V3.5.0

编译软件:MDK4.53

硬件平台:STM32开发板(主芯片stm32f103c8t6

仿真器:JLINK


、版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、实验前提

在进行本文步骤前,请先阅读并实现以下博文:

1、《STM32之NVIC》:http://blog.csdn.net/feilusia/article/details/52819709


五、 基础知识

1、限位开关是什么?

答:限位开关其实就是会复原开关的开关按键。

也就是说按下限位开关的开关能触发STM32的IO中断,而松开手指时限位开关会复原。


2、限位开关有什么用?

答:通常被用于限制电机转动角度来使用。

例如两个限位开关形成45°的夹角,一旦电机转动触发任意其中一个限位开关,STM32检测到限位开关的中断则停止电机,不能再继续往此方向转动。


3、限位开关有什么优缺点?

答:限位开关的优点是以物理的方式触发单片机中断,因此不增加功耗。缺点是经常使用的话限位开关易损坏。


4、限位开关在软件上应如何开发?

答:由于限位开关通常是两个,因此按照普通按键的形式写两个按键,在按键中断中做停止电机等处理即可。


六、实验步骤

1、编写并添加限位开关驱动

1)编写驱动GUA_Limit_Switch.c(存放在“……\HARDWARE”)


    
    
  1. //******************************************************************************
  2. //name: GUA_Limit_Switch.c
  3. //introduce: 限位开关驱动
  4. //author: 甜甜的大香瓜
  5. //email: 897503845@qq.com
  6. //QQ group 香瓜单片机之STM8/STM32(164311667)
  7. //changetime: 2016.12.28
  8. //******************************************************************************
  9. #include "stm32f10x.h"
  10. #include "GUA_Limit_Switch.h"
  11. /*********************宏定义************************/
  12. //引脚宏定义
  13. #define GUA_LIMIT_SWITCH_UP_PORT GPIOA
  14. #define GUA_LIMIT_SWITCH_UP_PIN GPIO_Pin_1
  15. #define GUA_LIMIT_SWITCH_DOWN_PORT GPIOA
  16. #define GUA_LIMIT_SWITCH_DOWN_PIN GPIO_Pin_4
  17. /*********************内部函数************************/
  18. static void GUA_Limit_Switch_IO_Init(void);
  19. static void GUA_Limit_Switch_Exti_Init(void);
  20. //******************************************************************************
  21. //name: GUA_Limit_Switch_IO_Init
  22. //introduce: 限位开关的IO初始化
  23. //parameter: none
  24. //return: none
  25. //author: 甜甜的大香瓜
  26. //email: 897503845@qq.com
  27. //QQ group 香瓜单片机之STM8/STM32(164311667)
  28. //changetime: 2016.12.28
  29. //******************************************************************************
  30. static void GUA_Limit_Switch_IO_Init(void)
  31. {
  32. //IO结构体
  33. GPIO_InitTypeDef GPIO_InitStructure;
  34. //时钟使能
  35. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  36. //UP配置
  37. GPIO_InitStructure.GPIO_Pin = GUA_LIMIT_SWITCH_UP_PIN;
  38. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  39. GPIO_Init(GUA_LIMIT_SWITCH_UP_PORT, &GPIO_InitStructure);
  40. //DOWN配置
  41. GPIO_InitStructure.GPIO_Pin = GUA_LIMIT_SWITCH_DOWN_PIN;
  42. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  43. GPIO_Init(GUA_LIMIT_SWITCH_DOWN_PORT, &GPIO_InitStructure);
  44. }
  45. //******************************************************************************
  46. //name: GUA_Limit_Switch_Exti_Init
  47. //introduce: 限位开关的IO中断初始化
  48. //parameter: none
  49. //return: none
  50. //author: 甜甜的大香瓜
  51. //email: 897503845@qq.com
  52. //QQ group 香瓜单片机之STM8/STM32(164311667)
  53. //changetime: 2016.12.28
  54. //******************************************************************************
  55. static void GUA_Limit_Switch_Exti_Init(void)
  56. {
  57. EXTI_InitTypeDef EXTI_InitStructure;
  58. //UP中断配置
  59. EXTI_ClearITPendingBit(EXTI_Line1);
  60. GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
  61. EXTI_InitStructure.EXTI_Line = EXTI_Line1;
  62. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  63. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  64. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  65. EXTI_Init(&EXTI_InitStructure);
  66. //DOWN中断配置
  67. EXTI_ClearITPendingBit(EXTI_Line4);
  68. GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
  69. EXTI_InitStructure.EXTI_Line = EXTI_Line4;
  70. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  71. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  72. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  73. EXTI_Init(&EXTI_InitStructure);
  74. }
  75. //******************************************************************************
  76. //name: GUA_Limit_Switch_Check_Pin
  77. //introduce: 限位开关检测触发状态
  78. //parameter: nGUA_Limit_Switch_Status:GUA_LIMIT_SWITCH_STATUS_UP or GUA_LIMIT_SWITCH_STATUS_DOWN
  79. //return: GUA_LIMIT_SWITCH_STATUS_IDLE or GUA_LIMIT_SWITCH_STATUS_TRIGGER
  80. //author: 甜甜的大香瓜
  81. //QQ group 香瓜单片机之STM8/STM32(164311667)
  82. //changetime: 2016.12.28
  83. //******************************************************************************
  84. GUA_U8 GUA_Limit_Switch_Check_Pin(GUA_U8 nGUA_Limit_Switch_Status)
  85. {
  86. //UP限位开关
  87. if(nGUA_Limit_Switch_Status == GUA_LIMIT_SWITCH_STATUS_UP)
  88. {
  89. //没触发
  90. if(GPIO_ReadInputDataBit(GUA_LIMIT_SWITCH_UP_PORT, GUA_LIMIT_SWITCH_UP_PIN) == Bit_SET)
  91. {
  92. return GUA_LIMIT_SWITCH_STATUS_IDLE;
  93. }
  94. //触发
  95. else
  96. {
  97. return GUA_LIMIT_SWITCH_STATUS_TRIGGER;
  98. }
  99. }
  100. //DOWN限位开关
  101. else
  102. {
  103. //没触发
  104. if(GPIO_ReadInputDataBit(GUA_LIMIT_SWITCH_DOWN_PORT, GUA_LIMIT_SWITCH_DOWN_PIN) == Bit_SET)
  105. {
  106. return GUA_LIMIT_SWITCH_STATUS_IDLE;
  107. }
  108. //触发
  109. else
  110. {
  111. return GUA_LIMIT_SWITCH_STATUS_TRIGGER;
  112. }
  113. }
  114. }
  115. //******************************************************************************
  116. //name: GUA_Limit_Switch_Init
  117. //introduce: 限位开关初始化
  118. //parameter: none
  119. //return: none
  120. //author: 甜甜的大香瓜
  121. //email: 897503845@qq.com
  122. //QQ group 香瓜单片机之STM8/STM32(164311667)
  123. //changetime: 2016.12.28
  124. //******************************************************************************
  125. void GUA_Limit_Switch_Init(void)
  126. {
  127. //初始化IO
  128. GUA_Limit_Switch_IO_Init();
  129. //初始化IO的中断配置
  130. GUA_Limit_Switch_Exti_Init();
  131. }

2) 编写驱动头文件GUA_ Limit_Switch.h(存放在“ …… \HARDWARE ”)

    
    
  1. //******************************************************************************
  2. //name: GUA_Limit_Switch.h
  3. //introduce: 限位开关驱动头文件
  4. //author: 甜甜的大香瓜
  5. //email: 897503845@qq.com
  6. //QQ group 香瓜单片机之STM8/STM32(164311667)
  7. //changetime: 2016.12.28
  8. //******************************************************************************
  9. #ifndef _GUA_LIMIT_SWITCH_H_
  10. #define _GUA_LIMIT_SWITCH_H_
  11. /*********************宏定义************************/
  12. #ifndef GUA_U8
  13. typedef unsigned char GUA_U8;
  14. #endif
  15. #ifndef GUA_8
  16. typedef signed char GUA_8;
  17. #endif
  18. #ifndef GUA_U16
  19. typedef unsigned short GUA_U16;
  20. #endif
  21. #ifndef GUA_16
  22. typedef signed short GUA_16;
  23. #endif
  24. #ifndef GUA_U32
  25. typedef unsigned long GUA_U32;
  26. #endif
  27. #ifndef GUA_32
  28. typedef signed long GUA_32;
  29. #endif
  30. #ifndef GUA_U64
  31. typedef unsigned long long GUA_U64;
  32. #endif
  33. #ifndef GUA_64
  34. typedef signed long long GUA_64;
  35. #endif
  36. //可读的限位开关
  37. #define GUA_LIMIT_SWITCH_STATUS_UP 0 //UP限位开关
  38. #define GUA_LIMIT_SWITCH_STATUS_DOWN 1 //DWON限位开关
  39. //限位开关的触发状态
  40. #define GUA_LIMIT_SWITCH_STATUS_TRIGGER 0 //限位开关触发
  41. #define GUA_LIMIT_SWITCH_STATUS_IDLE 1 //D位开关没触发
  42. /*********************外部函数声明************************/
  43. GUA_U8 GUA_Limit_Switch_Check_Pin(GUA_U8 nGUA_Limit_Switch_Status);
  44. void GUA_Limit_Switch_Init(void);
  45. #endif

3) 工程中添加GUA_Limit_Switch.c


4)在MDK设置中添加串口驱动源文件路径



2、设置NVIC中断优先级(GUA_NVIC.c的GUA_NVIC_Init中)


    
    
  1. //限位开关UP键
  2. GUA_NVIC_Config(NVIC_PriorityGroup_2, EXTI1_IRQn, 1, 0, ENABLE);
  3. //限位开关DOWN键
  4. GUA_NVIC_Config(NVIC_PriorityGroup_2, EXTI4_IRQn, 1, 1, ENABLE);

3、写中断服务函数(stm32f10x_it.c中)

1)写中断服务函数


    
    
  1. //******************************************************************************
  2. //name: EXTI1_IRQHandler
  3. //introduce: 中断服务函数
  4. //parameter: none
  5. //return: none
  6. //author: 甜甜的大香瓜
  7. //email: 897503845@qq.com
  8. //QQ group 香瓜单片机之STM8/STM32(164311667)
  9. //changetime: 2016.10.19
  10. //******************************************************************************
  11. void EXTI1_IRQHandler(void)
  12. {
  13. if(EXTI_GetITStatus(EXTI_Line1) == SET)
  14. {
  15. /*
  16. //Up键,反转才停止
  17. if(stMotor_Config_2.DirectionSteps < 0)
  18. {
  19. stMotor_Config_2.Status = MOTOR_CONFIG_STATUS_IDLE; //电机Y停止
  20. }
  21. */
  22. //清除标志位
  23. EXTI_ClearITPendingBit(EXTI_Line1);
  24. }
  25. }
  26. //******************************************************************************
  27. //name: EXTI4_IRQHandler
  28. //introduce: 中断服务函数
  29. //parameter: none
  30. //return: none
  31. //author: 甜甜的大香瓜
  32. //email: 897503845@qq.com
  33. //QQ group 香瓜单片机之STM8/STM32(164311667)
  34. //changetime: 2016.10.19
  35. //******************************************************************************
  36. void EXTI4_IRQHandler(void)
  37. {
  38. if(EXTI_GetITStatus(EXTI_Line4) == SET)
  39. {
  40. /*
  41. //Down键,正转才停止
  42. if(stMotor_Config_2.DirectionSteps > 0)
  43. {
  44. stMotor_Config_2.Status = MOTOR_CONFIG_STATUS_IDLE; //电机Y停止
  45. }
  46. */
  47. //清除标志位
  48. EXTI_ClearITPendingBit(EXTI_Line4);
  49. }
  50. }
这里分别写了两个限位开关,并且简单举例限制电机。

4、在应用层中调用

1)添加驱动头文件(main.c中)

#include "GUA_Limit_Switch.h"
    
    

2) 添加驱动初始化代码(main.c的main函数中)


    
    
  1. //限位开关初始化
  2. GUA_Limit_Switch_Init();

七、实验结果

仿真并设置断点在两个限位开关的中断服务函数中,全速运行后分别按下限位开关,可分别进中断服务函数。

因此实验成功。




STM32F106是一款32微控制器,它没有直接的限位开关模块电路。通常情况下,限位开关模块是通过外部电路与STM32F106相连的。下面是一种常见的限位开关模块电路示意图: <img src="https://img-blog.csdn.net/20180627165240657?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N0b3JpZmYxMjM=I3N0b3JpZmYxMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/75" width="600"> 该电路由两个限位开关、两个电阻和一个电容组成。其中,两个限位开关分别与STM32F106的两个输入引脚相连,通过电阻分压器将输入电压从24V降至3.3V,以便与STM32F106的输入电平兼容。电容器用于减少开关信号的干扰。 在程序设计方面,可以通过STM32F106的GPIO模块来读取限位开关的状态。例如,将一个限位开关连接至STM32F106的PA0引脚,可以使用如下代码读取其状态: ```c #include "stm32f10x_gpio.h" GPIO_InitTypeDef GPIO_InitStructure; // 初始化PA0引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 读取PA0引脚的状态 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1){ // PA0引脚处于高电平状态,即限位开关未触发 }else{ // PA0引脚处于低电平状态,即限位开关已触发 } ``` 需要注意的是,限位开关的具体连接方式和程序设计可能会因具体应用而异,上述示例仅供参考。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值