我正在尝试从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
答案 0 :(得分:2)
也许TXBuffer并不真正包含您认为它的数据?也许你没有在错误的时间或错误的参数调用addToBuffer或调用它?
你可以在你的中断处理程序中尝试这样的事情:
TXBuffer[TXCurrentPos] = TXCurrentPos;
TXREG = TXBuffer[TXCurrentPos];
TXCurrentPos++;
为了向自己证明,您可以读写TXBuffer并将其发送到USART。
还可以尝试:
TXREG = TXEndPos;
查看这是否符合您的期望(=邮件的长度)。
我假设还有一些我们在这里没有看到的其他代码负责启动传输。还假设这是根据消息完成的,其中位置在消息之间重置 - 即,这不应该是循环缓冲区。
编辑:基于查看最近发布的代码: 您是否需要通过将缓冲区的第一个字节写入TXREG来启动发送器?我通常做的是启用中断并将第一个字节写入发送寄存器,快速查看数据表似乎表明您需要做的事情。另一件事是我仍然没有看到你如何确保从127到0的环绕?
你的main()似乎只是突然结束,一旦主要结束,执行会继续在哪里?
答案 1 :(得分:1)
有很多事情你没有照顾。 TXBuffer需要是一个循环缓冲区。一旦你将TXEndPos增加到127,那么你需要将它包回到0.相同的TXCurrrentPos。这也会影响测试以查看缓冲区中是否存在某些内容,> 0测试不够好。通用建议是available here。
答案 2 :(得分:1)
您的代码不完整,但它看起来不对:如果没有要发送的内容会怎么样?您似乎没有加载TXREG
,那么为什么会传输任何内容,无论是0x98
还是其他任何内容?
当使用这种代码体系结构时,通常使用的方法是在没有任何内容要发送的情况下关闭TXIE
(在IRQ例程的else
部分中),然后将其关闭无条件地在addToBuffer
函数的末尾(因为你确定至少要发送一个字符)。
此外,您应该直接测试TXEndPos
和TXCurrentPos
是否相等,因为这样可以通过添加两个模运算来非常轻松地使用循环缓冲区。