PIC18FXXXXX UART Tx функция сообщения? - PullRequest
0 голосов
/ 04 марта 2019

В настоящее время я использую 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 голосов
/ 05 марта 2019

Из таблицы (стр. 134):

TX1IF доступен только для чтения, и, следовательно, вы не должны писать в него (я думаю, что это ничего не даст, если вы попытаетесь, но я бы не стал связываться с этим).

R-0

TX1IF

TX1IF: Бит флага прерывания передачи EUSART1

1 = TXREG1 буфер передачи EUSART1пусто (очищается при записи TXREG1)

0 = Буфер передачи EUSART1 заполнен


Кроме того, поскольку прерывание срабатывает сразу после установки TX1IE, вы неНе нужно писать в TXREG1, потому что прерывание немедленно запустит следующий символ, и это, вероятно, вызовет проблемы, поэтому удалите это:

PIR1bits.TX1IF = 0;
TXREG1 = Count;

У меня есть еще открытый вопрос ( volatile для переменной, которая читается только в ISR? ) о необходимости volatile для буфера, и я думаю, что вам нужно отключить некоторые оптимизации, которые компилятор может попытаться сделать, и это подразумеваетчто вы не сможете использовать memset() (в этом случае вы можете использоватьверсия memset, которую я сделал несколько дней назад: Безопасен ли `memcpy ((void *) dest, src, n)` с массивом `volatile`? (в данном случае memset_vout())).

Редактировать: Поскольку ответ (и его комментарии) на первый из этих двух вопросов говорит о том, что вам нужно изменчиво, чтобы предотвратить нежелательную оптимизацию.И поэтому вам нужно переписать memset (вторая ссылка).


У вас есть другая проблема: вы не сбрасываете TxCount (который также должен быть volatile по той же причине, что и буфер).) после завершения передачи второе отправленное вами (и последующие) сообщение всегда будет возвращаться в чеке.ISR должен сбросить это сразу после сброса TX1IE

...