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

 
 
 
Reply to this topicStart new topic
> Проблема с UART'ом
CSB
сообщение Nov 27 2006, 13:13
Сообщение #1


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



В симуляторе все работает отлично, но на железе передача идет одним коротким пакетом и затыкается (не устанавливается флаг готовности передатчика UART). Чего это может быть?

Сообщение отредактировал CSB - Nov 27 2006, 13:14
Go to the top of the page
 
+Quote Post
rezident
сообщение Nov 27 2006, 14:43
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Исходный код в студию!
Go to the top of the page
 
+Quote Post
CSB
сообщение Nov 27 2006, 15:02
Сообщение #3


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Что за... я же цеплял исходник!

Сейчас проверяю, а файлы не цепляются sad.gif

Код
#include  <msp430x12x.h>
#include  <stdlib.h>
#include  <data_type.h>

#define XTAL 8000000L
#define SIZE_MESSAGE 4    // длина входного сообщения, без учета заголовка сообщения
#define SIZE 10           // размер буферов FIFO

struct
{
    byte FIFO_full   : 1; // флаг переполнения FIFO
    byte end_receive : 1; // флаг окончания приема пакета данных
} status_flags;

// кольцевая очередь FIFO для передачи информации в ПК
typedef struct
{
    byte *const home;     // указатель на начало буфера
    byte *head;           // указатель на голову буфера
    byte *tail;           // указатель на хвост буфера
    byte *const end;      // указатель на конец буфера
} out_circular_buffer;

// кольцевая очередь FIFO для приема информации из ПК
typedef struct
{
    byte *const home;     // указатель на начало очереди
    byte *tail;           // указатель на хвост очереди
    byte *const end;      // указатель на конец очереди
} in_circular_buffer;

byte                    UART_out[SIZE];    // выходной буфер (от МК к ПК)
byte                    UART_in[SIZE];     // входной буфер (от ПК к МК)

in_circular_buffer      in_buffer =
{
    UART_in,
    NULL,
    UART_in + (SIZE - 1)
};

out_circular_buffer     out_buffer =
{
    UART_out,
    NULL,
    NULL,
    UART_out + (SIZE - 1)
};

byte UART_getchar();
void UART_putchar(byte value);

//-----------------------------------------------------------------------------------------------------------------------------------------------
void main(void)
{
    byte state;                 // текущее состояние конечного автомата
    volatile word ct;

    WDTCTL =   WDTPW            // Пароль для доступа к сторожевому таймеру
             + WDTHOLD;         // Останов сторожевого таймера

    IE1 |= OFIE;                // Разрешение прерывания при возникновении ошибки осцилятора

    // инициализация USART0: режим UART
    P3SEL |= 0x30;              // для ног P3.4,5 выбирается функция периферийного модуля USART0 TXD/RXD
    ME2 |= UTXE0 /*+ URXE0*/;       // Включение передачи и приема USART0
    UCTL0 |= CHAR;              // Контроль четности отключен; один стоповый бит; 8-разрядные даные;
    UTCTL0 |= SSEL0;            // UCLK = ACLK
    UBR00 = 0x45;               // 8 MHz 115200
    UBR10 = 0x00;               // 8 MHz 115200
    UMCTL0 = 0x00;              // 8 MHz 115200 modulation
    UCTL0 &= ~ SWRST;           // инициализация конечного автомата USART
    //IE2 |= URXIE0;              // разрешить прерывание при приеме

    // инициализация буферов FIFO
    out_buffer.head = out_buffer.tail = out_buffer.home;
    in_buffer.tail = in_buffer.home;

    _EINT();                    // Разрешить маскируемые прерывания

    //
    for (;;)
    {
        if (! status_flags.FIFO_full)
          UART_putchar('1');
/*
        for (ct = 0; ct < 0xFFFF; ct++);
        for (ct = 0; ct < 0xFFFF; ct++);
        for (ct = 0; ct < 0xFFFF; ct++);
        for (ct = 0; ct < 0xFFFF; ct++);
*/
    };
}

