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

 
 
> UART MSP430F1611, Не могу осилить приём.
/Sergeant/
сообщение Apr 22 2008, 08:02
Сообщение #1





Группа: Новичок
Сообщений: 4
Регистрация: 12-07-07
Пользователь №: 29 075



Добрый день. Изучил весь фак и все темы про UART, посмотрел примеры производителя, но так и не понял в чём у меня проблема.
Суть такова: есть некий чёрный ящик(как он устроен - не знаю). Обмениваюсь с ним по UART со скоростью 8889 бит/с. В ответ на определённую последовательность байт, он(ЧЯ) выдаёт свою последовательность. У меня выходит так: шлю по TXD байты - всё хорошо, в ответ приходит тоже последовательность байт - смотрел осциллографом, но RD буффер получает только последний байт. Вернее выставляется флаг ОЕ, то есть все байты "наслаиваются" друг на друга, не вызывая прерывания. И только после последнего байта срабатывет процедура обработки прерывания.

Вот кусок кода:

Код
#include <io430x16x.h>
#include <iostream.h>
#include <intrinsics.h>

static char string1[20];
char i;
char j = 0;

void Init()                     // Начальные установки
{
  WDTCTL = WDTPW+WDTHOLD;       // Отключаем WDT
  __enable_interrupt();       // Разрешение прерываний
  
  P5DIR = 0xFE;                // Р5.0 - ввод, остальные - вывод
  P6DIR = 0xFF;                 // Неиспользуемые выводы
  P6OUT = 0xFF;
  P3SEL = 0x30;           // Р3.4 и Р3.5 - в режиме UART
  P3DIR = 0xDF;                // P3.5: на ввод, остальные: на вывод
  
// Устанавливаем MCLK, SMCLK и выводим SMCLK на Р1.4
  BCSCTL1 = 0x00;            // "0" - включение ХТ2
  P1DIR = 0x9C;                 // P1.4(F8МГЦ), P1.3(WR), P1.2(RD#), P1.7(ВКЛ) конфигурируем на вывод
  P1OUT = 0x00;
  P1SEL = 0x10;                // P1.4 = SMCLK
  
  unsigned int i;
  do
  {
    IFG1 &= ~OFIFG;             // Очищаем флаг прерывания ошибки генератора OFIFG
    for (i = 0xFF; i > 0; i--); // Временная задержка (~50мкс)
  }
  while ((IFG1 & OFIFG));       // Флаг OFIFG ещё установлен?
  BCSCTL2 = SELM_2;             // Выбираем MCLK - биты 7-6 регистра BCSCTL2
                                // в конфигурации "10" - XT2CLK
  BCSCTL2 |= SELS;              // Выбор SMCLK: ХТ2CLK
}

/*----------------Обработка прерываний по приёму-----------------------*/
#pragma vector = USART0RX_VECTOR
__interrupt void Uart_RX(void)          // Обработка прерываний на приём от UART
{
  //IE1 &= ~URXIE0;       // Запрещение прерывания RX
  string1[j++] = U0RXBUF;
  //IE1 |= URXIE0;    // Разрешение прерывания RX
}
/*---------------------------------------------------------------*/

int main( void )
{
  Init();

  ME1 = UTXE0+URXE0;  // Разрешаем передачу/приём UART0
  U0CTL = CHAR+SWRST; // Инициализация(ресет) UART0
  U0TCTL = 0x20 /*+ URXSE*/;        // Выбор тактовой частоты SMCLK
  U0BR0 = 0x84;         //  Выбираем делитель тактовой частоты - 0х384
  U0BR1 = 0x03;         //
  U0CTL &= ~SWRST;    // Вкл UART - снимаем RST
  IE1 |= URXIE0;             // Прерывание по приёму
  
  /*---Начинается передача последовательности байт---*/
  __no_operation();
  while(!IFG1_bit.UTXIFG0);   // Ждём, пока освободится буфер на передачу
  U0TXBUF = 0x55;
  while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0xAD;
    while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0x01;
  while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0x00;
  while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0x00;
  while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0x10;
  while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0xEE;  
    while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0x55;
  while(!IFG1_bit.UTXIFG0);
  U0TXBUF = 0x92;
   __no_operation();
/*---Передачу закончили, ждём ответ---*/
   while(1)  {}
}


Запись в строку здесь взята из примера TI, вообще будет не так, но главное, что не срабатывает прерывание после приёма каждого байта. Или же здесь получается, что приходят скопом прерывания от всех байтов и обрабатывается только последнее? Но с отключением прерываний(закоменарены вкл/откл) выходит всё так же.
Передача временно сделана по опросу флага, но она работает и меня пока не беспокоит.

