对arm按键中断还是不太了解深入寄存器去看看
使用key_init()就能得到按键按下的值,所以中断函数在key)_init里

key_init()分析
初始化io口对应的按键
使能io口

使能RCC寄存器里 AHB1 外设时钟使能寄存器 (RCC_AHB1ENR)
使能io口的时钟

设置连接高电压的按键
按键WK_UP连接3.3v电压 是高电频有效

所以设置为 pa组第0号下拉输入
GPIO_Set(GPIOA,PIN0,GPIO_MODE_IN,0,0,GPIO_PUPD_PD); //PA0设置为下拉输入
设置连接地的按键
按键WK_UP连接3.3v电压 是低电频有效

所以设置为 PH组第2,3号上拉输入
GPIO_Set(GPIOH,PIN2|PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PU); //PH2/3设置上拉输入
判断哪个按键按下

看看这个函数是怎么定义的
#define KEY0 PHin(3)
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
1对于MEM_ADDR #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) 把地址再赋予指针
2 对于 BITBAND #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)《《5)+(bitnum《《2))
如果我们用PH(3)作为例子的话

那么算出来的值是 0x4243820C
所以就是读取 这个地址来判断输入的取值

通过查芯片手册 发现gpioH 不是这个范围-----》为什么能操控呢

GIPOD代位操作
发现我们的找到的控制的地址是 0x4200 0000 + 的这说明了 用了gpio代位操作
就是表明 用一个位 代表了4个字节 = 32bit
公式推算
一个地址A = 四个字节 一个字节= 8位
对于某个比特,他所在字节地址为A,位的序号为n(0《=n《=7),那么这个比特在的别名区为:
比特的别名区地址: = AliasAddr= =0x42000000+ (A-0x40000000)*8*4 +n*4 0X42000000 是外设位带别名区的起始地址,0x40000000 是外设位带区的起始地址,
(A-0x40000000)表示该比特前面有多少个字节,一个字节有 8 位,所以8,一个位膨胀
后是 4 个字节,所以4,n 表示该比特在 A 地址的序号,因为一个位经过膨胀后是四个字
节,所以也*4。
统一公式
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x000FFFFF)《《5)+(bitnum《《2)) addr & 0xF0000000 是为了区别 SRAM 还是外设,实际效果就是取出 4 或者 2,如果是
外设,则取出的是 4,+0X02000000 之后就等于 0X42000000,0X42000000 是外设别名区
的起始地址。如果是 SRAM,则取出的是 2,+0X02000000 之后就等于 0X22000000,
0X22000000 是 SRAM 别名区的起始地址。
addr & 0x00FFFFFF 屏蔽了高三位,相当于减去 0X20000000 或者 0X40000000,但是
为什么是屏蔽高三位?因为外设的最高地址是:0X2010 0000,跟起始地址 0X20000000 相
减的时候,总是低 5 位才有效,所以干脆就把高三位屏蔽掉来达到减去起始地址的效果,
具体屏蔽掉多少位跟最高地址有关。SRAM 同理分析即可。《《5 相当于84,《《2 相当于
*4,这两个我们在上面分析过。
返回程序进行解析
我们拿到 控制寄存器的 地址是 0x4243 820C
经过推算 我们控制的寄存器实在 0x40021C10 的 bit3 位

对他进行读取 就能得到 按键输出的数据
进行代码的重构
我们把代位操作(个人觉得不好用)换成了在寄存器上的操作 重新load一遍 发现和之前一样

至此按键中断的寄存器写法到这里完成
对arm按键中断还是不太了解深入寄存器去看看
使用key_init()就能得到按键按下的值,所以中断函数在key)_init里

key_init()分析
初始化io口对应的按键
使能io口

使能RCC寄存器里 AHB1 外设时钟使能寄存器 (RCC_AHB1ENR)
使能io口的时钟

设置连接高电压的按键
按键WK_UP连接3.3v电压 是高电频有效

所以设置为 pa组第0号下拉输入
GPIO_Set(GPIOA,PIN0,GPIO_MODE_IN,0,0,GPIO_PUPD_PD); //PA0设置为下拉输入
设置连接地的按键
按键WK_UP连接3.3v电压 是低电频有效

所以设置为 PH组第2,3号上拉输入
GPIO_Set(GPIOH,PIN2|PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PU); //PH2/3设置上拉输入
判断哪个按键按下

看看这个函数是怎么定义的
#define KEY0 PHin(3)
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
1对于MEM_ADDR #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) 把地址再赋予指针
2 对于 BITBAND #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)《《5)+(bitnum《《2))
如果我们用PH(3)作为例子的话

那么算出来的值是 0x4243820C
所以就是读取 这个地址来判断输入的取值

通过查芯片手册 发现gpioH 不是这个范围-----》为什么能操控呢

GIPOD代位操作
发现我们的找到的控制的地址是 0x4200 0000 + 的这说明了 用了gpio代位操作
就是表明 用一个位 代表了4个字节 = 32bit
公式推算
一个地址A = 四个字节 一个字节= 8位
对于某个比特,他所在字节地址为A,位的序号为n(0《=n《=7),那么这个比特在的别名区为:
比特的别名区地址: = AliasAddr= =0x42000000+ (A-0x40000000)*8*4 +n*4 0X42000000 是外设位带别名区的起始地址,0x40000000 是外设位带区的起始地址,
(A-0x40000000)表示该比特前面有多少个字节,一个字节有 8 位,所以8,一个位膨胀
后是 4 个字节,所以4,n 表示该比特在 A 地址的序号,因为一个位经过膨胀后是四个字
节,所以也*4。
统一公式
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x000FFFFF)《《5)+(bitnum《《2)) addr & 0xF0000000 是为了区别 SRAM 还是外设,实际效果就是取出 4 或者 2,如果是
外设,则取出的是 4,+0X02000000 之后就等于 0X42000000,0X42000000 是外设别名区
的起始地址。如果是 SRAM,则取出的是 2,+0X02000000 之后就等于 0X22000000,
0X22000000 是 SRAM 别名区的起始地址。
addr & 0x00FFFFFF 屏蔽了高三位,相当于减去 0X20000000 或者 0X40000000,但是
为什么是屏蔽高三位?因为外设的最高地址是:0X2010 0000,跟起始地址 0X20000000 相
减的时候,总是低 5 位才有效,所以干脆就把高三位屏蔽掉来达到减去起始地址的效果,
具体屏蔽掉多少位跟最高地址有关。SRAM 同理分析即可。《《5 相当于84,《《2 相当于
*4,这两个我们在上面分析过。
返回程序进行解析
我们拿到 控制寄存器的 地址是 0x4243 820C
经过推算 我们控制的寄存器实在 0x40021C10 的 bit3 位

对他进行读取 就能得到 按键输出的数据
进行代码的重构
我们把代位操作(个人觉得不好用)换成了在寄存器上的操作 重新load一遍 发现和之前一样

至此按键中断的寄存器写法到这里完成
举报