一、实验目的

1.LED实验(点此可进入)基础上用STM32CubeMX生成Keil5工程文件和外设初始化代码(PB1为下降边沿触发外部中断1、PB2为下降边沿触发外部中断2、PB2抢占优先级高过 PB1 ; PA0、PB0为查询按键)。

2.在Keil5工程下,新建4个按键对应4个花式的流水灯(8个LED)程序,PA0、PB0按键在主程序的无限循环采用查询模式实现其对应流水灯花式,PB1、PB2在对应的中断服务程序中实现其对应流水灯花式循环一轮,PB2可以打断 PB1。

3.用开发板(STM32CubeMX的 HCLK 时钟设置为80M)验证。


二、软硬件环境

1.Java Run Time Environment (JRE);

2.STM32CubeMX软件;

3.Keil-MDK;

4.STM32G431RBTx开发板。


三、项目实现

1.STM32CubeMX修改相关配置

(1)重新配置PB1、PB2

        将PB1、PB2由GPIO_Input分别改为GPIO_EXTI1和GPIO_EXTI2。

        且“GPIO mode”均改为“External Interrupt M ode with Falling edge trigger detection”;同时,GPIO Pull-up/Pull-down配置为“Pull-up”。 

(2)配置NVIC

        “Priority Group”应选择2 bits,且在下面的NVIC Interrupt Table的配置应勾选EXTI line1与EXTI line2,且2的优先级应比1高,且“Time base”的优先级应为0。

(3)点击“Generate Code”生成工程代码。 

2.Keil调试、下载代码

 (1)外部中断处理流程

(2) 打开“stm32g4xx_it.c”

        在新生成的工程文件中,可以找到“stm32g4xx_it.c”,打开该文件,我们可找到EXIT1与EXIT2的相关函数,并且选中函数,可转到该函数的定义文件中。

 

(3)找到GPIO外部中断回调函数

         在上述的定义文件中,可看见一个中断请求处理函数HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)。且在验证确定为对应引脚所触发的中断后,将会调用GPIO外部中断回调函数。同样,也可通过右键转到该函数位置。

(4)编写回调函数代码

        将该弱定义的GPIO外部中断回调函数复制到main.c文件中,且需注释掉先前编写的有关PB1与PB2的相关代码。并将该回调函数内容删除,且需编写原先对应PB1与PB2的LED花式程序,且要令其循环一轮。

(5) 编译代码

        编译代码,若代码无误,便可下载代码,在开发板上检验PB1与PB2的中断功能,且确定PB2可打断PB1的中断。

 3.相关代码

 (1)Led.h
#ifndef LED_H
#define LED_H
void LED_Init(void);
void LED_ON(unsigned short int GPIO_Pin);
void LED_OFF(unsigned short int GPIO_Pin);
void LED_Toggle(unsigned short int GPIO_Pin);
void left_loop(void);
void right_loop(void);
#endif

(2)key.h
#ifndef KEY_H
#define KEY_H
unsigned char key_READ(void);
#endif

(3)Led.c
#include "Led.h"
#include "gpio.h"
void LED_Init(void)
{
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC, LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_RESET);
}
void LED_ON(unsigned short int GPIO_Pin)
{
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC, GPIO_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_RESET);
}
void LED_OFF(unsigned short int GPIO_Pin)
{
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC, GPIO_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_RESET);
}
void LED_Toggle(unsigned short int GPIO_Pin)
{
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_SET);
	HAL_GPIO_TogglePin ( GPIOC,GPIO_Pin );
	HAL_GPIO_WritePin(HC573_GPIO_Port, HC573_Pin, GPIO_PIN_RESET);
}
static uint16_t led_l = LED1_Pin;
void left_loop(void)
{
	LED_ON(led_l);
	HAL_Delay(100);
	LED_OFF(led_l);
	led_l<<=1;
	if(led_l==0)
		led_l=LED1_Pin;
}
static uint16_t led_r = LED8_Pin;
void right_loop(void)
{
	LED_ON(led_r);
	HAL_Delay(100);
	led_r>>=1;
	if(led_r==0)
		led_r=LED8_Pin;
	LED_OFF(led_r<<1);
}
(4)key.c
#include "main.h"
unsigned char value=0;
unsigned char key_READ(void)
{
	
	if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==GPIO_PIN_RESET)
	{
		HAL_Delay(20);
		if(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==GPIO_PIN_RESET)
		{
			value=1;
			while(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin)==GPIO_PIN_RESET);
		}
	}
