一 嵌入式系统C语言中对地址的访问方式
嵌入式系统中对一个具体内存地址的访问,通常需要使用指针(指针变量)的方式进行
二 指针的定义
int *p;
以上语句是c语言中定义一个指针(指针变量)的方式。
通常指针变量是用来存放地址的一种变量,对其赋值也必须是地址。
例如以下赋值方式,
①将变量地址赋值给指针变量
int a;
p=&a;//将变量a的地址赋值给指针
int a[10];
p=a;//将数组a的地址赋值给指针,数组名可以代表地址,或者p=&a[0];
struct student
{
int a;
char b;
} student;
p= &student; //将结构体变量的地址赋值给指针,结构体的名字不能作为地址,需使用&符号
② 将地址赋值给指针变量
p = 0x40002000;
在C/C++语言中,int* p = 0x40002000;
这种直接给指针赋绝对地址值的写法是合法的语法,
等同于 int* p = (int*)0x40002000;
这种写法通常出现在嵌入式开发中,用于访问特定的硬件寄存器或内存映射区域。
但是通常建议使用类型转换明确意图。
对指针变量强制类型转换必须使用指针, 换句话说就是如果你强制类型转换的对象是一个地址,那么必须使用的方式,**因为指针是存放地址的唯一类型。**例如指针(int *),int代表类型,也可以是一个结构体类型(student *);
typedef struct
{
int a;
char b;
} student;
student* p =
(student *)0x40002000;
至于为什么使用类型转换明确意图,
可以明确内存的解释方式,例如
- 同一内存地址存储的二进制数据,根据指针类型不同会被解释为不同的数据类型(如
int
、float
、结构体等)。 - 例如:地址
0x1000
处的4字节数据,用int*
解释为整数,用float*
解释为浮点数,二者值可能完全不同
定义指针运算的步长
- 指针运算(如
p+1
)的偏移量由指针类型决定。 int* p
执行p+1
时,地址实际增加sizeof(int)
(通常4字节);
char* q
执行q+1
时,地址仅增加1字
如果不使用类型转换,自增的步长会默认为指针变量的类型大小,因为定义指针的时候肯定要定义类型。
③
STM32中对寄存器赋值的常用方式
数值仅仅是举例说明指针的用途,不代表实际效果
typedef struct
{
uint32_t ODD;
uint32_t ORD
} GPIO_typedef;
#define GPIOBASE 0X04000000;
#define GPIOA (GPIO_typedef*)
GPIOBASE;
GPIOA-> ODD= 0X010B;