This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C123GH6PM:GPIODATA 寄存器的地址

Guru**** 2465890 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/665436/tm4c123gh6pm-address-of-gpiodata-register

器件型号:TM4C123GH6PM

HY、

我已经购买 了 Tiva C 系列 TM4C123G LaunchPad 评估套件、 我非常满意、工作得很好。

我已经从 YouTube 教程中实施了一些代码,如下所示:  

#include 

int main()
{
int 计数器= 0;

//通用输入/输出运行模式时钟门控控制(RCGCGPIO)
*((unsigned int*) 0x400FE608)= 0x20;

// RGB LED 连接到 PF1、PF2、PF3
// GPIO 方向- GPIODIR
*((unsigned int*) 0x40025400)= 0x0E;

// GPIO 数字使能- GPIODEN
*((unsigned int*) 0x4002551C)= 0x0E;

while (1)
{
// GPIO 数据- GPIODATA -红色 LED 亮起
*((unsigned int*) 0x400253FC)= 0x02;
计数器= 0;
while (计数器< 1000000)
{
COUNTER++;
}
// GPIO 数据- GPIODATA -蓝色 LED 亮起
*((unsigned int*) 0x400253FC)= 0x04;
计数器= 0;
while (计数器< 1000000)
{
COUNTER++;
}
// GPIO 数据- GPIODATA -绿色 LED 亮起
*((unsigned int*) 0x400253FC)= 0x08;
计数器= 0;
while (计数器< 1000000)
{
COUNTER++;
}
}
返回0;
} 

此代码运行良好、但我的问题是、当我要访问 GPIODATA 时、地址为0x400253FC。
在微控制器的数据表中、GPIODATA 的地址为0x40025000。
我知道这个控制器有六个模块(A、B、C、D、E 和 F),但是我不知道如何计算上面的地址?
谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此代码运行良好、但我的问题是、当我要访问 GPIODATA 时、地址为0x400253FC。
    在微控制器的数据表中、GPIODATA 的地址为0x40025000。
    我知道这个控制器有六个模块(A、B、C、D、E 和 F),但是我不知道如何计算上面的地址?
    谢谢你。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    首先、这是一种非常糟糕的编码方式。 您在这里提出的问题就是您需要的所有证据。

    2ndly、3FC 是数据寄存器的偏移量:查看数据表并确定它是哪个端口。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Danny F"]首先,这是一种非常糟糕的编码方式。

    它实际上不如 TIVAWare 类型安全、这需要一些工作。 它没有任何有用的抽象。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    让我对这一点稍作说明,因为它背后有一段历史。

    当 Luminary 活跃而正常时、这个问题引起了他们的注意:数据表的这一部分写得不是特别好、也没有对端口结构的完整描述。 我不确定是否在收购 Luminary 之后也将其带到了 TI。

    无论如何、每个端口的前255个字是单周期位段实现。 数据表的运行方式非常疯狂。

    偏移量0x3fc 处的下一个 DWORD 是数据寄存器。 但是、数据表中没有对此进行披露。 我在这里发布的 CMSIS 实现更清晰地显示:

    /**
    *@GPIOA 外设(GPIOA)的简要寄存器映射
    */
    
    typedef 结构{ /*!< GPIOA 结构 */
    __io uint32_t RESERVED0[255];
    __io uint32_t data; /*!< GPIO 数据 */
    __io uint32_t DIR; /*!< GPIO 方向 */
    __io uint32_t is; /*!< GPIO 中断检测 */
    __io uint32_t IBE; /*!< GPIO 双边沿中断 */
    __io uint32_t IEV; /*!< GPIO 中断事件 */
    __ io uint32_t IM; /*!< GPIO 中断屏蔽 */
    __io uint32_t RIS; /*!< GPIO 原始中断状态 */
    __io uint32_t MIS; /*!< GPIO 屏蔽中断状态 */
    __O uint32_t ICR; /*!< GPIO 中断清除 */
    __io uint32_t AFSEL; /*!< GPIO 备用功能选择 */
    __I uint32_t RESERVED1[55];
    __IO uint32_t DR2R; /*!< GPIO 2-mA 驱动选择 */
    __io uint32_t DR4R; /*!< GPIO 4-mA 驱动选择 */
    __io uint32_t DR8R; /*!< GPIO 8-mA 驱动选择 */
    __io uint32_t ODR; /*!< GPIO 开漏选择 */
    __io uint32_t PUR; /*!< GPIO 上拉选择 */
    __io uint32_t PDR; /*!< GPIO 下拉选择 */
    __IO uint32_t SLR; /*!< GPIO 斜率控制选择 */
    __io uint32_t DEN; /*!< GPIO 数字使能 */
    }GPIOA_Type;
    

    注意到 RESERVED0[]是32位类型? 这就是我们要讨论的内容。

    因此、您有两种方法可以读取/写入端口。

    1)通过数据寄存器:

    led_port->data |= LED;//set led 
    LED_PORT-> DATA &=~LED;//CLR LED
    

    2) 2)通过位段区域 
    LED_PORT->RESERVED0[LED]= LED;//set led
    LED_PORT->RESERVED0[LED]=~LED;//清除 LED
    

    第二种方法的优点是它本质上是原子的、并且通常更快。

    如果您愿意、可以将 RESERVED0[]重命名为您更喜欢的内容。

    但这比 TI 在其 driverlib 中的 HWREG()宏可读性要高得多。