Presentation is loading. Please wait.

Presentation is loading. Please wait.

ARM Embedded Programming Lecture 4 Accessing Memory Mapped Registers.

Similar presentations


Presentation on theme: "ARM Embedded Programming Lecture 4 Accessing Memory Mapped Registers."— Presentation transcript:

1 ARM Embedded Programming Lecture 4 Accessing Memory Mapped Registers

2 Microcontroller Programming Paradigm 1.Decide what peripheral you want to use 2.Look in datasheet for the registers to enable and configure 3.Set bits in the registers to make peripheral behave the way you want 4. GOTO 1

3 Configuring PeripheralRegisters Writing and Reading Memory Mapped registers: in assembly it is easy e.g. LDR R1, =0x400001400 ; R1 <= memory address MOV R0, [ R1] ; value now loaded into R0 but in standard C ???

4 Task: How to Set the bit #23 in Peripheral Register at address 0x40000004 ? Would like to write something like const unsigned int MASK = 0x00800000; // 0b0000-0000-1000-0000-0000-0000-0000-0000 my_reg = my_reg | MASK; // Bitwise OR operation will set the required bit How to modify Memory Mapped Registers ?

5 Manipulating Memory Mapped Registers via Pointers 1.Define a pointer to the register address unsigned int * reg_addr = (*unsigned int) 0x40000004; 2. Set the MASK constant (1u << 23) // left shifting the constant 0x01 by 23 bits 3. OR the MASK with the current register value *reg_addr = (* reg_addr) | (1u << 23) ; // change stored value using // the indirection operator *

6 Using Macro #define to make code readable Use a text replacement macro #define. #define BIT23 (1u<<23) // replaces any occurrence of string BIT23 by string (1u<<23) // Hide the de-reference operator * and save yourself some typing: #define my_reg (*reg_addr); // expand the text “my_reg” to the text “(*reg_addr)”; my_reg = my_reg | BIT23; // set bit #23 can be also expressed in shorter form: my_reg | = BIT23; When using a mask in C we perform a read and modify operation

7 typedef keyword To make the code less error prone use the typedef keyword. It introduces a user defined type that is checked by the compiler: typedef unsigned int* reg_address_t ; /* User defined type pointer */ reg_address_t reg_addr = (reg_addr_t) 0x40000004; /* points at the memory address */ /* Text substitution macros save typing and make code readable */ #define my_reg (*reg_addr); /* this looks like a “variable” holding register value */ #define BIT_23 (1u <<23); /* constant representing the MASK */ /* The manipulation of register data is now easy to express */ my_reg ++; my_reg |= BIT_23;...

8 Storing values in MEMORY. The volatile qualifier indicates that the variable could be changed by external circumstances, such as user’s input switch. It instructs the compiler to store and update variable values in memory rather than from temporary storage (e.g. a CPU register). int volatile x = 0x67 ; // defines variable x that is stored in SRAM x = x + 0x03; // the result 0x6A will always be stored and updated in SRAM The inclusion of the volatile qualifier guards against the compiler performing code optimisation and storing the variable in an internal CPU register !!

9 Accessing Group of Memory Mapped Registers It is common for related Peripheral Registers have adjacent addresses. We can use the STRUCTURE data type to describe this group.

10 Example of a Port Pin Toggle typedef struct { unsigned int volatile MODER; // GPIO Mode Register unsigned int volatile OTYPER; // GPIO Output Type Register unsigned int volatile OSPEEDR; // GPIO Output Speed Register unsigned int volatile PUPDR; // GPIO Pull-up/Pull-down Register unsigned int volatile IDR; // GPIO Input Data Register unsigned int volatile ODR; // GPIO Output Data Register } GPIO_type; // Define a typical GPIO register group #define GPIOD_BASE (unsigned int) 0x40001400 // Value of Base Address of PORT D #define GPIOD (( GPIO_type*) GPIOD_BASE) // Pointer to Base Address of PORT D // Using the pointer GPIOD to the structure GPIO_type we can access its elements (registers) GPIOD->MODER = (1u << 26); // Set bit #26 (pin 13) to be general purpose output while (1) { my_delay (40 ms); // User written function returns after a delay of 40 ms GPIOD->ODR ^ = (1u << 13)); // Toggle output bit #13 using bit-wise XOR };


Download ppt "ARM Embedded Programming Lecture 4 Accessing Memory Mapped Registers."

Similar presentations


Ads by Google