//-----------------------------------------------------------------------------------------------------------------------------------------------
#pragma vector = NMI_VECTOR
__interrupt void osc_fault(void)
{
//
// Прерывание при возникновении ошибки осциллятора
//

    volatile unsigned int i;

    BCSCTL1 |= XTS;             // ACLK = LFXT1 = HF XTAL - режим высокой частоты
    do
    {
        IFG1 &= ~ OFIFG;
        for (i = 0xFF; i; i--);    // Ожидание в течении ~50 мкс
    }
    while (IFG1 & OFIFG);    // Пока OFIFG установлен цикл будет повторяться, выход произойдет при стабилизации частоты
    BCSCTL2 |= SELM_3;          // MCLK = LFXT1 - источник тактирования для главного тактирования - XT1
    IE1 |= OFIE;                // Возобновить разрешение прерывания при возникновении ошибки осцилятора
}

//-----------------------------------------------------------------------------------------------------------------------------------------------
#pragma vector = UART0TX_VECTOR
__interrupt void usart0_tx(void)
{
//
//  Прерывание при передаче символа
//
    // Если буфер пуст, то запретим дальнейшие прерывания по флагу UTXIFG0
    if (out_buffer.head == out_buffer.tail)
    {
        status_flags.FIFO_full = 0;
        U0IE &= ~ UTXIE0;
    }
    else
    {
        TXBUF0 = *out_buffer.head;    // Cчитываем значение из головы буфера, пишем в UART это значение и увеличиваем
                                      //  указатель головы
        out_buffer.head++;

        // Если голова достигла конца буфера, то перемещаем указатель в начало буфера
        if (out_buffer.head > out_buffer.end)
          out_buffer.head = out_buffer.home;
    };
}

//-----------------------------------------------------------------------------------------------------------------------------------------------
void UART_putchar(byte value)
{
//
// Запись байта в буфер FIFO
//
    U0IE &= ~ (UTXIE0 + URXIE0);     // Запретим прерывания от UART

    // Если буфер не заполнен, то записываем в буфер value и сбрасываем FIFO_full
    if (   (out_buffer.tail == out_buffer.end && out_buffer.head == out_buffer.home)
        || (out_buffer.tail + 1 == out_buffer.head)
       )
      status_flags.FIFO_full = 1;
    else
    {
        *(out_buffer.tail) = value;
        status_flags.FIFO_full = 0;
        out_buffer.tail++;              // Увеличиваем указaтель хвоста очереди

        // Если хвост больше конца буфера, то вернем хвост в начало.
        if (out_buffer.tail > out_buffer.end)
          out_buffer.tail = out_buffer.home;
    };

    U0IE |= UTXIE0/* + URXIE0*/;         // Разрешим прерывания от UART
}
Go to the top of the page
 
+Quote Post
rezident
сообщение Nov 27 2006, 16:01
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Ну все правильно. Вызов прерывания с вектором UART0TX_VECTOR сбрасывает флаг UTXIFG0. А у вас по окончании пакета при выполняющемся условии
Код
if (out_buffer.head == out_buffer.tail)

в TXBUF0 ничего не записывается. Чтобы UTXIFG0 был установлен для вызова прерывания нужно либо его установить программно, либо что-то записать в TXBUF0.
Т.е. вместо (или вместе) с
Код
U0IE |= UTXIE0/* + URXIE0*/;         // Разрешим прерывания от UART

нужно выполнить
Код
IFG0 |= UTXIFG0;
Go to the top of the page
 
+Quote Post
VAI
сообщение Nov 27 2006, 16:29
Сообщение #5


Профессионал
*****

Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37



Выдрал из работающего проекта прием-передачу символов и свой кольцевой буфер.
При работе с буфером предприняты попытки разрешения конфликта одновременной записи в буфер принятого по прерыванию байта и считывания из этого же буфера.
Версия для работы без RTOS.
Прикрепленные файлы
Прикрепленный файл  1.zip ( 8.4 килобайт ) Кол-во скачиваний: 133
 


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
CSB
сообщение Nov 27 2006, 16:59
Сообщение #6


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



2rezident: спасибо за помощь. На железе посмотрю только завтра sad.gif
Поправочка: вместо IFG0 нужно IFG2. (это будущим поколения)

2VAI: спасибо за исходники.
Go to the top of the page
 
+Quote Post
rezident
сообщение Nov 28 2006, 10:18
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(CSB @ Nov 27 2006, 18:59) *
2rezident: спасибо за помощь. На железе посмотрю только завтра sad.gif
Поправочка: вместо IFG0 нужно IFG2. (это будущим поколения)

Сорри! В спешке промахнулся. Нужно IFG1 или IFG2. Зависит от конкретного типа кристалла MSP430.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 10:19
Рейтинг@Mail.ru


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