//	if(HAL_GPIO_ReadPin(B2_GPIO_Port,B2_Pin)==GPIO_PIN_RESET)
//	{
//		HAL_Delay(20);
//		if(HAL_GPIO_ReadPin(B2_GPIO_Port,B2_Pin)==GPIO_PIN_RESET)
//		{
//			value=2;
//			while(HAL_GPIO_ReadPin(B2_GPIO_Port,B2_Pin)==GPIO_PIN_RESET);
//		}
//	}
//	if(HAL_GPIO_ReadPin(B3_GPIO_Port,B3_Pin)==GPIO_PIN_RESET)
//	{
//		HAL_Delay(20);
//		if(HAL_GPIO_ReadPin(B3_GPIO_Port,B3_Pin)==GPIO_PIN_RESET)
//		{
//			value=3;
//			while(HAL_GPIO_ReadPin(B3_GPIO_Port,B3_Pin)==GPIO_PIN_RESET);
//		}
//	}
	if(HAL_GPIO_ReadPin(B4_GPIO_Port,B4_Pin)==GPIO_PIN_RESET)
	{
		HAL_Delay(20);
		if(HAL_GPIO_ReadPin(B4_GPIO_Port,B4_Pin)==GPIO_PIN_RESET)
		{
			value=4;
			while(HAL_GPIO_ReadPin(B4_GPIO_Port,B4_Pin)==GPIO_PIN_RESET);
		}
	}
	return value;
}
(5)原先的Led实验中的按键控制4个花式
while (1)     
  {
		switch(key_READ()){
			/*Key query*/
			case 1:
				while(key_READ()==1)
					left_loop();
				break;
//			case 2:
//				while(key_READ()==2)
//					right_loop();
//				break;
//			case 3:
//				LED_ON(LED1_Pin|LED3_Pin|LED5_Pin|LED7_Pin);
//				LED_OFF(LED2_Pin|LED4_Pin|LED6_Pin|LED8_Pin);
//				HAL_Delay(100);
//				while(key_READ()==3)
//				{
//					/*flash half*/
//					LED_Toggle(LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin);
//					HAL_Delay(500);
//				}
//				break;
			case 4:
				while(key_READ()==4)
				{
					/*flash all*/
					LED_Toggle(LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin);
					HAL_Delay(300);
				}
				break;
			}
(6)外部中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	static uint8_t i,j;
	if(GPIO_Pin == GPIO_PIN_1)
	{
		LED_OFF(GPIO_PIN_All);
		for(i=0;i<8;i++)
		{
			right_loop();
			HAL_Delay(300);
		}
	}
	if(GPIO_Pin == GPIO_PIN_2)
	{
		LED_ON(LED1_Pin|LED3_Pin|LED5_Pin|LED7_Pin);
		LED_OFF(LED2_Pin|LED4_Pin|LED6_Pin|LED8_Pin);
		HAL_Delay(100);
		for(j=0;j<8;j++)
		{
			LED_Toggle(LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin);
			HAL_Delay(500);
		}
	}
}

四、实验效果

外部中断


五、总结

         在本次的实验中,成功的实现了外部中断功能,且其在开发板上的验证也符合预期。这标志着我通过该实验,掌握了外部中断的基本原理,且掌握了STM32外部中断的配置方法。并且我在实验过程中也对于嵌入式系统的开发流程更加熟悉,嵌入式编程能力和调试与优化能力也进一步增强。除此之外,我还深入理解了中断机制在实际应用中的重要性。后续可以进一步探索中断与其他外设的协同工作,以构建更高效的嵌入式系统。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