下面讲的有几点不懂:1 代码5-2中“GPIOH_BASE+0x14”怎么得来的?2 代码5-2和5-3差一个*号,是不是代码5-2少写了?
比如,我们找到 GPIOH 端口的输出数据寄存器 ODR 的地址是 0x4002 1C14(至于这
个地址如何找到可以先跳过,后面我们会有详细的讲解),ODR 寄存器是 32bit,低 16bit
有效,对应着 16 个外部 IO,写 0/1 对应的的 IO 则输出低/高电平。现在我们通过 C 语言指
针的操作方式,让 GPIOH 的 16 个 IO 都输出高电平,具体见代码 5-1。
代码 5-1 通过绝对地址访问内存单元
1 // GPIOH 端口全部输出 高电平
2 *(unsigned int*)(0x4002 1C14) = 0xFFFF;
0x4002 1C14 在我们看来是 GPIOH 端口 ODR 的地址,但是在编译器看来,这只是一
个普通的变量,是一个立即数,要想让编译器也认为是指针,我们得进行强制类型转换,
把它转换成指针,即(unsigned int *)0x4002 1C14,然后再对这个指针进行 * 操作。
刚刚我们说了,通过绝对地址访问内存单元不好记忆且容易出错,我们可以通过寄存
器的方式来操作,具体见代码 5-2。
代码 5-2 通过寄存器别名方式访问内存单元
1 // GPIOH 端口全部输出 高电平
2 #define GPIOH_ODR (unsigned int*)(GPIOH_BASE+0x14)
3 * GPIOH_ODR = 0xFF;
为了方便操作,我们干脆把指针操作“*”也定义到寄存器别名里面,具体见代码 5-3。
代码 5-3 通过寄存器别名访问内存单元
1 // GPIOH 端口全部输出 高电平
2 #define GPIOH_ODR *(unsigned int*)(GPIOH_BASE+0x14)
3 GPIOH_ODR = 0xFF;