一、简介
本文介绍如何在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
1、限位开关是什么?
答:限位开关其实就是会复原开关的开关按键。
也就是说按下限位开关的开关能触发STM32的IO中断,而松开手指时限位开关会复原。
2、限位开关有什么用?
答:通常被用于限制电机转动角度来使用。
例如两个限位开关形成45°的夹角,一旦电机转动触发任意其中一个限位开关,STM32检测到限位开关的中断则停止电机,不能再继续往此方向转动。
3、限位开关有什么优缺点?
答:限位开关的优点是以物理的方式触发单片机中断,因此不增加功耗。缺点是经常使用的话限位开关易损坏。
4、限位开关在软件上应如何开发?
答:由于限位开关通常是两个,因此按照普通按键的形式写两个按键,在按键中断中做停止电机等处理即可。
六、实验步骤
1、编写并添加限位开关驱动
1)编写驱动GUA_Limit_Switch.c(存放在“……\HARDWARE”)
-
//******************************************************************************
-
//name: GUA_Limit_Switch.c
-
//introduce: 限位开关驱动
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.12.28
-
//******************************************************************************
-
#include "stm32f10x.h"
-
#include "GUA_Limit_Switch.h"
-
-
/*********************宏定义************************/
-
//引脚宏定义
-
#define GUA_LIMIT_SWITCH_UP_PORT GPIOA
-
#define GUA_LIMIT_SWITCH_UP_PIN GPIO_Pin_1
-
-
#define GUA_LIMIT_SWITCH_DOWN_PORT GPIOA
-
#define GUA_LIMIT_SWITCH_DOWN_PIN GPIO_Pin_4
-
-
/*********************内部函数************************/
-
static void GUA_Limit_Switch_IO_Init(void);
-
static void GUA_Limit_Switch_Exti_Init(void);
-
-
//******************************************************************************
-
//name: GUA_Limit_Switch_IO_Init
-
//introduce: 限位开关的IO初始化
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.12.28
-
//******************************************************************************
-
static void GUA_Limit_Switch_IO_Init(void)
-
{
-
//IO结构体
-
GPIO_InitTypeDef GPIO_InitStructure;
-
-
//时钟使能
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
-
-
//UP配置
-
GPIO_InitStructure.GPIO_Pin = GUA_LIMIT_SWITCH_UP_PIN;
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
-
GPIO_Init(GUA_LIMIT_SWITCH_UP_PORT, &GPIO_InitStructure);
-
-
//DOWN配置
-
GPIO_InitStructure.GPIO_Pin = GUA_LIMIT_SWITCH_DOWN_PIN;
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
-
GPIO_Init(GUA_LIMIT_SWITCH_DOWN_PORT, &GPIO_InitStructure);
-
}
-
-
//******************************************************************************
-
//name: GUA_Limit_Switch_Exti_Init
-
//introduce: 限位开关的IO中断初始化
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.12.28
-
//******************************************************************************
-
static void GUA_Limit_Switch_Exti_Init(void)
-
{
-
EXTI_InitTypeDef EXTI_InitStructure;
-
-
//UP中断配置
-
EXTI_ClearITPendingBit(EXTI_Line1);
-
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
-
-
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
-
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
-
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
-
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
-
EXTI_Init(&EXTI_InitStructure);
-
-
//DOWN中断配置
-
EXTI_ClearITPendingBit(EXTI_Line4);
-
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
-
-
EXTI_InitStructure.EXTI_Line = EXTI_Line4;
-
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
-
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
-
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
-
EXTI_Init(&EXTI_InitStructure);
-
}
-
-
//******************************************************************************
-
//name: GUA_Limit_Switch_Check_Pin
-
//introduce: 限位开关检测触发状态
-
//parameter: nGUA_Limit_Switch_Status:GUA_LIMIT_SWITCH_STATUS_UP or GUA_LIMIT_SWITCH_STATUS_DOWN
-
//return: GUA_LIMIT_SWITCH_STATUS_IDLE or GUA_LIMIT_SWITCH_STATUS_TRIGGER
-
//author: 甜甜的大香瓜
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.12.28
-
//******************************************************************************
-
GUA_U8 GUA_Limit_Switch_Check_Pin(GUA_U8 nGUA_Limit_Switch_Status)
-
{
-
//UP限位开关
-
if(nGUA_Limit_Switch_Status == GUA_LIMIT_SWITCH_STATUS_UP)
-
{
-
//没触发
-
if(GPIO_ReadInputDataBit(GUA_LIMIT_SWITCH_UP_PORT, GUA_LIMIT_SWITCH_UP_PIN) == Bit_SET)
-
{
-
return GUA_LIMIT_SWITCH_STATUS_IDLE;
-
}
-
//触发
-
else
-
{
-
return GUA_LIMIT_SWITCH_STATUS_TRIGGER;
-
}
-
}
-
//DOWN限位开关
-
else
-
{
-
//没触发
-
if(GPIO_ReadInputDataBit(GUA_LIMIT_SWITCH_DOWN_PORT, GUA_LIMIT_SWITCH_DOWN_PIN) == Bit_SET)
-
{
-
return GUA_LIMIT_SWITCH_STATUS_IDLE;
-
}
-
//触发
-
else
-
{
-
return GUA_LIMIT_SWITCH_STATUS_TRIGGER;
-
}
-
}
-
}
-
-
//******************************************************************************
-
//name: GUA_Limit_Switch_Init
-
//introduce: 限位开关初始化
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.12.28
-
//******************************************************************************
-
void GUA_Limit_Switch_Init(void)
-
{
-
//初始化IO
-
GUA_Limit_Switch_IO_Init();
-
-
//初始化IO的中断配置
-
GUA_Limit_Switch_Exti_Init();
-
}
2) 编写驱动头文件GUA_ Limit_Switch.h(存放在“ …… \HARDWARE ”)
-
//******************************************************************************
-
//name: GUA_Limit_Switch.h
-
//introduce: 限位开关驱动头文件
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.12.28
-
//******************************************************************************
-
#ifndef _GUA_LIMIT_SWITCH_H_
-
#define _GUA_LIMIT_SWITCH_H_
-
-
/*********************宏定义************************/
-
#ifndef GUA_U8
-
typedef
unsigned
char GUA_U8;
-
#endif
-
-
#ifndef GUA_8
-
typedef
signed
char GUA_8;
-
#endif
-
-
#ifndef GUA_U16
-
typedef
unsigned
short GUA_U16;
-
#endif
-
-
#ifndef GUA_16
-
typedef
signed
short GUA_16;
-
#endif
-
-
#ifndef GUA_U32
-
typedef
unsigned
long GUA_U32;
-
#endif
-
-
#ifndef GUA_32
-
typedef
signed
long GUA_32;
-
#endif
-
-
#ifndef GUA_U64
-
typedef
unsigned
long
long GUA_U64;
-
#endif
-
-
#ifndef GUA_64
-
typedef
signed
long
long GUA_64;
-
#endif
-
-
//可读的限位开关
-
#define GUA_LIMIT_SWITCH_STATUS_UP 0 //UP限位开关
-
#define GUA_LIMIT_SWITCH_STATUS_DOWN 1 //DWON限位开关
-
-
//限位开关的触发状态
-
#define GUA_LIMIT_SWITCH_STATUS_TRIGGER 0 //限位开关触发
-
#define GUA_LIMIT_SWITCH_STATUS_IDLE 1 //D位开关没触发
-
-
/*********************外部函数声明************************/
-
GUA_U8 GUA_Limit_Switch_Check_Pin(GUA_U8 nGUA_Limit_Switch_Status);
-
void GUA_Limit_Switch_Init(void);
-
-
#endif
3) 工程中添加GUA_Limit_Switch.c
4)在MDK设置中添加串口驱动源文件路径
2、设置NVIC中断优先级(GUA_NVIC.c的GUA_NVIC_Init中)
-
//限位开关UP键
-
GUA_NVIC_Config(NVIC_PriorityGroup_2, EXTI1_IRQn,
1,
0, ENABLE);
-
-
//限位开关DOWN键
-
GUA_NVIC_Config(NVIC_PriorityGroup_2, EXTI4_IRQn,
1,
1, ENABLE);
3、写中断服务函数(stm32f10x_it.c中)
1)写中断服务函数
-
//******************************************************************************
-
//name: EXTI1_IRQHandler
-
//introduce: 中断服务函数
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.19
-
//******************************************************************************
-
void EXTI1_IRQHandler(void)
-
{
-
if(EXTI_GetITStatus(EXTI_Line1) == SET)
-
{
-
/*
-
//Up键,反转才停止
-
if(stMotor_Config_2.DirectionSteps < 0)
-
{
-
stMotor_Config_2.Status = MOTOR_CONFIG_STATUS_IDLE; //电机Y停止
-
}
-
*/
-
//清除标志位
-
EXTI_ClearITPendingBit(EXTI_Line1);
-
}
-
}
-
-
//******************************************************************************
-
//name: EXTI4_IRQHandler
-
//introduce: 中断服务函数
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.19
-
//******************************************************************************
-
void EXTI4_IRQHandler(void)
-
{
-
if(EXTI_GetITStatus(EXTI_Line4) == SET)
-
{
-
/*
-
//Down键,正转才停止
-
if(stMotor_Config_2.DirectionSteps > 0)
-
{
-
stMotor_Config_2.Status = MOTOR_CONFIG_STATUS_IDLE; //电机Y停止
-
}
-
*/
-
//清除标志位
-
EXTI_ClearITPendingBit(EXTI_Line4);
-
}
-
}
这里分别写了两个限位开关,并且简单举例限制电机。
4、在应用层中调用
1)添加驱动头文件(main.c中)
#include "GUA_Limit_Switch.h"
2) 添加驱动初始化代码(main.c的main函数中)
-
//限位开关初始化
-
GUA_Limit_Switch_Init();
七、实验结果
仿真并设置断点在两个限位开关的中断服务函数中,全速运行后分别按下限位开关,可分别进中断服务函数。
因此实验成功。