• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

[stm32_STD_lib Learning]用keil初始化GPIO引脚后观察寄存器


Recommended Posts

通过keil在线调试,观察GPIO_STD_lib中初始化后GPIO寄存器的状态

如图,首先你需要在调试设置处取消勾选下载到flash。如果不取消亲测,在调试过程中无法中断的情况下,只能从汇编的角度观察程序运行。

dagu1wvh4l13324.png

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

3jiabxczt5q3325.png

板级外设初始化功能的断点。

tm1of45pppx3326.png

因为当我按下键1时,灯反而熄灭了,这不符合预期;

在线调试期间,执行初始化LED_Blue_Init()后,检查LED引脚的输出和实际灯的开关:

如图,此时GPIOB_Pin_1引脚输出为0,但灯亮。

重新查看原理图,发现GPIOB_Pin_1的引脚与LED的共阴极联动,即输出会低电平点亮,需要改变bsp中的点亮功能来调用ReSet功能(原来设置的)。

2f3yzxfqo2e3327.png

至此,key1和key2功能混淆的原因已经找到了;(以后写代码的时候,首先要注意仔细看原理图,不然就是在写bug。)

接下来检查重点检测功能,因为之前的现象不符合预期,问题很多。我们指的是在野火的关键检测中阻塞的编写。

现在试着清除堵塞,看看有什么效果:

代码如下:(忘记用markdown了,我来看看)

uint8_t KEY1_Detect(void)

{

If((GPIO _ KEY1-IDR)GPIO _ key 1 _ PIN)//如果在从输入寄存器IDR读取的状态中检测到key 1引脚状态

{

/*

这句话是野火的关键阻挡功能。

while((GPIO _ key 1-IDR)GPIO _ key 1 _ Pin);

发现这里不需要堵塞,只是现象不一样。

如果没有被遮挡,按键时LED功能会瞬间运行,即按键时灯会立刻打开。

如果被遮挡,LED功能只有在松开按键时才会运行,也就是在灯打开之前松开按键。

*/

返回1;//如果pin被按下,它将返回true

}else//如果未按下,pin返回到flase

{

返回0;

}

}

在这一点上,按钮阻塞现象的区别也就明白了;

还有一个问题。浮动输入和上拉下拉的实际效果如何?

因为在之前写标准库的过程中,我了解到如果是在下拉模式下,标准库会手动设置设置复位寄存器BSRR和BRR。

我想看看浮动、上拉和下拉后从寄存器中读取的值有什么区别。

浮动空间我不知道,但预计上下两级应该分别是高和低。首先,在引脚初始化之前,查看输入寄存器的值:

h23wbvzoa0g3328.png

3795-20220501093419271-1537765169.png" width="555"/>

 

 

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

Floating浮空

ksdwyztpg5t3329.png

 

2nmrpufzr4k3330.png

 

 

 

 

IPD下拉

v20ixj1gt203331.png

2coab5vecbt3332.png

IPU上拉

 z4o5312xhhi3333.png

 

 

 vqebonyl1bs3334.png

 

 

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

1tq2ljv2w5m3335.png

 

yuiv1l2lzs33336.png

 

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

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

 

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

1ns5aeitdls3337.png

 

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

vdk32s25trh3338.png

 

运行观察

gmlnu3upqpg3339.png

 

 

 44u5gw2qhpj3340.png

 

dnnkjk5romk3341.png

 

 

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

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

 

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

kuw0jm5njt43342.png

 

bq5zjuyz3fc3343.png

 

 

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

fw4bpey1gld3344.png

 

 

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

2vy3dfbj1yt3345.png

 

kadb3qplupc3346.png

 

 

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

mjyu22bhj0a3347.png

 

 

 

q5vmwcgxtnp3348.png

 

 

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

gtwyunnqbob3349.png

 

xdomuj5yvyt3350.png

 

 

 此时IDR会同步;

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

okuj1fnz1ig3351.png

 

 

cpxjlhnowyc3352.png

 

 

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

n1r3ofjy5ok3353.png

 

h0ha4j2t3ce3354.png

 

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

上拉:

 

bdmkvsqu0zb3355.png

 

c1tn0ysonrp3356.png

 

输出下:

3y1cketou233357.png

 

haaorq41smv3358.png

 

 结论已经出来了,和上拉还是浮空无关,在输入模式下,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的值会改变

 3wvi0bkyifg3359.png

 

 

 jpgmtn1fxtd3360.png

 

 

 r4aigvdjv313361.png

 

 

 另一个问题:(已解决)

貌似复位后无法进入main

yziqnl5dnbl3362.png

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

hdj2g3bvzfc3363.png

 

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

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now