[英]Is "(unsigned int *) 0x400253FCU" a pointer in the TI Stellaris Microcontroller header file <LM4F120H5QR.h>?
背景:
我正在学习嵌入式系统编程。 在这个过程中,我了解到“指针”是嵌入式系统中最重要的。 指针是在 C 中声明的变量,其值是另一个变量的地址。 我可以通过取消引用指针来操纵/更改这个其他变量的值。
例子:
int *pt; // Integer pointer variable declaration.
float *pf; // Float pointer variable declaration.
int *pt
表示pt
是一个指针变量,能够指向 int 类型的变量。 另一方面,指针变量fp
只能存储float类型变量的地址。
要将值(地址)分配给指针变量,必须使用地址运算符 ( &
)。
int var = 20; //Actual variable declaration
int *pt; //Pointer Variable Declaration
pt = &var; //Here with the ampersand (&)operator we denotes an
//address in memory to the pt pointer.
/*Changing the variable value from 20 to 79*/
*pt = 79; //Dereference
printf (“Value of *pt variable: %d\n”, *pt); //Output:79
printf (“Value of var variable: %d\n”, var); //Output:79
这两个链接对我理解指针很有帮助:
题
当我遇到 Stellaris LM4F120H5QR 微控制器的 header 文件时,我的问题出现了。 这个 header 文件定义了具有 memory 地址的寄存器位置,如下所示:
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
当我遇到这种语法时,我很困惑是否确实将“ (volatile unsigned long *)0x400253FC)
”定义为指针并且整个句子可以解释为如下图所示?
如果那不正确,有人可以解释解释嵌入式系统 header 文件的寄存器定义的正确方法吗?
header 文件的链接 -->这里
这是一个正确的反抗......如果你尝试它会工作得很好......让我帮助你理解这个声明它是如何工作的
例如,如果您在 memory 中有一个特定地址(此地址0x400253FC )并且您希望将 ( 50 ) 的值写入第一个字节,则以下代码将是错误的
// the following code is wrong
0x400253FC = 50 ;
上面的代码会给出一个编译错误.. 那么如何告诉编译器将这个 ( 0x400253FC ) 作为一个 memory 地址??,只需在转换的帮助下做到这一点
(unsinged char *)0x400253FC // cast this number 0x400253FC as char pointer
现在你有了一个指针,所以你可以取消引用它并将值写入 memory(指针指向的位置),如下所示
*((unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
一些编译器在进行优化时会删除这行代码,以防止编译器这样做,我们添加了volatile 说明符...所以表达式将像这样
*((volatile unsinged char *)0x400253FC) = 50; // write the value 50 in address 0x400253FC
所以这就是如何访问 memory 中的一个字节
如果你想访问 memory 中的 4 个字节,那么它将是这样的
//assuming your compiler consider the long variable as 4 byte
*((volatile unsinged long*)0x400253FC) = 50; // write the value 50 in 4 byte in memory start with address 0x400253FC
(*((volatile unsigned long *)0x400253FC)) = 0x12345678
初等C,解析出来就好了。 我认为您不确定混淆在哪里。
我想你了解类型转换
unsigned int x; //a variable
x = 0x400253FC; //assign the variable a value
(volatile unsigned long *)x //typecast x into a different type volatile unsigned long *
同样使用指针
volatile unsigned long *z;
(*z)=0x12345678; //at the address pointed to by z place the value 0x12345678;
把它分成几部分。
(
*
(
(volatile unsigned long *)0x400253FC
)
)
0x400253FC a value
(volatile unsigned long *)0x400253FC typecast that value into an unsigned long pointer
((volatile unsigned long *)0x400253FC) enclose that pointer as a whole at this point it is a pointer, like z from above.
*((volatile unsigned long *)0x400253FC) dereference it one level, like *z above you can now use this to manipulate the unsigned long address.
(*((volatile unsigned long *)0x400253FC)) good idea to wrap defines in parens to not confuse the compiler. doesn't hurt.
(*((volatile unsigned long *)0x400253FC)) = 0x12345678. Like *z = 0x12345678 above, write/store 0x12345678 to the address 0x400253FC
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
GPIO_PORTF_DATA_R = 0x12345678; store/write 0x12345678 to the address 0x400253FC
unsigned long k; k = GPIO_PORTF_DATA_R; load/read from address 0x400253FC and save it in k
如果你有一个 8 位宽的寄存器,那么就这样调整类型转换。
#define SOME_8BIT_REG (*((volatile unsigned char *)0x5006789A))
SOME_8BIT_REG = 0x33;
你可以试试
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
#define SOME_8BIT_REG (*((volatile unsigned char *)0x5006789A))
void fun ( void )
{
GPIO_PORTF_DATA_R = 0x12345678;
SOME_8BIT_REG = 0x33;
}
00000000 <fun>:
0: e3a02033 mov r2, #51 ; 0x33
4: e59f1010 ldr r1, [pc, #16] ; 1c <fun+0x1c>
8: e59f0010 ldr r0, [pc, #16] ; 20 <fun+0x20>
c: e59f3010 ldr r3, [pc, #16] ; 24 <fun+0x24>
10: e58103fc str r0, [r1, #1020] ; 0x3fc
14: e5c3209a strb r2, [r3, #154] ; 0x9a
18: e12fff1e bx lr
1c: 40025000
20: 12345678
24: 50067800
10: e58103fc str r0, [r1, #1020] ; 0x3fc
32 bit store (write) 0x12345678 to address 0x400253fc
14: e5c3209a strb r2, [r3, #154] ; 0x9a
8 bit store (write) 0x33 to address 0x5006789a
指令集无关紧要
0000000000000000 <fun>:
0: 48 c7 04 25 fc 53 02 movq $0x12345678,0x400253fc
7: 40 78 56 34 12
c: c6 04 25 9a 78 06 50 movb $0x33,0x5006789a
13: 33
14: c3 retq
Disassembly of section .text:
00000000 <fun>:
0: 123457b7 lui x15,0x12345
4: 40025737 lui x14,0x40025
8: 67878793 addi x15,x15,1656 # 12345678 <fun+0x12345678>
c: 3ef72e23 sw x15,1020(x14) # 400253fc <fun+0x400253fc>
10: 500687b7 lui x15,0x50068
14: 03300713 li x14,51
18: 88e78d23 sb x14,-1894(x15) # 5006789a <fun+0x5006789a>
1c: 8082 ret
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.