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.

[参考译文] SW-EK-TM4C123GXL:GPIOPinWrite:HWREG是否需要传递UINT32_t?

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1103418/sw-ek-tm4c123gxl-gpiopinwrite-does-hwreg-need-to-be-passed-a-uint32_t

部件号:SW-EK-TM4C123GXL

我有一个中断时钟频率为100kHz,因此需要尽可能高效(例如最小时钟)。

所以我改变了对库的调用,将写入定向到内存映射寄存器。 这基本上只会删除在库中检查参数是否正确的操作。

有一件事让我困惑。 在GPIOPinWrite中,我们有:

Fullscreen
1
HWREG(ui32Port + (GPIO_O_DATA + (ui8Pins << 2))) = ui8Val;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

但在hw_types.h中,HWREG的定义为:

Fullscreen
1
2
#define HWREG(x) \
(*((volatile uint32_t *)(x)))
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

这不是说它是指向UINT32_t的指针,那么为什么GPIOPinWrite将uint8_t放入内存地址? 那么应该使用HWREGB -还是我误解了代码?

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

    好的-当我可以睡觉时,请最后仔细阅读CPU数据表。 我想我明白发生了什么。

    GPIO数据从ui32Port开始,长度为0x400字节,但实际上为0x100 32位字。 每个单词,24个最高位都是保留的,您只能设置8个最低有效位。 现在,对于写入代码的代码-展开以上代码以获取

    Fullscreen
    1
    (*((volatile uint32_t *)(ui32Port + (GPIO_O_DATA + (ui8Pins << 2))))) = (uint32_t) ui8Val;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    我所做的是明确地将类型转换写入UINT32_t,它隐含在原始中,但不显示。 因此,类型转换将最大的24位设置为零,这些设置保留位,ui8Val将设置为最低的8位。<2只是意味着当我们循环通过引脚时,我们向前跳转4个字节(等于一个32位字)。

    但是,代码可能 应该是,

    Fullscreen
    1
    (*((volatile uint8_t *)(ui32Port + (GPIO_O_DATA + (ui8Pins << 2))))) = (uint8_t) ui8Val;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    这只是设置最低的8位,而不会触及保留位。 但它假定32位数字是小尾数,而不是由编译器决定。

    现在,当我传递ui8Val =-1时,它变得更加棘手;例如,只需设置在ui8Pins中命名的所有GPIO引脚。 当它通过uint8_t时,它就变成0xff了-这很好。 但是如果我被32位数所转换,它就会变成0xffffffff,并在保留的位中加上1。 我可以这样做吗?

    所以我不清楚哪一种编码最清晰(在任何一种情况下都是通过HWREG定义的...

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

    您好,David:

     对于GPIOPinWrite(),TivaWare正在尝试实现单个引脚的位设置功能。 请参阅下面的说明或参阅您各自设备数据表中的相同部分。  

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

    是的,那是我读过的文档,它说您必须写入的数据只有8位宽,因为每个端口只能写入8个针脚。 因此,如果只需要写入8位, 则HWREGB ([例如  (*((volatile uint8_t *)(x))]是否使用? 但是库驱动程序使用HWREG...

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

    您好,David:

     上层24位 是保留的,而不是实际实现的。 写在上面的24位不起作用,因为它不会写任何内容。 因此,仅将8位写入地址或整个32位将是相同的。 是否有理由要修改TivaWare HWREG?

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

    我不确定写入保留位的含义,特别是在这种情况下,PIN不能引用保留位。 在文档中找不到。 我问的原因是,我是否从GPIOPinWrite内部获取代码并删除Assert错误测试,这将在非常紧的循环中保存时钟。

    但是,如果两个代码的结果相同,在相同的时钟数量上,那么我猜它的摆动和回旋处...

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

    您好,

     当我查看GPIOPinWrite()的反汇编代码时,它已经 优化为一个周期指令。  

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

    有趣-回家后我会检查一下。 想知道如何解决断言问题,也许它总是很静态,它可以在编译期间解决? 但是,GPIOPinWrite如何知道它在链接前收到的参数? 不管怎样,回家后我会检查一下。 如果是这样,我只能通过代码内联来获得。

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

    默认情况下,驱动程序库不是使用调试支持构建的。 因此,不会检查Assert。 如果要使用Assert,则需要重新生成driverlib。 请参阅下面的GPIO.c源代码。 如果不想重建库,可以将GPIO.c文件复制到CCS项目中。 尝试hello项目。 在CCS预定义符号中添加调试符号。  

    #ifdef调试
    静态布尔值
    _GPIOBaseValid (UINT32_t ui32Port)

    返回((ui32Port == gPIO_Porta_base)||
    (ui32Port == gPIO_Porta_AHB_BASE)||
    (ui32Port == gPIO_PORTB_BASE)||
    (ui32Port == gPIO_PORTB_AHB_BASE)||
    (ui32Port == gPIO_PORTC_BASE)||
    (ui32Port == gPIO_PORTC_AHB_BASE)||
    (ui32Port == gPIO_PORTD_BASE)||
    (ui32Port == gPIO_PORTD_AHB_BASE)||
    (ui32Port == gPIO_PORT_BASE)||
    (ui32Port == gPIO_PORT_AHB_BASE)||
    (ui32Port == gPIO_PORTF_BASE)||
    (ui32Port == gPIO_PORTF_AHB_BASE)||
    (ui32Port == gPIO_PORTG_BASE)||
    (ui32Port == gPIO_PORTG_AHB_BASE)||
    (ui32Port == gPIO_PORTH_BASE)||
    (ui32Port == gPIO_PORTH_AHB_BASE)||
    (ui32Port == gPIO_PORTJ_BASE)||
    (ui32Port == gPIO_PORTJ_AHB_BASE)||
    (ui32Port == gPIO_PORTK_BASE)||
    (ui32Port == gPIO_PORTL_BASE)||
    (ui32Port == gPIO_PORTM_BASE)||
    (ui32Port == gPIO_PORTN_BASE)||
    (ui32Port == gPIO_PORTP_BASE)||
    (ui32Port == gPIO_PORTQ_BASE)||
    (ui32Port == gPIO_PORTR_BASE)||
    (ui32Port == gPIO_PORTS_BASE)||
    (ui32Port == gPIO_PORTT_BASE);
    }
    #endif

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

    TA -是的,这说明了这一点。