经过深入学习BSRR、BRR、ODR寄存器的区别、特性,发现,BSRR与ODR的速度是一样的。所不同的是:BSRR和BRR适用于中断函数对端口的操作,而如果直接对ODR可能会引起竞争。我们可以直接对ODR进行操作,也可以通过BSRR或者BRR来进行操作。这只是两种方式,并且后者会更安全些。 BSRR的优点在于,可以一次性对不同的位进行“位”置位和复位(也即两个不同引脚的置位复位可以并行操作)。而BRR用来专门的进行“位”复位,它的作用和BSRR的高16位是相同的。但是,有了BRR这个16位的“复位器”,我们就可以快速的进行一个IO口(16根引脚)的“复位”,而不用进行移位(因为如果要使用BSRR的“位”复位功能,那么要对这个16位的操作数移位至BSRR的高16位)。综合起来,我们应这样理解BSRR(一个32位的寄存器)与BRR(一个16位的寄存器):起初,我们为了方便对GPIO的16根引脚进行位操作,所以设计了“BSR” 和BRR这两个16位的寄存器,用来分别进行置位和复位操作,后来,为了能使不同引脚的置位/复位操作能并行执行,所以让“BSR (Bit Set Register )”寄存器设计成一个32位的寄存器(命名为BSRR,Bit Set and Reset Register),其中它的高16位用来进行“位”复位,所以最后GPIO 一共有了 BSRR 和 BRR 这两个特殊的寄存器。(注意,BSRR和BRR都是“只写型”的寄存器,也就是说,它们每次设置的时候只起一次作用。) 之所以之前采用了看起来一样的GPIO置位复位命令,却得到2.5M的输出频率,很可能是我们的编译器编译的结果,使得我们在进行“置位/复位”时,隐含的调用了一下寄存器操作指令(后来我们就是直接用的这个寄存器操作指令,所以得到12M输出),所以多耗去几个系统时钟。另外,我在调试过程中,将 GPIOE->BSRR=0x00002000; GPIOE->BSRR=0x20000000; 这两个代码换一下顺序,就导致输出的频率不一样,一个为10.28M一个为12M。具体原因不详。可能是编译器的原因。但是,“有输出”,就意味着,BSRR寄存器中如果对同一根引脚置1和置0,那么它只会置1,但是,如果分两次对同一位进行置1或置0,则会有高、低两个电平的输出变化。所以,从这可以推测,BSRR寄存器是非记忆型的(一次性使用)。 当然,这些也只是以我目前所掌握的知识量来做的推测,也许以后的应用中有了更深刻的认识,会发现其中真正的问题。综合起来看,吴文庆师兄的24M已经是STM32F207的上限频率了,但是,如果使用一个技巧(就是不断写100行置0置1代码),也许能看到36M的输出(但本质上是没有变的)。
|