ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【stm32_STD_lib学习】用keil观察GPIO引脚初始化后的寄存器

2022-05-01 13:33:42  阅读:337  来源: 互联网

标签:STD lib 引脚 ODR IDR BSRR 浮空 按键


通过keil在线调试观察GPIO_STD_lib中Init后的GPIO寄存器状态

如图,首先需要在Debug设置处取消下载到flash的勾选,亲测如果不取消的话,调试时无法打断点也只能在汇编角度观察程序运行

 

 

如图,调出外设观察窗口:

 

为板级外设的初始化函数打断点

 

因为我key1键按下时,灯反而灭了,不符合预期;

通过在线调试过程中,检查初始化LED_Blue_Init()执行后,LED引脚的输出和实际灯的亮灭:

,如图,此时引脚GPIOB_Pin_1的引脚输出为0,但是灯却是亮的,

重新检查原理图后,发现GPIOB_Pin_1的引脚是与LED共阴极链接的,即输出低电平才会亮,得把bsp里的灯亮函数改为调用Reset函数(原来是Set)

 

 至此,key1和key2功能混乱的原因找到了;(以后写代码时得先注意把原理图看仔细些,不然就是在写bug)

接下来检查一下按键检测函数,因为前期现象不符合预期,有许多疑问,参考了野火的按键检测中阻塞的写法;

现在尝试把阻塞去掉看看有什么影响:

代码如下:(忘记用markdown了,将就看吧)

uint8_t KEY1_Detect(void)
{
  if ((GPIO_KEY1->IDR) & GPIO_KEY1_Pin)  //如果从输入寄存器IDR中读出的状态中,检测到KEY1引脚状态
  {
    /*

    这句是野火的按键阻塞函数

    while((GPIO_KEY1->IDR) & GPIO_KEY1_Pin);

    实测发现不需要阻塞在这里也行,只是现象不同,

    不阻塞的话,LED函数会在按键按下瞬间运行,即按下按键立刻开灯

    阻塞的话会在按键松开时才运行LED函数,即松开按键才开灯

    */

    return 1;              //引脚是按下的话就返回true


  }else                  //引脚未按下的话就返回flase
  {
    return 0;
  }
}

至此,按键阻塞的现象差异也明白了;

还剩下一个问题,浮空输入和上拉下拉的实际效果怎么样?

因为在之前的自己写标准库过程中,了解了如果是上下拉模式,标准库会手动去设置置位复位寄存器BSRR、BRR

 想看看实际上,浮空、上拉、下拉后,从寄存器中读出来的值有什么不同,

浮空不知道,但上下拉预期应该分别是高、低电平,先看引脚初始化前输入寄存器的值:

 

 

 

 如图A、C引脚都是0x0;

Floating浮空

 

 

 

 

 

IPD下拉

IPU上拉

 

 

 

 

 

 

 重新在上拉模式下打断点检查:

 

 

观察到函数确实操作了BSRR寄存器,输出寄存器ODR也改变了,但是输入寄存器IDR的值并没有改变,

原因我也不清楚,但这说明了一个现象,设置BSRR后,改变并不会同步到IDR上,只会同步到ODR上

 

 来看看KEY1_Detect按键检测的实现函数:

 

我这里是通过IDR检查的,尝试把对应led_off的Key2检测函数改成ODR检查

 

运行观察

 

 

 

 

 

 

 至此,现象说明的第一个直接问题是,用IDR和ODR做输入状态的检测条件,效果是不同的,

和前面提到的一样,上拉模式设置BSRR寄存器后,改变并不会同步到输入寄存器IDR上,只会同步到输出寄存器ODR上

 

检查在输出模式下的Led引脚是否也是这样:

 

 

 

 如图,把我的IDR该位清零了,再接着测试写BSRR

 

 

 再把上拉、下拉输入的key引脚设置CRL、BSRR过程中,IDR和ODR的变化记录下来:

 

 

 

 我这时才发现,其实我是在看浮空输入下(CRL复位为0x4代表浮空输入),改变BSRR,IDR和ODR会有什么变化

 

 

 

 

 

 上拉模式下,设置BSRR前后寄存器变化:

 

 

 

 此时IDR会同步;

再重新初始化引脚为浮空,查看更改BSRR的现象

 

 

 

 

 太乱了,我决定把std库抛开,直接设置CRL寄存器后,观察BSRR的改变对IDR和ODR的影响

 

 

在浮空、输入模式下,设置BSRR,ODR改变了,IDR没改变

上拉:

 

 

 

输出下:

 

 

 结论已经出来了,和上拉还是浮空无关,在输入模式下,IDR不会同步BSRR的变化,只有输出模式下,IDR才会同步BSRR的变化;

而ODR不管在任何情况下都会同步BSRR的变化。

回到本设计的过程,我想实现,key1按键被按下后,led点亮;key2按键被按下后,led熄灭;

1.在原理图方面要搞清楚引脚和led、按键的接法,和逻辑上的高低是否相同;

这里led共阴,得输出低电平才亮;按键的逻辑和思维习惯一样,按下为高电平;

那么在led_bsp中,调用std库时得调和电路符合的那个,ON调Reset,OFF调Set;

按键检测中检测高电平为按下,没问题。

2.在按键引脚设置为输入的前提下,设置BSRR的值是不会被反映到IDR的;

如果要获得BSRR改变的信号,得去读ODR;

复位时是浮空输入,在std库初始化的过程中,分别对上拉下拉设置了BSRR,

但在我前面测试的过程中,在std库对引脚初始化后,通过IDR输入数据寄存器去读,就读不到上下拉的变化;

只有把IDR改为ODR,才能读到BSRR的改变,用到这个上下拉造成的效果;

3.又通过测试发现,上拉的引脚在程序里一直读到1,下拉的引脚在程序里一直读到0,不管外部的按键如何变化;

4.所以设置为浮空输入才是按键的正确使用方法,并且又发现,在浮空输入下,通过ODR根本读不到外部按键的变化;

所以说之前的用法果然是错的,正确用法的思路应该是:

设置为输入模式下,IDR接收外部环境的变化,不根据内部输出改变;

设置位输出模式下,ODR接收内部控制的信号,不根据外部信号改变。

输入模式与IDR,输出模式与ODR,这两组概念是绑定使用的,对GPIO的疑问解决了。

 

过程发现的另一个现象:(或许用不上,以后再看)

GPIO时钟使能时,IDR的值会改变

 

 

 

 

 

 

 

 

 

 另一个问题:(已解决)

貌似复位后无法进入main

按住复位键后全速运行提示不支持那么多断点,哈哈,减掉一点

 

断点删除后,得重新编译烧写,后面就能正常调试了。

 

标签:STD,lib,引脚,ODR,IDR,BSRR,浮空,按键
来源: https://www.cnblogs.com/xianyucaicaizi/p/16212643.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有