IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> C 语言点运算符( . )和箭头运算符( -> )的区别(以单片机寄存器结构体定义为例) -> 正文阅读

[嵌入式]C 语言点运算符( . )和箭头运算符( -> )的区别(以单片机寄存器结构体定义为例)

在单片机寄存器封装的时候,一般库都会选择用地址偏移的办法完成。

    #define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00)

    #define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04)

    #define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08)

    #define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C)

    #define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10)

    #define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14)

    #define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18)

GPIOC_BASE是一个基地址,记录的是GPIOC寄存器的起始地址,是一个普通的常量,假设这个常量为C。

(unsigned int*)代表强制转换,即将后面的常量转变为一个地址指针,且类型为无符号整型。总的来说,C就是一个指向无符号整型的地址指针。如果没有强制转换,编译器会认为C就是一个普通的常量。

前面再加(*),就是指针的取内容,代表是取出在C地址的内容。所以GPIOC_CRL等内容并不是一个地址(指针),而是对应地址上面的内容。

    typedef struct

    {

        uint32_t CRL; /*GPIO 端口配置低寄存器 地址偏移: 0x00 */

        uint32_t CRH; /*GPIO 端口配置高寄存器 地址偏移: 0x04 */

        uint32_t IDR; /*GPIO 数据输入寄存器 地址偏移: 0x08 */

        uint32_t ODR; /*GPIO 数据输出寄存器 地址偏移: 0x0C */

        uint32_t BSRR; /*GPIO 位设置/清除寄存器 地址偏移: 0x10 */

        uint32_t BRR; /*GPIO 端口位清除寄存器 地址偏移: 0x14 */

        uint16_t LCKR; /*GPIO 端口配置锁定寄存器 地址偏移: 0x18 */

    }GPIO_TypeDef;

然后会封装一个结构体,命名为GPIO_TypeDef,存在7个成员。

 #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

之后GPIOC宏定义为GPIO_TypeDef类型的指针。GPIOC是一个指向GPIO_TypeDef类型,且初始位置为GPIOC_BASE的指针。这里和前面不同的地方在于,前面没有(*),也就是不需要取内容。

typedef struct          // 定义一个结构体类型
{
    char name[20];      // 结构体成员:name
    int height;             // 结构体成员:height
}STUDENT;
    
STUDENT data;              // 声明一个结构体变量
data.height = 180;          // 结构体变量通过点运算符( . )访问

以上是我们经常用的结构体定义和访问,可以看到我们并不是定义一个指针,而是定义了一个普通结构体变量,然后通过点运算符(.)去访问成员。那GPIOC作为一个指针,是如何访问结构体成员内部的结构。

  • 点运算符的左操作数必须是一个结构或者一个联合,而右操作数必须是该类型(结构或联合)成员的名字。
  • 运算符 -> 也可用于选择结构或联合的成员,但是箭头运算符的左操作数必须是一个指针,它指向一个结构或联合类型。右操作数是该结构或联合成员的名字。

所以一般寄存器的访问都是通过箭头运算符进行访问的。例如GPIOC->CRL= 0x00000001,可对CRL寄存器进行赋值。

typedef struct          // 定义一个结构体类型
{
    char name[20];      // 结构体成员:name
    int height;             // 结构体成员:height
}STUDENT;
    
STUDENT data;              // 结构体变量
STUDENT *pdata;              //结构体指针变量

 //点运算符( . )访问
data.height = 180;         
 //箭头运算符( -> )访问
pdata->height = 180;
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-27 14:15:39  更:2021-09-27 14:18:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 1:36:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码