使用指针直接访问寄存器
Using pointers for direct register access
我正在尝试使用指针直接访问 nrf52840 usb 加密狗中的寄存器。我正在使用 Segger Embedded Studio 编译和 link 所有内容,但它似乎生成了不正确的 RAM 和闪存位置。编辑 linker 文件并重新编译后,一切似乎都在正确的地方;然而,编程后(使用 NRF Connect 完成)LED 仍然不亮。我的想法是我可能错误地寻址了寄存器。谁能告诉我我是否正确使用指针?
注意:无法使用 Segger Embedded Studio 对 nrf52840 usb dongle 进行编程,因为 nrf52840 usb dongle 没有调试器。
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
}
}
您的寄存器的偏移量似乎是相对于您的基地址的字节偏移量。
然后你像这样创建你的指针:
volatile unsigned long * startHFClk_reg = (volatile unsigned long *)CLOCK_BASE_ADDRESS + TASKS_HFCLKSTART_OFFSET;
您从 CLOCK_BASE_ADDRESS
创建一个 volatile unsigned long *
,然后添加偏移量。这里应用了指针算法的规则。
您将 TASKS_HFCLKSTART_OFFSET * sizeof(unsigned long)
添加到基址。
要避免这种情况,请尝试
volatile unsigned long * startHFClk_reg = (volatile unsigned long *)(CLOCK_BASE_ADDRESS + TASKS_HFCLKSTART_OFFSET);
我正在尝试使用指针直接访问 nrf52840 usb 加密狗中的寄存器。我正在使用 Segger Embedded Studio 编译和 link 所有内容,但它似乎生成了不正确的 RAM 和闪存位置。编辑 linker 文件并重新编译后,一切似乎都在正确的地方;然而,编程后(使用 NRF Connect 完成)LED 仍然不亮。我的想法是我可能错误地寻址了寄存器。谁能告诉我我是否正确使用指针?
注意:无法使用 Segger Embedded Studio 对 nrf52840 usb dongle 进行编程,因为 nrf52840 usb dongle 没有调试器。
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
}
}
您的寄存器的偏移量似乎是相对于您的基地址的字节偏移量。
然后你像这样创建你的指针:
volatile unsigned long * startHFClk_reg = (volatile unsigned long *)CLOCK_BASE_ADDRESS + TASKS_HFCLKSTART_OFFSET;
您从 CLOCK_BASE_ADDRESS
创建一个 volatile unsigned long *
,然后添加偏移量。这里应用了指针算法的规则。
您将 TASKS_HFCLKSTART_OFFSET * sizeof(unsigned long)
添加到基址。
要避免这种情况,请尝试
volatile unsigned long * startHFClk_reg = (volatile unsigned long *)(CLOCK_BASE_ADDRESS + TASKS_HFCLKSTART_OFFSET);