以下三行代码是使用1 MOV指令修改位的优化方法,而不是使用较少中断安全的读-修改-写成语。它们是相同的,并在GPIO的数据寄存器中设置LED_RED位:
*((volatile unsigned long*)(0x40025000 + (LED_RED << 2))) = LED_RED;*(GPIO_PORTF_DATA_BITS_R + LED_RED) = LED_RED;GPIO_PORTF_DATA_BITS_R[LED_RED] = LED_RED;LED_RED就是(volatile unsigned long) 0x02。在这个微控制器的内存映射中,这个寄存器(和其他寄存器)的前两个LSB是未使用的,所以第一个例子中的左移位是有意义的。
GPIO_PORTF_DATA_BITS_R的定义是:
#define GPIO_PORTF_DATA_BITS_R ((volatile unsigned long *)0x40025000)
我的问题是:,为什么在使用指针算法或数组索引(分别是第二种方法和第三种方法)时,我不需要左移两次?我很难理解。提前谢谢你。
发布于 2021-08-15 01:36:13
记住C指针算法是如何工作的:向指针添加偏移量是以所指向的类型的单位来操作的。由于GPIO_PORTF_DATA_BITS_R具有unisgned long *和sizeof(unsigned long) == 4类型,因此GPIO_PORTF_DATA_BITS_R + LED_RED有效地添加了2 * 4 =8字节。
注意,(1)在0x40025000上做算术,它是一个整数,而不是指针,因此我们需要添加8才能得到相同的结果。左移2等于乘4,所以LED_RED << 2再次等于8。
(3)根据[]算子的定义,与(2)完全等价。
https://stackoverflow.com/questions/68788097
复制相似问题