硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1841|回复: 5
收起左侧

[GPIO] 关于STM32软件中断的分享和提问

[复制链接]

2

主题

23

回帖

29

积分

新手上路

积分
29
发表于 2021-12-2 20:43:53 | 显示全部楼层 |阅读模式

感觉没有什么写软件中断的文章,最近特别研究了一下

以目前来看,软件中断属于外部中断,也就是EXTI。

软件前几个LINE其实就是GPIO中断,中断响应入口也是一样的。区别在于GPIO中断是IO触发的,软件中断是代码触发的。还有个重要区别是ST官方库的特点,在于IMR寄存器的配置。
GPIO中断在GPIO_INIT的函数中就配置了IMR寄存器,但如果要开软件中断,需要另外配置IMR寄存器。我最开始研究用软件中断时候一直没配置IMR,导致怎么也进不去,后来就一直手动配IMR。
但直接动寄存器总感觉不太正规,最近仔细找了下发现了 HAL_EXTI_SetConfigLine 这个函数,这个函数是配置外部中断专用的,里面就会配置IMR。外部中断还有专门的处理函数 HAL_EXTI_IRQHandler 可以用函数指针调用任何函数,更灵活了。

有几个问题想问问
1、外部中断有很多个LINE,如下,远超过GPIO中断的数量,这些中断都怎么用的?如果GPIO中断入口是EXTIx_IRQHandler,超过GPIO编号的中断响应入口在哪?
#define EXTI_LINE_0                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x00U)
#define EXTI_LINE_1                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x01U)
#define EXTI_LINE_2                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x02U)
#define EXTI_LINE_3                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x03U)
#define EXTI_LINE_4                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x04U)
#define EXTI_LINE_5                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x05U)
#define EXTI_LINE_6                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x06U)
#define EXTI_LINE_7                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x07U)
#define EXTI_LINE_8                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x08U)
#define EXTI_LINE_9                         (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x09U)
#define EXTI_LINE_10                        (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x0AU)
#define EXTI_LINE_11                        (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x0BU)
#define EXTI_LINE_12                        (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x0CU)
#define EXTI_LINE_13                        (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x0DU)
#define EXTI_LINE_14                        (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x0EU)
#define EXTI_LINE_15                        (EXTI_GPIO     | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x0FU)
#define EXTI_LINE_16                        (EXTI_CONFIG   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x10U)
#define EXTI_LINE_17                        (EXTI_CONFIG   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x11U)
#define EXTI_LINE_18                        (EXTI_CONFIG   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x12U)
#define EXTI_LINE_19                        (EXTI_CONFIG   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x13U)
#define EXTI_LINE_20                        (EXTI_CONFIG   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x14U)
#define EXTI_LINE_21                        (EXTI_CONFIG   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x15U)
#define EXTI_LINE_22                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x16U)
#define EXTI_LINE_23                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x17U)
#define EXTI_LINE_24                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x18U)
#define EXTI_LINE_25                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL     | 0x19U)
#define EXTI_LINE_26                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x1AU)
#define EXTI_LINE_27                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x1BU)
#define EXTI_LINE_28                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x1CU)
#define EXTI_LINE_29                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x1DU)
#define EXTI_LINE_30                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x1EU)
#define EXTI_LINE_31                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG1 | EXTI_TARGET_MSK_ALL_CPU | 0x1FU)
#define EXTI_LINE_32                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x00U)
#define EXTI_LINE_33                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x01U)
#define EXTI_LINE_34                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL     | 0x02U)
#define EXTI_LINE_35                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL     | 0x03U)
#define EXTI_LINE_36                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x04U)
#define EXTI_LINE_37                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x05U)
#define EXTI_LINE_38                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x06U)
#define EXTI_LINE_39                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x07U)
#define EXTI_LINE_40                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x08U)
#define EXTI_LINE_41                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL     | 0x09U)
#define EXTI_LINE_42                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x0AU)
#define EXTI_LINE_43                        (EXTI_DIRECT   | EXTI_EVENT | EXTI_REG2 | EXTI_TARGET_MSK_ALL_CPU | 0x0BU)



