【问题标题】:How do these uart structs as function parameters work?这些作为函数参数的 uart 结构是如何工作的?
【发布时间】:2018-02-28 09:53:36
【问题描述】:

我有这段代码,我正试图理解,但我被困住了,所以也许你们中的一个好人可以为我指明正确的方向。

一步一步来,我已经完成了这部分的初始化...

volatile struct UART *pTXD1;
volatile struct UARTINIT *pPort1;

...结构...

struct UARTINIT
{
    union SR_BYTE SR; /* Status register */
    BYTE DR; /* Data register */
    BYTE BRR1; /* Baud Rate reg 1 */
    BYTE BRR2; /* Baud Rate reg 2 */
    union CR1_BYTE CR1; /* Control register 1 */
    union CR2_BYTE CR2; /* Control register 2 */
    BYTE CR3; /* Control register 3 */
    BYTE CR4; /* Control register 4 */
};

struct UART
{
    BYTE *Buffer;
    WORD max;
    WORD read;
    WORD write;
    BYTE Baud;
    BYTE stopp;
};

...函数调用...

Transmit_Uart(pTXD1, pPort1);

...函数

void Transmit_Uart(struct UART *Buff, struct UARTINIT *USART)
{
    if ((*Buff).write != (*Buff).read)
    {
        if ((*USART).SR.bit.TC)
        {
            (*Buff).read = ((*Buff).read + 1) % (*Buff).max;
            (*USART).DR = (*Buff).Buffer[(*Buff).read];
        }
    }
    else
        (*Buff).stopp = OFF;
    return;
}

我的问题是我不明白哪些信息写入了结构。 该函数以 pTXD1 和 pPort1 作为参数调用,但这两个只是指向结构的指针,不是吗?

如果我的问题无法理解,我深表歉意,并很乐意根据需要提供更多信息。

【问题讨论】:

  • 您可能应该找到一本很好的初学者书籍,其中解释了指针和取消引用运算符*,以了解它的作用。
  • 搜索并阅读“内存映射”硬件/寄存器/结构。比如this等文章。

标签: c struct embedded uart memory-mapping


【解决方案1】:

他们使用UARTINIT 结构体来可视化 UART 硬件中的内存映射硬件寄存器。结构必须与寄存器布局完全对应才能工作,因此编写代码的人必须确保没有结构填充处于活动状态。 (通常在 8 位或 16 位 MCU 上不是问题,但会在更大的内核上。)

因此,结构指针pPort1 将指向芯片上可能存在的多个 UART 硬件之一中的第一个寄存器。寄存器已经“分配”了——它们以内存映射硬件的形式存在。

UART 结构似乎只是一个用户定义的结构,用于存储各种设置和将数据铲入和移出 UART 硬件缓冲区。如果是这样,则该结构必须分配在用户 RAM 中的某个位置。或者它也是一个寄存器内存映射,在这种情况下你有一些非常奇怪的硬件。

需要某种形式的文档来了解其使用方式。 ((*Buff).read + 1) % (*Buff).max; 之类的代码看起来很晦涩;我不知道为什么他们不简单地让驱动程序读取/写入原始数据字节。

【讨论】:

  • 我明白了,这很有意义,谢谢,感谢您的解释。
【解决方案2】:

将参数传递给函数的引用调用方法将参数的地址复制到形式参数中。在函数内部,地址用于访问调用中使用的实际参数。这意味着对参数所做的更改会影响传递的参数。

click here for more info

在这里,您将指针传递给结构而不是结构本身。 *Buff“取消引用”指针。换句话说,*Buff 会给你指针指向的结构。

for tutorial on dereferencing(haven't watched it but seems decent enough)


现在您可以直接将结构作为参数发送,但这样做是在函数范围内创建结构的副本。因此,您在函数内部所做的任何更改都会影响该副本而不是原始版本。所以你发送一个指针。


此外,不建议将结构按值传递给函数,因为它们通常非常大,需要复制到函数的堆栈中......等等等等(我可以继续)


底线....

您将指针传递给函数....函数更新指针处的值....丢弃 mic(yayyy)。

如果出现疑问,我们很乐意澄清。但是请尝试查看一些关于通过引用传递、取消引用等的教程(应该有所帮助)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多