我目前正在使用PIC18F67J60尝试使用UART打印出字符串和/或整数值,但我只能从中获得“00”。我对嵌入式C有点新意,所以可能有些东西我实际上缺失了。
该功能定义为:
u8 UART_TxMessage(u8 Count, u8 *Bufr)
{
if (Timer_Expired(RxTimer))
{
Timer_Stop(RxTimer);
RxIndex = 0;
}
if (TxCount)
return(0); // still sending last message
if (Count > MAX_MSG)
return(Count);
memcpy(TxBufr,Bufr,Count);
TxIndex = 0;
TxCount = Count;
PIR1bits.TX1IF = 0;
TXREG1 = Count;
PIE1bits.TX1IE = 1;
return(Count);
}
除了“00”之外我唯一能得到任何东西的方法是回复在Rx方面收到的东西;所以我有信心这只是我缺乏知识。
我真的很感激任何例子!
ISR功能按要求:
void UART_ISR()
{
u8 c;
if (PIR1bits.TX1IF && PIE1bits.TX1IE)
{
PIR1bits.TX1IF = 0;
if (TxIndex < TxCount)
{
TXREG1 = TxBufr[TxIndex++];
} else {
PIE1bits.TX1IE = 0;
}
}
if (PIR1bits.RC1IF)
{
Timer_Set(RxTimer,100);
PIR1bits.RC1IF = 0;
c = RCREG1;
if (RxCount)
return; // buffer in use
if (RxIndex >= MAX_MSG)
{
RxIndex = 0; // abort
return;
}
RxBufr[RxIndex++] = c;
}
}
从数据表(第134页):
TX1IF是只读的,因此,你不应该写它(我想如果你尝试它什么都不做,但我不会惹这个)。
R-0
TX1IF
TX1IF:EUSART1发送中断标志位
1 = EUSART1发送缓冲器TXREG1为空(写入TXREG1时清零)
0 = EUSART1发送缓冲区已满
此外,当您设置TX1IE
时立即触发中断,您不必写入TXREG1
,因为中断将立即启动下一个字符,这可能会导致问题,因此请删除此:
PIR1bits.TX1IF = 0;
TXREG1 = Count;
我有一个问题仍然是开放的(volatile for variable that is only read in ISR?)关于缓冲区需要volatile
,我认为你需要它来禁用编译器可能尝试做的一些优化,这意味着你将无法使用memset()
(在这种情况下,你可以使用我几天前做过的memset版本:Is `memcpy((void *)dest, src, n)` with a `volatile` array safe?(在这种情况下,memset_vout()
))。
编辑:正如这两个问题中的第一个问题的答案(及其评论)所示,您需要使用volatile来防止不必要的优化。因此,您需要重写memset(第二个链接)。
您还有另一个问题:在结束传输后,您不会重置TxCount
(也应该是volatile
的原因与缓冲区相同),因此您发送给您的第二个(和后续)消息将始终在检查中返回。 ISR应该在重置TX1IE
之后重置