一、指针的原理
在Soc芯片内部,长这样

RAM:起暂存的作用。
Flash:像读 RAM 一样读 Flash,但是不能像写 RAM 一样写 Flash(要先擦除才能
执行特定的操作去烧写)。
如下代码示例
01 int a;
02 int *p;
03 p = &a;
04 *p = 1; // 相当于 a = 1
其中,a、p 都是“变量”,可以读可以写,执行第 1、2 行代码时,会在 RAM 里分配 2 个区域存放变量 a、p,如图

执行第 3 行代码时,p 变量所在的内存,里面的值等于 addr1,如图所示:

执行第 4 行代码时,使用 p 的值(addr1)作为地址来写内存,写入数值 1,就是让地
址为 addr1 的内存,即变量 a 的值等于 1。如下图所示:
二、指针变量的大小
首先说明,1字节(byte)=8字(bit)
char c; // 大小为1字节
short b; // 大小为2字节
int a; // 大小为4字节
long i; // 对于32位处理,大小为4字节;对于64位处理器,大小为8字节
char *p1; // 指针用来保存地址,无论是何种指针,对于32位处理器,指针变量的大小都是4字节
short *p2; // 指针用来保存地址,无论是何种指针,对于32位处理器,指针变量的大小都是4字节
int *p3; // 指针用来保存地址,无论是何种指针,对于32位处理器,指针变量的大小都是4字节
long *p4; // 指针用来保存地址,无论是何种指针,对于32位处理器,指针变量的大小都是4字节
经常使用的类型
uint8_t // 实际上是unsigned char
uint16_t // 实际上是unsigned short
uint32_t // 实际上是unsigned int
uint64_t // 对于32位处理器,它是unsigned long long; 对于64位处理器,它是unsigned long
二、结构体
1.1.1结构体的引入
要描述 1 个人,他有名字、年龄、性别,可以如下定义变量:
char name[10];
int age;
int sex;
要描述 20 个人呢?可以如下定义数组:
char name[20][10];
int age[20];
int sex[20];
如果一个函数里,要传递一个人的信息可以这样写括号里面的内容叫形参
void print_info(char *name, int age, int sex);
如果人的信息非常多,就需要引入结构体
struct person {
char name[10];
int age;
int sex;
};
定义 20 个人:
struct person persons[20];
传入信息:
void print_info(struct person p);
2.1.1结构体指针
例如:
01 struct person zhangsan;
02 struct person *p;
03 p = &zhangsan;
内存中如图:

让结构体指针,直接指向 GPIO 模块:
例如:
typedef struct
{
uint32_t CRL; // 配置低8位引脚模式
uint32_t CRH; // 配置高8位引脚模式
uint32_t IDR; // 输入数据寄存器(只读)
uint32_t ODR; // 输出数据寄存器
uint32_t BSRR; // 位设置/复位寄存器
uint32_t BRR; // 位复位寄存器
uint32_t LCKR; // 配置锁定寄存器
} GPIO_REGS;
GPIO_REGS *gpioa = (GPIO_REGS *)0x40011000;
gpioa->BSRR = (1<<13);
BSRR第十三位设置为1原理如下


指针变了 gpioa 的值是 0x40011000,BSRR 在“GPIO_REGS”里的偏移地址是 0x10,所
以“gpioa->BSRR”访问的是“0x40011000+0x10”,就是 GPIOA_BSRR 寄存器的地址。
三、位操作
位运算是指二进制位之间的运算。

1.1.1 逻辑移位
对于无符号型值,算术移位等同于逻辑移位;对于有符号型值 ,算术左移等同于逻辑左移;算术右移补的是符号位,正数补0,负数补1。
无符号类型的数值移位时是“逻辑移位”,“有符号”的数值移位时是“算术移位”。
示例逻辑左移
unsigned int a = 0x123;
unsigned int b = a<<2; // b=0x48C

2.1.1把某几位设置为某值
把bit7设置为1,把bit8清除为0,分两步操作:先设置bit7,再清除bit8。
另一种情况: bit[8:7]= val, 先清除bit8, bit7,再或上val,
代码如下:
unsigned int a = 0x123;
unsigned int b = a & ~(3<<7); /* 清除bit7, bit8 */
b = b | (val << 7); /* 设置bit7, bit8为val */
嵌入式C语言核心概念解析
7963

被折叠的 条评论
为什么被折叠?



