Использование указателей для прямого доступа к реестру - PullRequest
1 голос
/ 21 марта 2019

Я пытаюсь использовать указатели для прямого доступа к регистрам в USB-ключе nrf52840.Я использую Segger Embedded Studio для компиляции и компоновки всего, но кажется, что он генерирует неправильные места в RAM и Flash.После редактирования файла компоновщика и перекомпиляции все кажется в нужном месте;однако после программирования (выполненного с помощью NRF Connect) светодиод по-прежнему не горит.Я думаю, что я могу неправильно обращаться к регистрам.Может кто-нибудь сказать мне, правильно ли я использую указатели?

Примечание: Программирование USB-ключа nrf52840 не может быть выполнено с помощью Segger Embedded Studio, поскольку USB-ключ nrf52840 не имеет отладчика.

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 Ответ

1 голос
/ 21 марта 2019

Смещения ваших регистров кажутся смещениями в байтах от вашего базового адреса.

Затем вы создаете свои указатели так:

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) к базовому адресу.

Чтобы избежать этого, попробуйте

volatile unsigned long * startHFClk_reg     = (volatile unsigned long *)(CLOCK_BASE_ADDRESS  + TASKS_HFCLKSTART_OFFSET);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...