• 不同芯片中的寄存器操作各有不同,其驱动的编写也不一样;不过对于GPIO它们有些通用的知识,大家都是一致的
    • GPIO: General-purpose input/output,通用的输入输出口
    • GPIO模块一般结构

    a. 有多组 GPIO,每组有多个 GPIO**(对于某些芯片,资源可能较少,只有很少的GPIO)
    b. 使能:电源/时钟
    c. 模式(Mode):引脚可用于 GPIO 或其他功能
    d. 方向:引脚 Mode 设置为 GPIO 时,可以继续设置它是输出引脚,还是输入引脚
    e. 数值:对于输出引脚,可以设置寄存器让它输出高、低电平
    对于输入引脚,可以读取寄存器得到引脚的当前电平**

    • 单片机、单核处理器芯片、多核处理器芯片等
    • 使用的芯片来至不同厂家,用的是不同的型号,其内部资源各有差别,但对于GPIO其内部结构都是类似的
    • GPIO内部结构框图分析:
      • image.png
      • 芯片内部有N组GPIO,每组GPIO中有若干个引脚
      • 想让某个引脚输入高低电平,怎么操作?
        • 沿着数据的流向反向来看
        • GPIO引脚数据来自IO_MUX多路选择器,MUX可以选择来自GPIO模块或串口模块的数据(这一步骤需要选着引脚数据来自哪) 一个引脚可以用于 GPIO、串口、USB 或其他功能
        • 数据来自GPIO模块时,需要使能该模块(enbale)
        • 为了省电,这些模块有可能在默认状态下是关闭的;为了使用模块需要进行使能模块来提供power、clock给模块工作
    • 对于一个GPIO引脚,操作需要4个步骤:
      • image.png
    • 对于GPIO操作各步骤,都需要R/W寄存器
      • 读写寄存器有个重要原则:不要去影响到其他位(don’t effort other bits)
    • 寄存器操作方式:
      • read-modify-write

    直接读写:读出、修改对应位、写入
    要设置 bit n:
    val = data_reg;
    val = val | (1<data_reg = val;
    可简化为: data_reg |= (1<<n);

    • 上面这种方式操作需要三个步骤,效率较低;于是有些处理器(芯片)对于数据寄存器又引出了两个寄存器:设置寄存器(set_reg)、清除寄存器(clr_reg)
    • set-and-clear protocol
      • image.png
      • 设置寄存器(set_reg)的哪一位为1,处理器内部硬件就会对应的设置实际数据寄存器的某一位为1
      • 清除寄存器(clr_reg)的哪一位为1,处理器内部硬件就会对应的设置实际数据寄存器的某一位为0

    set_reg, clr_reg, data_reg 三个寄存器对应的是同一个物理寄存器,
    要设置 bit n:set_reg = (1<要清除 bit n:clr_reg = (1<<n);

    • set-and-clear protocol是硬件内部实现的,我们并不需要了解其实现原理