手把手教STM32基础项目之震动感应灯

目录

1.项目概述

2.材料准备

3.接线图

4.GPIO相关配置

5.中断相关配置

6.项目总结 


1.项目概述

该项目非常适合初学stm32的小白进行尝试,本项目运用了stm32常用的外设如io,中断,也用到了常用的模块,有继电器模块,振动传感器,相信尝试完这个项目之后小白们都可以顺利入门stm32.

2.材料准备

1.stm32F103c8t6最最小系统板

2.震动传感器模块

3.一路继电器模块

3.接线图

 

4.GPIO相关配置

首先我们先回顾一下GPIO相关的配置,震动传感器的输出引脚产生震动输出低电平,没有震动是高电平。我们首先选择一个单片机的引脚连接振动传感器的引脚,这里我们就选PA1这个引脚。

从下面的系统结构图可以看出,GPIOA是搭载在APB2总线下的,因此我们需要开启APB2的时钟。

 我们在固件库中找到APB2的使能函数配置使能就可以了。

配置好就是这个样子

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,  ENABLE);

接着我们配置GPIO的功能

固件库需要我们配置引脚编号,速度,模式三个参数。我们分别配置成PA1,50,10M。

** 
  * @brief  GPIO Init structure definition  
  */

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

shake.c(配置震动传感器)

#include "shake.h"
#include "stm32f10x.h"

void Shake_Init(void)
{
	
    GPIO_InitTypeDef shake_init; //这里结构体的定义要在时钟之前,不然会报错
	
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,  ENABLE);

    shake_init.GPIO_Mode =GPIO_Mode_IPD;
	shake_init.GPIO_Pin  =GPIO_Pin_1;
	shake_init.GPIO_Speed=GPIO_Speed_10MHz;
	
	GPIO_Init(GPIOA,&shake_init);

}

relay.c(配置继电器)

#include "relay.h"
#include "stm32f10x.h"
 
 void Relay_Init(void)
 {
	 
	 GPIO_InitTypeDef Relay_init;//ʹÄÜGPIOAµÄʱÖÓ
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );、
	 
	 Relay_init.GPIO_Mode =GPIO_Mode_IPU ;
     Relay_init.GPIO_Pin  =GPIO_Pin_5;
	 Relay_init.GPIO_Speed=GPIO_Speed_10MHz;

     GPIO_Init( GPIOA, &Relay_init  );

 }	 

5.中断相关配置

如何配置中断:

1. 初始化用来中断的GPIO口

2. 初始化EXTI

3. 配置NVIC(中断优先级) 配置中断的优先级,中断嵌套

4.编写中断服务函数

中断简介

stm32总共有20条中断线,而0-15是我们GPIO的,其它的是特殊功能的中断线。我们只关心GPIO的中断线即可。

选择好中断先后我们通过输入线进入,接着经过边沿检测电路,边沿检测这里又分了,上升沿触发检测(0变化到1的过程),下降沿触发检测(1变化到0的过程).......。由于我们震动传感器至少高低电平的变化,因此我们只需关注是上升沿触发检测还是下降沿触发检测。配置完边沿检测后我们会来到NVIC中断控制器,它其实也是一个外设,只不过是内核的外设,跟配置exti是一样的都是配置结构体。

 

 配置EXTI

首先来回顾一下EXTI的结构体成员有哪些。

typedef struct
{
  uint32_t EXTI_Line;     //EXTI选择中断线/事件线选择        
   
  EXTIMode_TypeDef EXTI_Mode; //EXTI模式选择,可选择为中断模式/产生事件      

  EXTITrigger_TypeDef EXTI_Trigger; //EXTI边沿触发事件,可选择为上升沿触发,下降沿触发,
                                                       上升沿下降沿都触发

  FunctionalState EXTI_LineCmd;    //控制是否使能EXTI线
}EXTI_InitTypeDef;

配置NVIC

typedef struct
{

  uint8_t NVIC_IRQChannel; //设置中断通道

  uint8_t NVIC_IRQChannelPreemptionPriority; //设置抢占优先级

  uint8_t NVIC_IRQChannelSubPriority;     //设置子优先级
   
  FunctionalState NVIC_IRQChannelCmd;   //是否使能NVIC

} NVIC_InitTypeDef;

这里要注意:在配置之前抢占优先级还需定义优先级组,不同的组别优先级也是不一样的,组别的数字越小说明优先级越高。比较的时候先是比较抢占优先级,谁的数字越小谁的优先级就高。 如果抢占优先级数字一样, 那么我们就去比较子优先级,比较方法和抢占优先级是一样的,如抢占优先级和子优先级一样, 那么会比较中断的序号,同样也是序号数越小优先级越高。

exti.c(配置中断)

#include "stm32f10x.h"
#include "exti.h"

void exti_Init(void)
{
	// 1.配置GPIO
	GPIO_InitTypeDef shake_init;
	EXTI_InitTypeDef exti_init;
	NVIC_InitTypeDef nvic_init;
	
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,  ENABLE);
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO,  ENABLE);
	GPIO_EXTILineConfig( GPIO_PortSourceGPIOA,  GPIO_PinSource1);
	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);
	
    shake_init.GPIO_Mode =GPIO_Mode_IPD;
	shake_init.GPIO_Pin  =GPIO_Pin_1;
	shake_init.GPIO_Speed=GPIO_Speed_10MHz;
	
	GPIO_Init(GPIOA,&shake_init);
	//2.配置EXTI外部中断
	exti_init.EXTI_Line    = EXTI_Line1 ; //设置中断通道
	exti_init.EXTI_LineCmd = ENABLE;     
	exti_init.EXTI_Mode    =EXTI_Mode_Interrupt;
	exti_init.EXTI_Trigger=EXTI_Trigger_Falling;
	
	EXTI_Init(&exti_init);
	
	//3.配置NVIC中断控制器
	nvic_init.NVIC_IRQChannel =EXTI1_IRQn;         //设置中断通道	
	nvic_init.NVIC_IRQChannelPreemptionPriority =1;//设置抢占优先级
	nvic_init.NVIC_IRQChannelSubPriority =1;       //设置子优先级
	nvic_init.NVIC_IRQChannelCmd=ENABLE;           //使能
  NVIC_Init(&nvic_init);

}

 编写中断服务函数:

main.c

#include "stm32f10x.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"

  void delay(uint16_t time)
{
	  uint16_t i=0;
	  while(time--)
	 
		   {
				 i=16000;
	       while(i--);
			 }
	 
		 }		
	
	
int  main()
{
 Shake_Init();
 Relay_Init();


void EXTI1_IRQHandler(void)
{
   if(EXTI_GetITStatus(EXTI_Line1 != RESET)) //判断是否发送中断

  {
         GPIO_SetBits(GPIOA,  GPIO_Pin_5);   //打开继电器,开灯
         delay(1000);
		 GPIO_ResetBits(GPIOA,  GPIO_Pin_5);  //关闭继电器,关灯

  }

}

6.项目总结 

这个项目实现起来比较简单,帮助初学者体验了一把软硬件结合的快感,也熟悉了stm32的一些基本的外设,我本人也是从这个小项目入坑stm32的,希望对大家有所帮助。

  • 0
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LJX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值