使用数组和指针算法闪烁LED

问题描述 投票:1回答:1
#include "lm4f120h5qr.h"
#define LED_RED (1u<<1)
#define LED_BLUE (1u<<2)
#define LED_GREEN (1u<<3)

    GPIO_PORTF_DATA_R  |= LED_RED; // line1

    *((unsigned long volatile *)(0x40025000 +(LED_RED << 2)))=LED_RED;//line2
    *(GPIO_PORTF_DATA_BITS_R + LED_RED)=LED_RED; //line3
    GPIO_PORTF_DATA_BITS_R[LED_RED]=LED_RED;  //line3

我正在关注互联网课程,这是使用“数组和指针算术”的一个例子。但我无法理解使用“指针算法”来修改特定位的概念。

我可以理解“line1”,它修改了一个位,而没有改变GPIO_PORTF_DATA_R指向的位置中的任何其他位,因此它打开了RED LED(如果我在这里弄错了,请纠正我)。

我可以理解为什么我们在“line2”中移位2位,因为我们忽略了2个最后的位,并且“line2”和“line3”共享相同的概念,他们在Disassembly中执行相同的指令。

我的第一个问题是*(GPIO_PORTF_DATA_BITS_R + LED_RED)究竟指向哪里?以及*(GPIO_PORTF_DATA_BITS_R + LED_RED)= LED_RED如何工作?

第二个问题是为什么我们不再需要在“line3”中移位2位。他们说它是自动完成的,但有人可以解释背后的原因吗?

谢谢。

c pointers arm pointer-arithmetic
1个回答
1
投票

我不确定上下文是什么,但我可以回答你的两个问题:

  1. 如果GPIO_PORTF_DATA_BITS_R是一个数组,*(GPIO_PORTF_DATA_BITS_R + LED_RED)=LED_RED将无符号int值LED_RED赋值给数组中的LED_REDth位置。再次不确定为什么要将LED_RED分配给数组中的那个位置,但这取决于你。
  2. 将值向左移2位将其乘以4.您需要在第2行中执行此操作,因为GPIO_PORTF_DATA_BITS_R是一个4字节值的数组(我用Google搜索并看到它是32位)。内存是字节寻址的,因此如果要转到数组中的LED_REDth位置,可以将LED_RED * 4添加到数组起始处的内存地址中。但是,C中的指针算法知道*GPIO_PORTF_DATA_BITS_R的大小,因此自动在第3行中进行4次乘法运算。

编辑:不是将LED_RED 2个字节向左移动,更简洁的计算内存地址偏移的方法是LED_RED * sizeof(*GPIO_PORTF_DATA_BITS_R)(或者如果你只是设置一个数组值那么就做你在第3行做的事情)。

© www.soinside.com 2019 - 2024. All rights reserved.