PIC18FXXXXX UART Tx消息功能?

时间:2019-03-04 20:55:46

标签: c pic uart

我目前正在使用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;
    }
}

1 个答案:

答案 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

之后立即重置