当前位置: 首页 > news >正文

STM32学习【5】用按键控制LED亮灭(寄存器)以及对位运算的思考

目录

  • 1. 看原理图
  • 2 使能GPIOA+GPIOA时钟模块
      • 2.2 设置引脚GPIO输入
      • 2.3 读取引脚值
    • 3. 关于寄存器操作的思考


写在前面
注意,这篇文章虽然说是用按键控制led亮灭,重点不在代码,而是关键核心的描述。
用寄存器的方式,通过key来控制led的亮灭,在各种封装库存在且算力充沛的情况下,是否还有必要用这么底层的方式来写代码呢?
事实上,实际工作中是不需要的,但是学习中,是一定要的,只有这样我们才能理解真实的代码世界是什么样的。
那么真实的代码是什么样的?其实就是一个个拨码开关,不断的开,关,通,断,如果我们肉眼能看到代码运行的世界,我相信那里一定色彩斑斓!


1. 看原理图

  • 我们使用KEY1来控制红色LED:按下KEY1则灯亮,松开后灯灭

  • KEY1用的是PA0引脚

2 使能GPIOA+GPIOA时钟模块

RCC_APB2ENR地址:0x40021000 + 0x18


很明显,要想使能GPIOA,就要把第3和4设置成1,

对应下面的代码:

unsigned int *pReg;
unsigned int *pRegA;
unsigned int *pRegB;

/*使能GPIOB, GPIOA */
pReg = (unsigned int *)(0x40021000 + 0x18);//找到对应的寄存器位置
*pReg |= (1<<3) | (1<<2);
//这里的计算分为两步,(1<<3) | (1<<2)计算,使其第三位和第四位都是1的32位数据,然后通过*pReg |,把1并入到第三位第四位寄存器中。

2.2 设置引脚GPIO输入

GPIOA_CRL地址:0x40010800 + 0x00

/* 设置GPIOB为输出引脚 */
pRegB = (unsigned int *)(0x40010C00 + 0x00);
*pRegB |= (1<<0);

/*设置GPIOA0Î输入引脚*/
pRegA = (unsigned int *)(0x40010800 + 0x00);
*pRegA &= ~(3);     /* mode0 = 0b00 */
*pRegA &= ~(3<<2);  /* cnf0 = 0b00 */
*pRegA |= (1<<2);   /* cnf0 = 0b01 */

2.3 读取引脚值

GPIOA_IDR 地址:0x40010800 + 0x08

/* GPIOB output data register */
pRegB = (unsigned int *)(0x40010C00 + 0x0C);

/* GPIOA input data register */
pRegA = (unsigned int *)(0x40010800 + 0x08);

	/* 读取GPIOA input data register */
		
*pRegA & (1<<0)) == 0 /* KEY1被按下*/	
*pRegB &= ~(1<<0);//设置GPIOB输出0
*pRegB |= (1<<0);//设置GPIOB输出1

3. 关于寄存器操作的思考

*pRegA & (1<<0)) == 0 /* KEY1被按下*/	
*pRegB &= ~(1<<0);//设置GPIOB输出0
*pRegB |= (1<<0);//设置GPIOB输出1

逻辑与和逻辑或,其实有点哲学意义上的对立和统一。

逻辑或:非常简单的逻辑。只要双方有一个是1,那么或运算必然是1。
1.逻辑或,1和1之间的相互成就。在逻辑或的世界里,1拥有绝对的power,不论遇见什么都会同化为1。 可以说,人难得糊涂,事业才能越做越大。
逻辑与:只要双方有一个是0,那么结果必然是0,逻辑与就像对0有洁癖的家伙,
2.逻辑与,0和0之间的相互擦除,在逻辑与的世界里,0拥有绝对的power,不论遇见什么都会同化0。 可以说,底层人的相互拉踩,才是真正的阶层固化。

总结起来,我们要是想把1作为抓手,就用或,像用0作为抓手,就用与。
比如:
我们需要让寄存器某些位置1的时候用,我们就用或,不论什么位,碰见1就变1。
我们要把某些位清零的时候用,我们就用与。不论什么位,碰见0就变0.
那么我们把上面的案例拿过来看看。
*检测pRegA & (1<<0)) == 0 // KEY1被按下
我们要检测某些位是不是1,那么就要把其他的位用0干掉,一定是用,那么必然我们要把其他位干掉,要用与。

*pRegB &= ~(1<<0);设置GPIOB输出0:我们要设置对应的位为0,首先确定最终必然要用与。
*pRegB |= (1<<0);//设置GPIOB输出1:我们要设置对应的位为0,首先确定最终必然要用或。

相关文章:

  • LeetCode 2614.对角线上的质数:遍历(质数判断)
  • ★ Linux ★ 进程(上)
  • 深度解析manus:技术原理剖析、开源平替方案架构分析
  • kali破解Pdf/execl/word
  • 汽车一键启动PKE无钥匙系统
  • 使用C++写一个递推计算均方差和标准差的用例
  • 使用pyinstaller打包py文件
  • SQL注入第6关
  • 如何用日事清做研发目标、需求、规划、迭代、Bug、效能、复盘、绩效一站式管理
  • 3月18号
  • 7种数据结构
  • ubuntu安装NVIDIA显卡驱动及CUDA环境
  • 【MySQL】关闭外键约束检查
  • python-leetcode 47.组合总和
  • Redis 面试思路
  • 深度学习-148-langchain之如何使用with_structured_output()从模型中返回结构化数据
  • 机试准备第19天
  • 4.angular 服务
  • 5.3《凸透镜成像的规律》——先于5.2《生活中的透镜》讲
  • Windows 部署 RuoYi 前后端分离项目
  • 《探秘海昏侯国》数字沉浸特展亮相首届江西文化旅游产业博览交易会
  • 荣盛发展股东所持1.17亿股将被司法拍卖,起拍价约1.788亿元
  • 山西太原一居民小区发生爆炸,应急管理部派工作组赴现场
  • 自称“最美”通缉犯出狱当主播?央广网:三观怎能跟着“五官”跑
  • 工信部:加快自动驾驶系统安全要求强制性国家标准研制
  • 第1现场|无军用物资!伊朗港口爆炸已遇难40人伤1200人