使用指针进行直接寄存器访问

时间:2019-03-21 02:21:47

标签: c pointers nrf52

我正在尝试使用指针直接访问nrf52840 usb加密狗中的寄存器。我正在使用Segger Embedded Studio编译和链接所有内容,但似乎会生成不正确的RAM和闪存位置。编辑链接器文件并重新编译后,一切似乎都在正确的位置;但是,在编程(使用NRF Connect完成)之后,LED仍然不点亮。我的想法是我可能不正确地寻址寄存器。谁能告诉我我是否正确使用了指针?

注意:由于nrf52840 usb加密狗没有调试器,因此无法使用Segger Embedded Studio对nrf52840 usb加密狗进行编程。

LED_Test.c

// RGB LED at pins 22(G), 23(R), and 24(B)

// Addresses to registers, tasks, and events for the clock
#define CLOCK_BASE_ADDRESS     0x40000000
#define TASKS_HFCLKSTART_OFFSET     0x000
#define TASKS_LFCLKSTART_OFFSET     0x008
#define EVENTS_HFCLKSTARTED_OFFSET  0x100
#define EVENTS_LFCLKSTARTED_OFFSET  0x104
#define LFCLKSRC_ADDRESS_OFFSET     0x518

// Addresses to registers, tasks, and events for the GPIO
#define GPIO_BASE_ADDRESS      0x50000000
#define OUTSET_ADDRESS_OFFSET       0x508  //  1's written to this register set corresponding pins (HIGH). 0's have no effect.
#define DIRSET_ADDRESS_OFFSET       0x518  //  1's written to this register setup corresponding pins as OUTPUT. 0's have no effect.

volatile unsigned long * startHFClk_reg     = (volatile unsigned long *)CLOCK_BASE_ADDRESS  + TASKS_HFCLKSTART_OFFSET;
volatile unsigned long * HFClkStarted_reg   = (volatile unsigned long *)CLOCK_BASE_ADDRESS  + EVENTS_HFCLKSTARTED_OFFSET;
volatile unsigned long * LFClkSource_reg    = (volatile unsigned long *)CLOCK_BASE_ADDRESS  + LFCLKSRC_ADDRESS_OFFSET;
volatile unsigned long * startLFClk_reg     = (volatile unsigned long *)CLOCK_BASE_ADDRESS  + TASKS_LFCLKSTART_OFFSET;
volatile unsigned long * LFClkStarted_reg   = (volatile unsigned long *)CLOCK_BASE_ADDRESS  + EVENTS_LFCLKSTARTED_OFFSET;

volatile unsigned long * setupOutputs_reg   = (volatile unsigned long *)GPIO_BASE_ADDRESS   + DIRSET_ADDRESS_OFFSET;
volatile unsigned long * setPins_reg        = (volatile unsigned long *)GPIO_BASE_ADDRESS   + OUTSET_ADDRESS_OFFSET;

void main(void){

    *startHFClk_reg     = 0x01;         //  Start external 64 MHz crystal oscillator
    while(!HFClkStarted_reg){}
    *LFClkSource_reg    = 0x01;         //  LF oscillator source = external xtal
    *startLFClk_reg     = 0x01;         //  Start external 32.768 kHz crystal oscillator
    while(!LFClkStarted_reg){}

    *setupOutputs_reg   = 0x01C00000;   //  Make pins 22, 23, and 24 OUTPUT

    for(;;){
        *setPins_reg    = 0x00400000;   //  Make pin 22 HIGH
    }
}

1 个答案:

答案 0 :(得分:1)

您的寄存器的偏移量似乎是您的基址的字节偏移量。

然后您创建指针,如下所示:

isSoundOn.toggle()

您从volatile unsigned long * startHFClk_reg = (volatile unsigned long *)CLOCK_BASE_ADDRESS + TASKS_HFCLKSTART_OFFSET; 创建一个volatile unsigned long *,然后添加偏移量。这里应用了指针算术规则。 您将CLOCK_BASE_ADDRESS添加到基本地址。

为避免这种情况,请尝试

TASKS_HFCLKSTART_OFFSET * sizeof(unsigned long)