
一个菜鸟的STM32寄存器学习笔记2_输入按键扫描.pdf
4页使用 GPIO输入功能实现按键扫描,来控制 LED灯的亮灭 一. 需要配置的寄存器 1. 配置相关引脚时钟,包括与 LED和按键 key相连的 IO 口: RCC->APB2ENR 2. 配置相关引脚的工作模式( LED 强制推挽输出, key 如果没有外接上拉或者下拉电阻则在内部设置为上拉或下拉输入模式,如果 key外接上拉或下拉电阻则设置为浮空输入模式 ) GPIOB->CRL (key 用的是 GIOB.0) 3. 获取按键 KEY的值并进行判断 二. 详细说明(按键使用的是 GPIOB的 0脚 没有外接上拉或者下拉电阻, LED是 GPIOC的 1脚 ) 第一步 配置 LED和 key的时钟 这里配置时钟和配置 LED 是一样的把对应的位写上 1 即可(补充一个 LED 那个文档的一个问题 :在 LED 那个笔记里说给某位写 1 要先清零再写入,感觉没有必要清零,使用的 位或 方法不管原来里面是 1还是 0或上 1还是 1 给某位写 0一样,只要和 0位与 就可以 ) 我们要给 GPIOC和 GPIOB时钟使能就位或一个数就可以要给 GPIOC使能 RCC->APB2ENR |= 0x00000010; 给 GPIOB使能 RCC->APB2ENR |=0X00000008; 也可以写在一起 (不推荐,因为修改程序不方便,上面的哪个不用注释掉就好,写在一起需要修改数字容易出错 ) RCC->APB2ENR |=0X00000018; 第二步 配置 IO口的工作模式 需要配置两东西, LED的相关配置可以使用第一篇文章配置好的, key根据 自己硬件 分成两种情况 1.有外界上拉 /下拉电阻配置成 浮空输入 2.无外部上拉 /下拉电阻配置成 上拉 /下拉输入模式 GPIOC.1对应 LED配置成强制推挽输出 不再 GPIOC->CRL&=0XFFFFFF0F; GPIOC->CRL|=0X00000030;// CNF1=00 ,MODE1=11合在一起是 3 KEY对应的引脚是 GPIOB.0 分成两种情况 1. 外接有上拉 /下拉电阻 外接有上拉 /下拉电阻配置成浮空输入 GPIOB->CRL&=0XFFFFFFF0; GPIOB->CRL|=0x00000004;//CNF0=01,MODE0=00 合在一起是 4 2. 外接没有上拉 /下拉电阻 KEY对应引脚配置成上拉 /下拉输入模式 GPIOB->CRL&=0XFFFFFFF0; GPIOB->CRL|=0X00000008;//CNF0=10,MODE0=00 合在一起是 8 到这里只是设置成了上拉 /下拉输入模式。
到底是上拉还是下拉要 还看其他的寄存器 从上图可以看出 设置上拉输入还是下拉输入需要 除了设置 CNF 和 MODE 还要设置 ODR这个寄存器 这个寄存器是用来给 IO 口输出数据的现在需要它来设置上拉下拉(我的理解是如果需要下拉就向对应的引脚写 0 让这个引脚默认是低电平,效果和在外部下拉电阻一样,想设置成上拉电阻就和向该位写 1就等于把该位的 电平默认设置为高电平 ) 所以要使用内部的上拉 /下拉输入模式需要 GPIOB->ODR&=0xFFFFFFFe;//GPIOB.0下拉 或者 GPIOB->ODR|=0X00000001;//GPIOB.0上拉 综合一下我的板子上 GPIOB.0连接的 key没有上拉电阻所以我使用内部上拉输入,引脚配置如下 GPIOB->CRL&=0XFFFFFFF0; GPIOB->CRL|=0X00000008;//上拉 /下拉输入模式 GPIOB->ODR|=0X00000001;//上拉模式 第三步 检测按键状态控制 LED亮灭 现在引脚已经配置好了,我们按下按键 STM32 可以检测到按键按下接下来就是需要读出按键的值来判断按键是按下还是抬起。
这里需要一个寄存器 这个寄存器就是保存 IO 口输入 数据寄存器 0~15 表示一组端口的 0~15 个引脚我们这里是 GPIOB.0所以判断 0号位的值就可以知道按键是否按下 If(GPIOB->IDR&0x0001==0)//把寄存器的值和 0x0001位与判断最后一位是否为 0是//的话会判断条件为真就执行 if里面的语句 GPIOC->BSRR|=0X00020000;//点亮 led else GPIOC->BSRR|=OX00000002;//灭掉 LED 以上就是 用按键控制 LED的学的过程 示例: LED ——GPI0C.1 key——GPIOB.0 #include “stm32f103x.h” Int main() { RCC->APB2ENR|=0X00000010; RCC->APB2ENR|=0X00000008; GPIOB->CRL&=0XFFFFFFF0; GPIOB->CRL|=0x00000004; GPIOB->ODR|=0x00000001; GPIOC->CRL&=0XFFFFFF0F; GPIOC->CRL|=0X00000030; while(1) { if(GPIOB->IDR&0X00000001==0) { GPIOC->BSRR=0x00020000; } else GPIOC->BSRR=0x00000002; }} 。
