реклама на сайте
подробности

 
 
> Передача на UART1 (LPC2146)
meister
сообщение Dec 10 2007, 11:41
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484



Никак не могу сделать простую передачу на UART1.

Код
    CODE32

    EXTERN fwu_uart1_impl
    PUBLIC fwu_uart1_asm

fwu_uart1_asm: // я уж думал spurious interrupts мешали.
    SUB lr, lr, #4;
    STMFD sp!, {lr};
    MRS lr, SPSR;
    TST lr, #I_Bit;
    BNE fwu_uart1_asm_ret;

    BL fwu_uart1_impl;

fwu_uart1_asm_ret:
    LDMFD sp!, {pc}^;

//////////////////////////////////////

    struct my_dataseg_t
    {
        u8_t volatile tx;        
        bool volatile tx_ready;
        bool volatile tx_empty;
    };

    __no_init my_dataseg_t ds;

    unsigned const serSOURCE_THRE = 0x02;
    unsigned const serSOURCE_RX_TIMEOUT = 0x0C;
    unsigned const serSOURCE_ERROR = 0x06;
    unsigned const serSOURCE_RX = 0x04;
    unsigned const serINTERRUPT_SOURCE_MASK = 0x0F;

__arm void fwu_uart1_impl(void)
{
    switch (U1IIR & serINTERRUPT_SOURCE_MASK)
    {
    case serSOURCE_ERROR:
        ds.rx_error = true;
        ds.rx_ready = true;
        break;
        
    case serSOURCE_THRE:
        if (ds.tx_ready)
        {
            U1THR = ds.tx;
        }
        else
        {
            ds.tx_empty = true;
        }
        ds.tx_ready = false;            
        break;

    case serSOURCE_RX_TIMEOUT:
    case serSOURCE_RX:
        ds.rx = U1RBR;
        ds.rx_error = false;
        ds.rx_ready = true;
        break;

    default:
        break;
    }

    VICVectAddr = 0;
}

    void send_byte(u8_t B)
    {
        while (true)
        {
            __disable_interrupt();
            if (ds.tx_empty)
            {
                U1THR = b;
                ds.tx_empty = false;
                ds.tx_ready = false;
                __enable_interrupt();
                return;
            }
            else if (!ds.tx_ready)
            {
                ds.tx = b;
                ds.tx_empty = false;
                ds.tx_ready = true;
                __enable_interrupt();
                return;
            }
            else
            {
                __enable_interrupt();
                while (ds.tx_ready) { power_off(); }
            }
        }
    }

    void start_transmit(void)
    {
        U1IER = 0;
        line_driver(true);
        
        ds.tx_ready = false;
        ds.tx_empty = true;
      
        U1FCR_bit.FCRFE = 1;  // FIFO Enable
        U1FCR_bit.TFR = 1;    // TX FIFO RESET
        U1IER_bit.THREIE = 1; // THRE Interrupt Enable
        U1TER_bit.TxEn = 1;            
    }

    void power_off(void) {}

////////////////////////////////////
Вот так передаю.

        start_transmit();

        u8_t const buf[] = {1, 2, 3, 4, 5, 6, 7, 8, '?'};
        for (u8_t const * i = BEGIN_OF_ARY(buf); i != END_OF_ARY(buf); ++i)
        {
            send_byte(*i);
        }

        while (true) {} // тут останавливается и ничего больше не передается. [/font]


Передается только первый байт. Причем в ds.tx остается последний передаваемый байт - '?'. Если отладчик поставить на U1THR = b; - он там остановится. Если нажимать "продолжить" - передаются все байты. Подскажите пожалуйста -- с утра голову ломаю.

