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



所有评论(0)