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:TM4C123GH6PM GPIO 数据表中的数据寄存器偏移错误

Guru**** 2614275 points

Other Parts Discussed in Thread: TM4C123GH6PM, EK-TM4C123GXL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/778647/tm4c123gh6pm-tm4c123gh6pm-gpio-data-register-offset-wrong-in-datasheet

器件型号:TM4C123GH6PM
Thread 中讨论的其他器件: EK-TM4C123GXL

您好!

我在文件中注意到了这一点

D S -T M 4C 123G H6 P M - 1 5 8 4 2。 2 7 4 1.
S P M S 376E

这是 Tiva TM4C123GH6PM 的数据表、数据寄存器存在错误的偏移:

数据表显示偏移量为0x0000、但 Code Composer Studio IDE 的寄存器偏移量为0x03FC。 写入偏移量0x00不起任何作用、而我可以通过 EK-tm4c123gxl 板进行确认、只有在写入偏移量0x03FC 时、引脚才会切换。 我是正确的还是遗漏了什么?

花了我一天时间才找到它:-D 现在我对 Tiva 的 GPIO 有了很多了解。

此致、

L. B.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    您尝试写入哪个 GPIO 端口和哪个引脚? 假设您要写入端口 A 的引脚0。 通常、您会按如下方式调用 API。

    GPIOPinWrite (GPIO_Porta_base、GPIO_PIN_0、GPIO_PIN_0);

    现在、看看下面的 API 编码。

    在 gpio.c 中、您将看到 GPIOPinWrite (GPIO_Porta_base、GPIO_PIN_0、GPIO_PIN_0正在写入地址 ui32Port +(GPIO_O_DATA +(ui8pins << 2))。 ui32Port 等于0x40004000、GPIO_DATA = 0x00000000、(ui8Piins<2)等于0x00000001<2或0x0000004。 最终地址等于0x40004004。 基本上、数据寄存器中的每个位都映射到一个字地址、以方便在不执行读-修改-写的情况下进行位写入。 数据表10.2.1.2数据寄存器操作下提供了一些详细信息。



    //
    //
    //! 将值写入指定的引脚。
    //!
    //! \param ui32Port 是 GPIO 端口的基址。
    //! \param ui8pins 是引脚的位封装表示。
    //! \param ui8Val 是要写入引脚的值。
    //!
    //! 将相应的位值写入指定的输出引脚
    //! Ui8引脚。 写入配置为输入引脚的引脚无效。
    //!
    //! 引脚使用位封装字节指定、其中每个位都是
    //! 置位表示要访问的引脚、以及字节的位0的位置
    //! 代表 GPIO 端口引脚0、位1代表 GPIO 端口引脚1、依此类推。
    //!
    //! \无返回。
    //
    //
    无效
    GPIOPinWrite (uint32_t ui32Port、uint8_t ui8引脚、uint8_t ui8Val)

    //
    //检查参数。
    //
    assert (_GPIOBaseValid (ui32Port));

    //
    //写入引脚。
    //
    HWREG (ui32Port +(GPIO_O_DATA +(ui8引脚<< 2)))= ui8Val;


    网址为 hw_memmap.h
    //
    //
    //以下是存储器和的基址定义
    //外设。
    //
    //
    #define FLASH_base 0x00000000 //闪存存储器
    #define SRAM_base 0x20000000 // SRAM 存储器
    #define WATCHDOG0_BASE 0x40000000 //看门狗0
    #define WATCHDOG1_BASE 0x40001000 //看门狗1
    #define GPIO_Porta_base 0x4000// GPIO 端口 A
    #define GPIO_PORTB_BASE 0x40005000 // GPIO 端口 B
    #define GPIO_PORTC_BASE 0x40006000 // GPIO 端口 C
    #define GPIO_PORTD_base 0x40007000 // GPIO 端口 D

    网址为 hw_gpio.h
    //
    //
    //以下是为 GPIO 寄存器偏移定义的。
    //
    //
    #define GPIO_O_DATA 0x00000000 // GPIO 数据
    #define GPIO_O_DIR 0x00000400 // GPIO 方向


    网址为 gpio.h
    //
    //
    //以下值定义了 ui8Pins 参数到的位字段
    //多个 API。
    //
    //
    #define GPIO_PIN_0 0x00000001 // GPIO 引脚0
    #define GPIO_PIN_1 0x00000002 // GPIO 引脚1
    #define GPIO_PIN_2 0x00000004 // GPIO 引脚2
    #define GPIO_PIN_3 0x00000008 // GPIO 引脚3
    #define GPIO_PIN_4 0x00000010 // GPIO 引脚4
    #define GPIO_PIN_5 0x00000020 // GPIO 引脚5
    #define GPIO_PIN_6 0x00000040 // GPIO 引脚6
    #define GPIO_PIN_7 0x00000080 // GPIO 引脚7
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我理解您的答案-您正在讨论位段。

    我正在处理的项目是一个开源项目、由于 TivaWare 库中的版权声明、我必须编写我自己的 GPIOWrite 函数。

    以下是我的代码:

    //定义我们需要进行引脚切换的寄存器//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    #define ADDR (x)    (*(unsigned long*)(x)))
    #define SYSCTL_GPIO_ENABLE    *(volatile unsigned long *) 0x400FE608
    #define SYSCTL_GPIO_READY     *(volatile unsigned long *) 0x400FEA08

    #define SYSCTL_GPIOA_MASK     0x0001
    #define GPIO_PORta_DIR        *(volatile unsigned long *) 0x40004400 // GPIO 端口 A 方向寄存器基址
    #define GPIO_PORta_data       *(volatile unsigned long *) 0x400043FC/GPIO 端口 A 数据寄存器基址
    #define GPIO_PORta_dig_PIN    *(volatile unsigned long *) 0x4000451C/GPIO 端口 A 数字引脚使能寄存器基址
    #define GPIO_PINMASK_7        0x80                                 // GPIO 引脚 PA7屏蔽

    //提供宏来执行引脚切换////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //初始化引脚+时钟
    #define PIN_init (number)                                       \
       执行{                                                       \
           switch (number){                                        \
           案例0:                                                \            
               中断;                                             \
            案例7:                                               \
               /*打开 GPIO A 时钟*/                         \
               SYSCTL_GPIO_ENABLE |= SYSCTL_GPIOA_MASK;           \
               /*等待 GPIO A 就绪*/\                         
               while (!(SYSCTL_GPIO_READY 和 SYSCTL_GPIOA_MASK)){} \
               /*设置为输出 GPIO PA7 */                       \
               GPIO_PORta_DIR |= GPIO_PINMASK_7;                  \
               GPIO_PORta_dig 引脚|= GPIO_PINMASK_7;              \
               /*拉低 GPIO PA7 */                            \
               GPIO_PORta_data &=~GPIO_PINMASK_7;                \
               中断;                                             \
           }                                                      \
       } while (0)

    //将引脚设置为高电平
    #define PIN_SET (number)                        \
       执行{                                       \
           switch (number){                        \
           案例0:                                \           
               中断;                             \
           案例7:                                \
               /*设置 PA7 */                      \
               GPIO_PORta_data |= GPIO_PINMASK_7; \
               中断;                             \
           }                                      \
       } while (0)                                 \


    如果我使用

    #define GPIO_PORta_data       *(volatile unsigned long *) 0x40000//GPIO 端口 A 数据寄存器基址

    不管用。

    此致、

    L. B.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您在正确的轨道上了解位段。 如果您再次阅读位段概念、您将了解它的工作原理。

    写入0x40004000意味着您没有将任何引脚设置为高电平。 没有可写的引脚。

    要仅将引脚0设置为高电平、您需要写入0x40004004。
    要仅将引脚1设置为高电平、您需要写入0x40004008。
    要同时将引脚0和引脚1设置为高电平、您需要写入0x4000400C。
    要仅将引脚7设置为高电平、请写入0x40004200。
    要将所有引脚(引脚0...引 脚7)设置为高电平、您需要向0x400043FC 写入数据。

    这意味着、256个引脚组合中的每个引脚都映射到一个唯一的字地址、以方便位写入。 当您写入0x400043FC 时、即使您写入该地址的值仅设置了 pin7、该地址中的所有引脚也可写入高电平。

    尝试写入0x40004200、您会发现您可以写入值为0x80的引脚7。 如果您要将0xFF 写入0x40004200、则只会设置 pin7、但不会设置其他引脚。 在该地址处、只有引脚7是可写的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    实际上、在数据表中、说明开头有一个重要的句子、就是您在这里所说的内容、这是:

    为了写入 GPIODATA、必须设置屏蔽中由地址总线位[9:2]产生的相应位。 否则、写入操作将保持位值不变。

    因此、我被认为 GPIODATA 寄存器是 MSP430中的 OUT 寄存器误导了。

    感谢你能抽出时间!

    此致、
    L. B.