USART передает проблемы на PIC - PullRequest
2 голосов
/ 20 сентября 2010

Я пытаюсь отправить данные на SD-карту с PIC18f4580, но PIC не отправляет то, что должно быть.

связанные глобальные переменные:

unsigned char TXBuffer[128]; //tx buffer
unsigned char TXCurrentPos = 0x00; //tracks the next byte to be sent
unsigned char TXEndPos = 0x00; //tracks where new data should be put into the array

Я добавляю данные в буфер, используя следующую функцию:

void addToBuffer(char data){

    TXBuffer[TXEndPos] = data;
    TXEndPos++;
}

И помещает данные из TXBuffer в TXREG со следующим прерыванием:

else if (PIR1bits.TXIF == 1){

    if((TXEndPos - TXCurrentPos) > 0){         // if there is data in the buffer
        TXREG = TXBuffer[TXCurrentPos];           // send next byte
        TXCurrentPos++;               // update to the new position
    }

Используя осциллограф, я вижу, что PIC отправляет 0x98, независимо от того, что я помещаю в буфер. На самом деле я никогда не помещал 0x98 в буфер.

Однако, если я заменю

TXREG = TXBuffer[TXCurrentPos];

с

TXREG = 0x55;

или

TXREG = TXCurrentPos;

затем я получаю ожидаемые результаты, то есть PIC будет отправлять 0x55 несколько раз или считать от 0 соответственно.

Так почему у PIC проблемы с отправкой данных из массива, но в любое другое время это нормально? Подчеркну, что передача обрабатывается в прерывании, потому что я чувствую, что это корень моей проблемы.

РЕДАКТИРОВАТЬ: Это кольцевой буфер в том смысле, что TXEndPos и ​​TXCurrentPos возвращаются к 0, когда они достигают 127. Я также отключаю прерывание передачи, когда TXEndPos - TXCurrentPos == 0, и повторно включаю его при добавлении данных в буфер. Действительно, мой код работает полностью, как и ожидалось: если я добавлю 13 символов в TXBuffer в основном, мой PIC передаст 13 символов, а затем остановится. Проблема в том, что они всегда одинакового (неправильного) символа - 0x98.

EDIT2: более полные функции здесь: http://pastebin.com/MyYz1Qzq

Ответы [ 3 ]

2 голосов
/ 20 сентября 2010

Возможно, TXBuffer на самом деле не содержит данных, которые, по вашему мнению, содержат?Может быть, вы не вызываете addToBuffer или вызываете его не в то время или с неправильным параметром?

Вы можете попробовать что-то вроде этого в вашем обработчике прерываний:

TXBuffer[TXCurrentPos] = TXCurrentPos;
TXREG = TXBuffer[TXCurrentPos];
TXCurrentPos++;

Просто чтобы доказатьсамостоятельно вы можете прочитать и написать в TXBuffer и отправить его в USART.

Также попробуйте:

TXREG = TXEndPos;

Чтобы проверить, соответствует ли это вашему ожиданию (= длина вашего сообщения).

Я предполагаю, что есть некоторый другой код, который мы не видим здесь, который заботится о начале передачи.Также предполагается, что это делается для каждого сообщения с перезаписываемой позицией между сообщениями, т. Е. Это не должен быть кольцевой буфер.

РЕДАКТИРОВАТЬ: на основе просмотра недавно опубликованного кода: не нужнозапустить передатчик путем записи первого байта вашего буфера в TXREG?Обычно я включаю прерывание и записываю первый байт в регистр передачи, и быстрый просмотр таблицы данных показывает, что это то, что вам нужно сделать.Другое дело, что я до сих пор не понимаю, как вы гарантируете переход от 127 до 0?

Кроме того, ваш main (), кажется, просто внезапно завершается, где продолжается выполнение после завершения main?

1 голос
/ 20 сентября 2010

Ваш код неполон, но выглядит как есть: что произойдет, если отправлять нечего?Похоже, вы не загружаете TXREG тогда, так почему бы что-либо передавать, будь то 0x98 или что-то еще?

Обычно это делается, когда используется этот вид архитектуры кода.отключите TXIE, если отправлять нечего (в части else процедуры IRQ), и включите его безоговорочно в конце функции addToBuffer (поскольку вы точно знаете, что есть хотя быодин символ для отправки).

Кроме того, вы должны проверить TXEndPos и TXCurrentPos непосредственно на равенство, поскольку это позволит вам очень легко использовать кольцевой буфер, добавив две операции по модулю.

1 голос
/ 20 сентября 2010

Есть много вещей, о которых вы не заботитесь. TXBuffer должен быть кольцевым буфером. Как только вы увеличиваете TXEndPos до 127, вам нужно обернуть его обратно в 0. То же самое для TXCurrrentPos. Это также влияет на тест, чтобы увидеть, есть ли что-то в буфере, тест> 0 не достаточно хорош. Общий совет доступен здесь .

...