【问题标题】:PIC18FXXXXX UART Tx message function?PIC18FXXXXX UART Tx 消息功能?
【发布时间】:2019-03-04 20:55:46
【问题描述】:

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

【问题讨论】:

  • 我猜你写了一个中断函数。可以发一下吗?
  • 此外,如果您知道如何对掩码执行相同操作,请避免使用位域。它们更快,而且位域是实现定义的,这意味着您的代码不可移植,并且可能表现与预期不同。 (即:PIE1 |= _PIE1_TX1IE_MASK;)或类似的东西。
  • @CacahueteFrito 编辑原始帖子以显示 ISR
  • 顺便说一下,我不知道你的确切图片,但至少在 PIC16f1829 上,TXIF 是只读的。
  • 在最后一条评论之后,在我提到的 PIC 中,可能在你的 PIC 中,你不应该重置 TXIF,而且,你不应该在 ISR 之外填充 TXREG,所以我会删除那些两行,看看是否有效。

标签: c pic uart


【解决方案1】:

来自数据表(第 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()))。

编辑: 正如这两个问题中第一个问题的答案(及其 cmets)所说,您需要 volatile 来防止不需要的优化。因此你需要重写 memset(第二个链接)。


您还有一个问题:您在结束传输后没有重置TxCount(也应该是volatile,原因与缓冲区相同),所以您发送给您的第二条(和后续)消息将始终返回支票。 ISR 应该在它重置后重置 TX1IE

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多