我目前正在使用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;
}
}
答案 0 :(得分:0)
摘自数据表(第134页):
TX1IF是只读的,因此,您不应该对其进行写操作(如果您尝试尝试,TX1IF不会执行任何操作,但我不会对此感到困惑)。
R-0
TX1IF
TX1IF:EUSART1发送中断标志位
1 = EUSART1发送缓冲区TXREG1为空(在发生以下情况时清除 写入TXREG1)
0 = EUSART1发送缓冲区已满
此外,当您设置TX1IE
时中断立即触发,因此您不必写入TXREG1
,因为中断将立即开始下一个字符,这可能会导致问题,所以删除这个:
PIR1bits.TX1IF = 0;
TXREG1 = Count;
对于volatile
是否需要缓冲区,我还有一个疑问(volatile for variable that is only read in ISR?),我认为您需要它来禁用编译器可以尝试执行的某些优化,这将表示您将无法使用memset()
(在这种情况下,您可以使用我几天前使用的memset版本:Is `memcpy((void *)dest, src, n)` with a `volatile` array safe?(在这种情况下为memset_vout()
))
编辑: 正如对这两个问题中第一个问题的回答(及其评论)所言,您需要使用volatile来防止不必要的优化。因此,您需要重写memset(第二个链接)。
您还有另一个问题:在结束传输后,您没有重置TxCount
(出于与缓冲区相同的原因,它也应该是volatile
),因此第二条消息(及后续消息)您发送的邮件将始终返回支票。 ISR应该在重置TX1IE