Вот ее текст:
Код
typedef unsigned char BYTE;
#define TX_BUFFER_SIZE0 64
#define COM_TEMP 6 // COMxTX Empty
volatile BYTE tx_buffer0[TX_BUFFER_SIZE0];
volatile char tx_wr_index0, tx_rd_index0, tx_counter0;
void putBYTE0(BYTE c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
tx_buffer0[tx_wr_index0] = c;
if (++tx_wr_index0 == TX_BUFFER_SIZE0)
tx_wr_index0=0;
tx_counter0++;
}
__arm __irq void IRQ_Handler(void)
{
if (IRQSTA & (1 << INT_T0)) // сброс прерывания от таймера
T0ICLR = 0;
BYTE status;
status = COM0STA0;
if (status & (1 << COM_TEMP))
{
if (tx_counter0)
{
tx_counter0--; // 1
COM0TX = tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == TX_BUFFER_SIZE0) // 2
tx_rd_index0=0;
// test -------
if (!tx_counter0 && (tx_rd_index0 != tx_wr_index0))
LED_OFF;
// test -------
}
}
}
#define TX_BUFFER_SIZE0 64
#define COM_TEMP 6 // COMxTX Empty
volatile BYTE tx_buffer0[TX_BUFFER_SIZE0];
volatile char tx_wr_index0, tx_rd_index0, tx_counter0;
void putBYTE0(BYTE c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
tx_buffer0[tx_wr_index0] = c;
if (++tx_wr_index0 == TX_BUFFER_SIZE0)
tx_wr_index0=0;
tx_counter0++;
}
__arm __irq void IRQ_Handler(void)
{
if (IRQSTA & (1 << INT_T0)) // сброс прерывания от таймера
T0ICLR = 0;
BYTE status;
status = COM0STA0;
if (status & (1 << COM_TEMP))
{
if (tx_counter0)
{
tx_counter0--; // 1
COM0TX = tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == TX_BUFFER_SIZE0) // 2
tx_rd_index0=0;
// test -------
if (!tx_counter0 && (tx_rd_index0 != tx_wr_index0))
LED_OFF;
// test -------
}
}
}
Глюк в том, что в передатчик UART иногда посылается на 1 байт больше! Этот факт отражен в тестовом фрагменте между двумя // test. Т.е. при уменьшении tx_counter до 0, tx_rd_index0 становится больше (на 1), чем tx_wr_index0.
Так реально и происходит. ПК получает лишний байт, стоящий за буфером. Бряк, останавливающий Jet-Lin и поставленный на макрос LED_OFF, показывает в Watch, что tx_rd_index = tx_wtr_index+1 (с учетом, естественно закольцовки буфера). Дальше идет, как и положено, полная ерунда

Что тут не так? В п/п putBYTE() инкремент tx_counter0 идет самым последним, так что, вроде, ни о какой атомарности и необходимости запрещать прерывания речи не идет. Хотя ХЗ.
HELP!!!
PS. Вся оптимизация выключена. Даже не LOW, а NO. Хотя при LOW-уровне было тоже самое.