2

我正在尝试从 PIC18f4580 向 SD 卡发送数据,但 PIC 并未发送应有的内容。

相关的全局变量:

unsigned char TXBuffer[128]; //tx buffer
unsigned char TXCurrentPos = 0x00; //tracks the next byte to be sent
unsigned char TXEndPos = 0x00; //tracks where new data should be put into the array

我正在使用以下函数将数据添加到缓冲区:

void addToBuffer(char data){

    TXBuffer[TXEndPos] = data;
    TXEndPos++;
}

并使用以下中断将 TXBuffer 中的数据放入 TXREG:

else if (PIR1bits.TXIF == 1){

    if((TXEndPos - TXCurrentPos) > 0){         // if there is data in the buffer
        TXREG = TXBuffer[TXCurrentPos];           // send next byte
        TXCurrentPos++;               // update to the new position
    }

使用示波器,我可以看到 PIC 正在发送 0x98,无论我在缓冲区中放入了什么。事实上,我从未将 0x98 放入缓冲区。

但是,如果我更换

TXREG = TXBuffer[TXCurrentPos];

TXREG = 0x55;

或者

TXREG = TXCurrentPos;

然后我得到了预期的结果,即PIC将重复发送0x55,或者分别从0开始计数。

那么,为什么 PIC 无法从阵列中发送数据,而其他任何时候都可以呢?我会强调传输是在中断中处理的,因为我觉得这是我问题的根源。

编辑:它是一个循环缓冲区,因为 TXEndPos 和 TXCurrentPos 在达到 127 时返回 0。当 TXEndPos - TXCurrentPos == 0 时,我还禁用发送中断,并在将数据添加到缓冲区时重新启用它。真的,我的代码完全按预期工作,如果我在 main 中向 TXBuffer 添加 13 个字符,我的 PIC 将传输 13 个字符然后停止。问题是它们总是相同的(错误的)字符 - 0x98。

EDIT2:更完整的功能在这里: http: //pastebin.com/MyYz1Qzq

4

3 回答 3

2

也许 TXBuffer 并没有真正包含您认为的数据?也许您没有调用 addToBuffer 或在错误的时间或使用错误的参数调用它?

你可以在你的中断处理程序中尝试这样的事情:

TXBuffer[TXCurrentPos] = TXCurrentPos;
TXREG = TXBuffer[TXCurrentPos];
TXCurrentPos++;

只是为了向自己证明您可以读取和写入 TXBuffer 并将其发送到 USART。

也试试:

TXREG = TXEndPos;

看看这是否符合您的期望(= 您的消息的长度)。

我假设还有一些我们在这里看不到的其他代码负责启动传输。还假设这是每条消息完成的,并且在消息之间重置位置 - 即这不应该是一个循环缓冲区。

编辑:基于查看最近发布的代码:您不需要通过将缓冲区的第一个字节写入 TXREG 来启动发送器吗?我通常会做的是启用中断并将第一个字节写入发送寄存器,快速查看数据表似乎表明这是你需要做的。另一件事是我仍然看不到您如何确保从 127 到 0 的环绕?

此外,您的 main() 似乎只是突然结束,一旦 main 结束,执行将在哪里继续?

于 2010-09-19T22:14:43.087 回答
1

有很多事情你没有照顾。TXBuffer 需要是一个循环缓冲区。一旦将 TXEndPos 增加到超过 127,则需要将其回绕回 0。对于 TXCurrrentPos 也是如此。这也会影响测试以查看缓冲区中是否有东西,> 0 测试还不够好。一般建议可在此处获得

于 2010-09-19T22:02:39.473 回答
1

您的代码不完整,但它看起来是错误的:如果没有要发送的内容会发生什么?那时您似乎没有加载TXREG,那么为什么要传输0x98任何内容,无论是它还是其他?

使用这种代码架构时通常的做法是在TXIE没有要发送的内容时关闭(在elseIRQ 例程的一部分中),并在函数结束时无条件打开它addToBuffer(因为你知道确保至少有一个字符要发送)。

此外,您应该直接测试TXEndPosandTXCurrentPos是否相等,因为通过添加两个模运算,您可以很容易地使用循环缓冲区。

于 2010-09-19T22:04:49.277 回答