ЗЫ заранее прошу извинить, если еть очевидные косяки, ибо программированием проца занимаюсь недавно.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aag
сообщение Apr 22 2008, 08:50
Сообщение #2


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

Группа: Свой
Сообщений: 81
Регистрация: 8-04-06
Из: Новосибирск
Пользователь №: 15 939



Скорость точно 8889 бит/с ?

Такое ощущение, что скрость другая, поэтому происходит рассинхронизация...

Вот такой пример попробуйте:
Код
#include <msp430x16x.h>

char rx_buffer[64]; //буффер на прием
int rx_size;  // размер буффера

char tx_buffer[32]; //буффер на передачу
int tx_size; //размер буффера
int tx_sent; //номер отправленного байта

int main()
{
  WDTCTL = WDTPW + WDTHOLD; //отключаем сторожевой таймер

  P3DIR = 0x0F;
  P3SEL = 0x30; // 00110000  (ноги 3.4 и 3.5 - uart)
  
  BCSCTL1 |= XTS;
  // тактирование происходит от кварцевого резонатора, подключенного к выходам XIn, XOut (первый резонатор)
  
  UCTL0 = SWRST;
  UCTL0 |= CHAR;
  UTCTL0 = SSEL0;
  UBR10 = 0x01;  //  эти числа выбранны для скорости 9600
  UBR00 = 0xA0;  //  при частоте резонатора 4 МГц
  UMCTL0 = 109;  //  (в вашем случае их надо изменить)
  ME1 |= (UTXE0 | URXE0);
  UCTL0 &= ~SWRST;
  IE1 |= URXIE0;
  IE1 |= UTXIE0;

  rx_size = 0;
  tx_sent = 0;
  tx_buffer[0] = 0x55;  // записываем байты,
  tx_buffer[1] = 0xAD; // которые будем отправлять
  tx_buffer[2] = 0x01;
  tx_buffer[3] = 0x00;
  tx_buffer[4] = 0x00;
  tx_buffer[5] = 0x10;
  tx_buffer[6] = 0xEE;
  tx_buffer[7] = 0x55;
  tx_buffer[8] = 0x92;
  tx_size = 9; // будем отравлять 9 байт из буффера
  
  _BIS_SR(GIE);

  TXBUF0 = tx_buffer[tx_sent++]; // отправка первого (нулевого) байта

  for(;;);
}

#pragma vector=USART0RX_VECTOR
__interrupt void RxD(void)
{
  if (rx_size < 63)
    rx_buffer[rx_size++] = RXBUF0; // запись полученных байтов
}

#pragma vector=USART0TX_VECTOR
__interrupt void TxD()
{
  if (tx_sent < tx_size)
    TXBUF0 = ts_buffer[tx_sent++]; // передача байтов из буффера
  else
  {
    tx_sent = 0;
    tx_size = 0;
  }
}


Сообщение отредактировал aag - Apr 22 2008, 09:07
Go to the top of the page
 
+Quote Post
/Sergeant/
сообщение Apr 22 2008, 11:48
Сообщение #3





Группа: Новичок
Сообщений: 4
Регистрация: 12-07-07
Пользователь №: 29 075



Цитата(aag @ Apr 22 2008, 12:50) *
Скорость точно 8889 бит/с ?

Такое ощущение, что скрость другая, поэтому происходит рассинхронизация...

Вот такой пример попробуйте:
Код
int main()
{

...

  TXBUF0 = tx_buffer[tx_sent++]; // здесь какой-то глюк, tx_sent автоматически увеличивается на
                                                  // единицу, после того как сделал так: TXBUF0 = tx_buffer[tx_sent];
                                                  // стало на отправку работать правильно

  for(;;);
}

#pragma vector=USART0RX_VECTOR
__interrupt void RxD(void)
{
  if (rx_size < 63)
    rx_buffer[rx_size++] = RXBUF0; // запись полученных байтов
}

#pragma vector=USART0TX_VECTOR
__interrupt void TxD()
{
  if (tx_sent < tx_size)
    TXBUF0 = ts_buffer[tx_sent++]; // передача байтов из буффера
  else
  {
    tx_sent = 0;
    tx_size = 0;
  }
}


Такой пример попробовал(обозначил небольшой глюк выше), но всё по-прежнему - на проц приходит пакет байтов, но обрабатывать их он не желает. Скорость с которой приходят байты, судя по осциилографу, именно 8889 бит/с или очень близко к тому. Что там можно ещё наковырять? Значение модуляции менять? На какое?
Go to the top of the page
 
+Quote Post



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

 


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


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