2、如下结构体是配置外部中断的,里面有几个参数不明。
1)GPIO中断有上升沿或者下降沿触发,在配置软件中断时候,或者说配置外部中断时候,也有这个沿的设置,就是下面结构体里trigger的设置。但在软件中断里这个沿怎么理解,要不要配,如果不配会怎么样呢?
2)外部中断配置时候还有个关联GPIO的功能,如下面结构体GPIOSel,这个是怎么个意思?
typedef struct
{
  uint32_t Line;           /*!< The Exti line to be configured. This parameter
                                can be a value of @ref EXTI_Line */
  uint32_t Mode;           /*!< The Exit Mode to be configured for a core.
                                This parameter can be a combination of @ref EXTI_Mode */
  uint32_t Trigger;        /*!< The Exti Trigger to be configured. This parameter
                                can be a value of @ref EXTI_Trigger */
  uint32_t GPIOSel;        /*!< The Exti GPIO multiplexer selection to be configured.
                                This parameter is only possible for line 0 to 15. It
                                can be a value of @ref EXTI_GPIOSel */

  uint32_t PendClearSource; /*!< Specifies the event pending clear source for D3/SRD
                                 domain. This parameter can be a value of @ref
                                 EXTI_PendClear_Source */

} EXTI_ConfigTypeDef;




坐等大侠来解答
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2021-12-3 00:37:38 | 显示全部楼层
这个是不是VScode直接复制出来的。现在HAL库的外部中断配置比较省事了,直接GPIO_Init就可配置了。

1、GPIO只用了前16个,后面的都是专用的。
QQ截图20211203003557.png


2、上升沿,下降沿或者双沿,要配置的。


回复

使用道具 举报

2

主题

23

回帖

29

积分

新手上路

积分
29
 楼主| 发表于 2021-12-3 09:17:46 | 显示全部楼层
eric2013 发表于 2021-12-3 00:37
这个是不是VScode直接复制出来的。现在HAL库的外部中断配置比较省事了,直接GPIO_Init就可配置了。

1、G ...

是VSCode,编辑模式底色还是连续的,出来就一条条了…………
用GPIO_INIT不是还配了IO嘛,我意思是不用IO触发,不占用IO,用__HAL_GPIO_EXTI_GENERATE_SWIT或者HAL_EXTI_GenerateSWI来触发的,就只配置个中断,用代码触发,我一般是给高级中断降级用的。
1、这个表格里的源如果我没用是不是可以用来做软件中断,就像占用IO的中断一样,这样IO的中断就省出来了。
2、这个上升下降沿,是不是软件中断会出个脉冲,无论配什么沿都能触发,只是下降沿会比上升沿晚个脉冲宽度。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2021-12-3 09:32:26 | 显示全部楼层
浪里个白条 发表于 2021-12-3 09:17
是VSCode,编辑模式底色还是连续的,出来就一条条了…………
用GPIO_INIT不是还配了IO嘛,我意思是不用I ...

1、前16个以后的应该不行,中断向量表里面没有相应的中断入口了。如果强行使用使用连接的外设中断,不知道行不行,可以试试。

2、这个可以看下EXTI的框图,同1时刻使用上升沿还是下降沿肯定有个先后问题,不是同1时刻就不一定那个是先,那个是后了。

回复

使用道具 举报

2

主题

23

回帖

29

积分

新手上路

积分
29
 楼主| 发表于 2021-12-3 10:09:03 | 显示全部楼层
eric2013 发表于 2021-12-3 09:32
1、前16个以后的应该不行,中断向量表里面没有相应的中断入口了。如果强行使用使用连接的外设中断,不知 ...

1、我之前没看到那个表格,多谢提醒,刚研究了下,猜想是要求Event input type 是Configurable, Connection to NVIC要求是Yes,这样就能用软件启动中断,我找到一条比较明显的LINE86 ETHERNET wakeup 对应中断应该就是ETH_WKUP_IRQn,等我试下看行不行2、从下面这个图看,我猜就是软件中断和GPIO的沿应该是作用方式一样,只是软件中断会出个脉冲,无论设什么沿都能触发,但是总有个先后,感觉这个设置有点鸡肋,不如把软件中断直接跳过沿检测接到后面

IM图片_2021123_100336.png
回复

使用道具 举报

4

主题

160

回帖

172

积分

初级会员

积分
172
发表于 2021-12-8 11:12:14 | 显示全部楼层
用过的分享一下 软件中断的实例。
还没用过软件中断呢。应该很有用。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-30 00:05 , Processed in 0.251667 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表