STM32CubeMX学习笔记4-外部中断

   由于原来的F407的板子烧坏了,现在换成F103的板子进行学习

1、外部中断简介 

        STM32F1的每个IO口都可以作为外部中断的中断输入,STM32F103的中断控制器支持19个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103的19个外部中断为:

  • EXTI线0~15:对应外部IO口的输入中断
  • EXTI线16:连接到PVD输出
  • EXTI线17:连接到RTC闹钟事件
  • EXTI线18:连接到USB唤醒事件
  • EXTI线19:连接到以太网唤醒事件(互联网型产品)

STM32F103供IO口使用的中断线只有16个,但是IO口却远不止16个。下图为GPIO跟中断线的映射关系图

2、硬件介绍

板子的几个按键的原理图如下

        在第2章我们学习到了按键的检测,本章将在按键检测的基础上学习外部中断,将用上升沿触发和下降沿触发两种触发方式来实现中断,并在中断中通过串口输出对应的字符串。

其中S4是高电平有效,因此应设置为下拉、上升沿触发中断 。而S1,S2,S3都是低电平有效,因此设置2为上拉,下降沿触发中断。

3、STM32CubeMX设置

选择芯片STM32F103ZET6,建立工程,设置好工程名称及目录。

RCC设置外接HSE,时钟设置为72M。

设置串口1,并打开串口中断。

(1)、将PA0设置成外部中断模式,触发模式选择上升沿触发,GPIO Pull-up/Pull-down中选择Pull-down上拉,并命名为S4。

 (2)将PE4,PE3,PE3,设置成外部中断模式,触发模式选择下降沿触发,GPIO Pull-up/Pull-down中选择Pull-up上拉,命名分别命名为S1,S2,S3

(3)、使能外部中断,并将优先级都设置为2.

配置好时钟树和基础设置即可生成代码了。

4、代码编写

在在gpio.c文件中可以看到PA0/PE2/PE3/PE4管脚的初始化函数。

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);

  /*Configure GPIO pins : PEPin PEPin PEPin */
  GPIO_InitStruct.Pin = S3_Pin|S2_Pin|S1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = LED3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LED3_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = S4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(S4_GPIO_Port, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);

  HAL_NVIC_SetPriority(EXTI2_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI2_IRQn);

  HAL_NVIC_SetPriority(EXTI3_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI3_IRQn);

  HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI4_IRQn);

}

随后我们可以在stm32f1xx_it.c中看到我们所配置的中断服务函数

重定义串口函数,

unsigned char tx_buf[256];
#define printf1(...) HAL_UART_Transmit(&huart1,tx_buf,sprintf((char*)tx_buf,__VA_ARGS__),10);

在main文件中编写中断回调函数

void delay(int ms)
{
	int i,j;
	for(i=0;i<ms;i++)
		for(j=0;j<110;j++);
	
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){

	delay(10);  //延时消抖,不建议
	switch(GPIO_Pin){
        case GPIO_PIN_0:
					
					if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==1)
            printf1("STM32F103 EXTI test this key is S4\r\n"); //A0
           break;
        case GPIO_PIN_2::
						
						if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)==0)
							printf1("STM32F103 EXTI test this key is S3\r\n"); //E2
            break;
        case GPIO_PIN_3:
						
						if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0)
							printf1("STM32F103 EXTI test this key is S2\r\n"); //E3
            break;
        case GPIO_PIN_4:
						
						if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
              printf1("STM32F103 EXTI test this key is S1\r\n"); //E4
            break;
    }
}

         在这里我自己写了一个延时函数,用作按键的消抖,至于为什么不适用hal库的延时函数(HAL_Delay();),是因为在使用的时候触发中断时程序会卡死,经过调试后发现程序卡死在delay函数中的while循环中,可能是因为在中断过程中导致时钟不再更新了导致的(个人观点),有知道的大佬可以在评论区留言。

 中断函数应该是快进快出的,这里加了延时消抖是会影响效率的,所以不建议加。

5、程序验证

将程序编译无误后下载到板子上,按下相应按键就会输出对应的信息。

参考文献:

【STM32】HAL库 STM32CubeMX教程三----外部中断(HAL库GPIO讲解)_hal_gpio_exti_callback-CSDN博客

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值