Сообщение отредактировал meister - Dec 10 2007, 12:14
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 6)
Alex03
сообщение Dec 10 2007, 13:40
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Если в 214х UART такой же как и в более младших (а это скорее всего так ибо совместимость с '550) то как минимум вот сюда посмотрите:
Код
        U1FCR_bit.FCRFE = 1;  // FIFO Enable
        U1FCR_bit.TFR = 1;    // TX FIFO RESET


FCR не доступен по чтению, поэтому чтение/модификация/запись к нему не катит.
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 10 2007, 14:14
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Код
void send_byte(u8_t B)
    {
        while (true)
        {
            __disable_interrupt();
            if (ds.tx_empty)
            {
                U1THR = b;
                ds.tx_empty = false;
                ds.tx_ready = false;
                __enable_interrupt();
                return;
            }
            else if (!ds.tx_ready)
            {
                ds.tx = b;
                ds.tx_empty = false;
                ds.tx_ready = true;
                __enable_interrupt();
                return;
            }
            else
            {
                __enable_interrupt();
                while (ds.tx_ready) { power_off(); }
            }
        }
    }


Возможно, причина в том, что вы разрешаете прерывания через какое то время после "U1THR = b" и прерывание по опустошению FIFO передатчика просто пропускается, в результате у вас передается только один символ - 'b'.

Цитата(Alex03 @ Dec 10 2007, 16:40) *
Если в 214х UART такой же как и в более младших (а это скорее всего так ибо совместимость с '550) то как минимум вот сюда посмотрите:
Код
        U1FCR_bit.FCRFE = 1;  // FIFO Enable
        U1FCR_bit.TFR = 1;    // TX FIFO RESET


FCR не доступен по чтению, поэтому чтение/модификация/запись к нему не катит.


И что, если не доступен, а что не так здесь?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 10 2007, 15:36
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Юрий Санвальд @ Dec 10 2007, 16:14) *
И что, если не доступен, а что не так здесь?
То, что U1FCR_bit.FCRFE = 1; эквивалентно U1FCR |= ( 1<< FCRFE);, а поскольку регистр недоступен для чтения - в результате в него запишется что-то непредсказуемое с единичкой в бите FCRFE. Поскольку стандартные заголовочные файлы не содержат описания битов, либо дописывать свои и делать RS232_UART->FCR = (0 << UART_RTLS) | (1 << UART_TFR) | (1 << UART_RFR) | (1 << UART_FCRFE); // enable and reset FIFO, 4-bytes int level
либо писать
Код
{
         __uartfcriir_bits Tmp;
        Tmp.FCRFE = 1;        // Enable FIFO
        Tmp.RFR = 1;        // Reset Rx FIFO
        Tmp.TFR = 1;        // Reset Rx FIFO
        Tmp.RTLS = 0;        // 1 byte FIFO
        U1FCR_bit = Tmp;
    }


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 10 2007, 16:52
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Цитата(Сергей Борщ @ Dec 10 2007, 18:36) *
То, что U1FCR_bit.FCRFE = 1; эквивалентно U1FCR |= ( 1<< FCRFE);, а поскольку регистр недоступен для чтения - в результате в него запишется что-то непредсказуемое с единичкой в бите FCRFE.


Мдя, чето я не подумал... 05.gif
Go to the top of the page
 
+Quote Post
Alex03
сообщение Dec 11 2007, 04:35
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(Сергей Борщ @ Dec 10 2007, 20:36) *
То, что U1FCR_bit.FCRFE = 1; эквивалентно U1FCR |= ( 1<< FCRFE);, а поскольку регистр недоступен для чтения - в результате в него запишется что-то непредсказуемое с единичкой в бите FCRFE.


Я бы сказал что предсказуемость там всё же есть, и
Код
U1FCR_bit.FCRFE = 1
эквивалентно
Код
U1FCR = U1IIR | ( 1<< FCRFE)

Ибо IIR и FCR находятся по одному адресу, только один по чтению а второй на запись. smile.gif

То же самое с RBR/THR, да ещё по биту DLAB регистры "мультиплексируются".
Go to the top of the page
 
+Quote Post
SanvaldYV
сообщение Dec 11 2007, 07:47
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371



Во всяком случае, у меня в проекте при инициализации UART были строки
Код
  U1FCR_bit.FCRFE = 1;  
  U1FCR_bit.RTLS = 0;


и никаких проблем не возникало biggrin.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th July 2025 - 06:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01432 секунд с 7
ELECTRONIX ©2004-2016