Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MSP430F449 UART работает только на 19200
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
ArtemTom
Чип MSP430F449IPZ, кварцевый резонатор PK-206 32.768MHz.

Комп <-RS232-> MSP430F449 <-> Внешнее устройство
С компа передаются данные на внешнее устройство через плату с MSP, внешнее устройство отправляет по запросу данные назад на ПК.
В программе начинаю так и все работает:
Код
#include <msp430x44x.h>

#define P1ON 0x90
#define P2ON 0x60
#define DTR1 0x02
#define DTR2 0x01

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;

// FLL module
  FLL_CTL0 |= XCAP0PF;                
  FLL_CTL1= XT2OFF;                      //SMCLK - on, XT2 - off, MCLK - DC0CLK, SMCLK -DCOCLK, ACLK devider 1
  FLL_CTL0 = DCOPLUS;
  SCFQCTL = 128-1;                      
  SCFI0 = FLLD_2 +FN_2;                // DCO 1.4 - 12 MHz (FLLD_2 +FN_2)
// FLL module

// Порты на комп
  UCTL0=SWRST;
  UTCTL0 = SSEL1;          // UCLK = SMCLK
  UBR10 = 0x01;              // 8MHz 19200
  UBR00 = 0xA0;             // 8MHz 19200
  UMCTL0 = 0xBB;           // 8MHz 19200
  UCTL0 =  0x10;             // 8n1
  P2SEL |= 0x30;             // P2.4,5 = USART0 TXD/RXD
  P2DIR |= 0x10;             // P2.4 output
  ME1 |= UTXE0 + URXE0;   // вкл USART0 TXD/RXD
  UCTL0 &= ~SWRST;
  IE1 |= URXIE0;            //  вкл USART0 RX interrupt

//Внешнее устройство
  UTCTL1 = SSEL1;           // UCLK = SMCLK
  UBR11 = 0x01;             // 8MHz 19200
  UBR01 = 0xA0;             // 8MHz 19200
  UMCTL1 = 0xBB;            // 8MHz 19200
  UCTL1 =  0x10;            // 8n1
  P4SEL = 0x03;             // P4.0,1 = USART1 TXD/RXD
  P4DIR = 0xFD;             // P4.1 output
  ME2 |= UTXE1 + URXE1;     //  USART1 TXD/RXD
  IE2 &= ~0x30;             // откл RxTx interrupts

  P4OUT = 0x50;             // откл RX and TX

  BTCTL = BT_ADLY_125;      // BT_fLCD_DIV128
  SVSCTL = 0x70;            // SVS 2.65 volt

  P1IE = DTR1+DTR2;       // вкл INT at port 1 and port 2
  IE2 |= BTIE;              // вкл basic timer
  WDTCTL = WDT_ARST_1000;   // Start WDT (1sec)
  IE1 |= 0x01;              // вкл WDT interrupt;

  _EINT();
}

#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
    IFG1 &= ~URXIFG0;    
    while ((IFG2 & UTXIFG1) == 0);
    TXBUF1 = RXBUF0;
}

#pragma vector=UART1RX_VECTOR
__interrupt void usart1_rx (void)
{
    IFG2 &= ~URXIFG1;    
    while ((IFG1 & UTXIFG0) == 0);
    TXBUF0 = RXBUF1;
}

#pragma vector=BASICTIMER_VECTOR
__interrupt void RTC(void)
{
  IFG2 &= ~BTIFG;
  // Reset WotchDog Timer
  WDTCTL = WDT_ARST_1000;
}


Пытаюсь менять строки:
Код
UBR10 = 0x01;              // 8MHz 19200
UBR00 = 0xA0;             // 8MHz 19200
UMCTL0 = 0xBB;           // 8MHz 19200


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

MrYuran
Цитата(ArtemTom @ Jun 21 2010, 10:58) *
Пробовал но нескольким файлам расчетов этих параметров.
Наверно затупил где-то?

Наверняка.
У меня 115200 от 2МГц спокойно работало на 149-м, без всяких выкрутасов.
Не думаю, чтобы в 449 что-то сильно поменялось.
Xenia
Цитата(ArtemTom @ Jun 21 2010, 10:58) *
Наверно затупил где-то?

Так у вас же ОЖИДАНИЯ торчат в процедурах обработки прерываний! - Вещь невиданная. И еще хотите, чтобы прерывания обрабатывались с большой скоростью.
ArtemTom
Код
while ((IFG2 & UTXIFG1) == 0);

Эти чтоль?
Как по мануалу, ждём Ready. Да и не в большой скорости дело, просто не могу настроить скорость отличную от 19200. Хотя может быть проблема и во внешнем устройстве.
MrYuran
Цитата(ArtemTom @ Jun 21 2010, 13:54) *
Код
while ((IFG2 & UTXIFG1) == 0);

не могу настроить скорость отличную от 19200.

Ну так приведите пример, для какой скорости чего настраивали.
Хотя я не понимаю, какие могут быть проблемы - входную тактовую частоту UART поделить на битрейт и разнести по двум байтам

Цитата(Xenia @ Jun 21 2010, 12:55) *
Так у вас же ОЖИДАНИЯ торчат в процедурах обработки прерываний!

Это может повлиять на задержки между байтами, но не на формат кадра - то есть были бы пропуски, но между правильными символами
Сергей Борщ
Цитата(ArtemTom @ Jun 21 2010, 09:58) *
кварцевый резонатор PK-206 32.768MHz.
А разве кто-то обещал, что проц будет работать с такой частотой?
Xenia
Цитата(MrYuran @ Jun 21 2010, 14:14) *
Это может повлиять на задержки между байтами, но не на формат кадра - то есть были бы пропуски, но между правильными символами

Это влияет на учет числа принимаемых/отсылаемых байт. Пока МК в прерывании висит на ожидании, новые поступающие по UART байты не учитываются, пропадая всуе. А потом говорится, что байты де пропали.
Если ожидания там нет, то и ожидать нечего. Советую ради теста закоментарить ожидания и посмотреть как это скажется на скорости.

А вообще-то программы взаимной пересылки между обоими UART'ами так не пишут. Никаких ожиданий быть не должно, а нужна буферизация. Т.е. в прерывании от поступления байта этот байт пишется в (самодельный) FIFO, из которого потом второй UART тоже по прерыванию (на этот раз от опустошения передатчика) забирает байты для передачи. В случае необходимости перекрестной пересылки - заводят два таких буфера для очередей на передачу для каждого из UART. И перехватывают 4 прерывания - по готовности передатчика и наличию в приемнике по каждому UART. Принимаемые байты пишутся в буфера очередей с одновременным разрешением прерывания по опустошению передатчика своего соседа. А в своем прерывании по опустошению передатчика забираешь байт из своего буфера и отсылаешь его. Если же буфер пуст, то маскируешь собственное прерывание по опустошению. Разрешать его будет сосед, когда запишет для тебя что-то в буфер. Где-то так.
ArtemTom
Цитата(Сергей Борщ @ Jun 21 2010, 14:19) *
А разве кто-то обещал, что проц будет работать с такой частотой?
Ну тут я опечатался немного, не MHz конечно.

Пробовал так, для 9600
Код
  UBR10 = 0x03;        
  UBR00 = 0x41;          
  UMCTL0 = 0xBB;

Цитата
программы взаимной пересылки между обоими UART'ами так не пишут.
Да я пока для примера, получится, буду обделывать. Сейчас постарался поменьше ненужного кода пихать.
MrYuran
Цитата(ArtemTom @ Jun 21 2010, 14:53) *
Пробовал так, для 9600
Код
  UBR10 = 0x03;        
  UBR00 = 0x41;          
  UMCTL0 = 0xBB;

Вроде никакого криминала, хотя при таком соотношении частот можно смело занулять модулятор.
Скорее всего, дело в PC-шной части.
Хотя...
Сейчас некогда разбираться, а вы случайно половинки регистров от разных УАРТов не перемешали?
ArtemTom
Да вроде ничего не перемешивал на 19200 все же работает.
Ладно, вроде все правильно, должно работать, наверно дело в чем то другом. Думал может кто подскажет из-за чего всякая лабуда в ком-порт может поступать, как-будто скорость не ту указал. Щас пошаманю немного может получится чего.
rezident
ArtemTom, у вас тактовая частота SMCLK выбрана 12МГц, вы от нее же и тактируете UART, так почему же расчетная частота для тактирования у вас 8МГц? Это раз.
Во-вторых, изучите внимательно раздел, где описаны источники прерываний USART и условия при которых сбрасываются флаги прерываний. Никакие опросы флагов в прерывании не требуются. Переход по вектору прерывания уже является фактом наличия установленного флага прерывания. Для передатчика этот же факт перехода по вектору прерывания является причиной для автоматического сброса флага данного прерывания. Программно сбрасывать флаг не нужно. Так можно потерять следующее прерывание. Для сброса же флага прерывания приемника UASRT есть два условия: чтение буфера приемника, либо программный сброс флага.
MrYuran
Цитата(ArtemTom @ Jun 21 2010, 15:15) *
Да вроде ничего не перемешивал на 19200 все же работает.

Потому что настройки одинаковые.
А если вы берёте один байт от новой скорости, а другой - от старой - получится полная каша.
Проверьте для успокоения. Похоже на то.
ArtemTom
Цитата(rezident @ Jun 21 2010, 15:15) *
у вас тактовая частота SMCLK выбрана 12МГц, вы от нее же и тактируете UART, так почему же расчетная частота для тактирования у вас 8МГц? Это раз.
Я думал что 8MHz указал.
В примерах правда такой вариант есть:
Код
FLL_CTL0 |= DCOPLUS + XCAP18PF;                // DCO+ set, freq = xtal x D x N+1
SCFI0 |= FN_4;                                // x2 DCO freq, 8MHz nominal DCO
SCFQCTL = 121;                              // (121+1) x 32768 x 2 = 7.99 MHz
Можете ткнуть пальцем почему в моём случае 12 MHz, а то я видимо не разобрался?
Если можно, разъясните пожалуйста по подробней про UMCTL0, не разберусь с этой модуляцией, как её указывать?

Цитата
а вы случайно половинки регистров от разных УАРТов не перемешали?
Проверьте для успокоения. Похоже на то.
Тут я видимо тоже не понял. Как проверить?

Да, флаги я тоже зря наставил.
rezident
Цитата(ArtemTom @ Jun 21 2010, 18:35) *
Можете ткнуть пальцем почему в моём случае 12 MHz, а то я видимо не разобрался?
А я на ваши комментарии ориентировался, лень было проверять smile.gif Если очень нужно, то давайте вместе разберемся.
Цитата(ArtemTom @ Jun 21 2010, 18:35) *
Если можно, разъясните пожалуйста по подробней про UMCTL0, не разберусь с этой модуляцией, как её указывать?
Когда-то VAI выкладывал здесь экселевский файлик для расчета параметров UART. См. приложение.
MrYuran
Цитата(ArtemTom @ Jun 21 2010, 16:35) *
Тут я видимо тоже не понял. Как проверить?

По даташиту.
Всё нормально.
Цитата
UART0
Transmit buffer UTXBUF0 077h
Receive buffer URXBUF0 076h
Baud rate UBR10 075h
Baud rate UBR00 074h

Modulation control UMCTL0 073h
Receive control URCTL0 072h
Transmit control UTCTL0 071h
UART control UCTL0 070h

Я думал, что UBR10 и UBR01 можно случайно попутать..
ArtemTom
Спасибо за файл, встречал его уже в темах.
Я разобрался с UBR10 и UBR01, а вот с модуляцией не очень.
Для 7995392Mhz получаем при 19200:
UBR00 & UBR10: 416
Т.е. 0хA0 и 0х01 можно записать в UBR00 & UBR10
Для модулятора получаем: 1326
А что записать в UMCTL0? 0x2E?
Ещё в файле подразделяется на Transmitter Hardware Corrections (Time to end of each bit) и Receiver Software Corrections (Start bit is time to half way, successive bits also to half way), отличаются как я вижу только значениями модуляции?
А какая между ними разница? У меня же и на прием и на передачу работают? Что куда писать?

Цитата
Если очень нужно, то давайте вместе разберемся.
Я делал так что: 128*32768*2=8388608MHz;
А SCFI0 = FN_2 - это диапазон от 1.4 до 12MHz.
Хотя может и путаю что-то.
rezident
Цитата(ArtemTom @ Jun 22 2010, 12:07) *
А какая между ними разница? У меня же и на прием и на передачу работают? Что куда писать?
Выбирайте число для модулятора UART в зависимости от того, какие пакеты у вас длиннее: на приеме или на передаче. Если не знаете, то выбирайте любое из получившихся.
Цитата(ArtemTom @ Jun 22 2010, 12:07) *
Я делал так что: 128*32768*2=8388608MHz;
А SCFI0 = FN_2 - это диапазон от 1.4 до 12MHz.
В зависимости от делителей (N и D=FLLD_x>>6) выходная частота fDCO может быть выше опорной в кратное число раз. Нужно стремиться чтобы эта частота (fDCO) попадала примерно в середину выбранного с помощью бит FN_x диапазона DCO и в то же время не превышала максимально допустимую. У вас в программе N=127 и D=2. Следовательно fDCO получается около 2*128*32768=8388608Гц и значит диапазон выбран не совсем верно. Нужно устанавливать FN_3 - 2 to 17.9MHz. Cледует заметить, что частота 8388608MHz для ядра (MCLK) выше, чем максимальная рекомендованная в datasheet (8MHz@3.6V).
Кроме всего вышеперечисленного, после сброса или подачи питания нужно выждать, чтобы установилась амплитуда колебаний часового генератора LFXT1. Т.к. он "раскочегаривается" довольно медленно - сотни мс.Для этого после подачи питания следует подождать сброса флага LFOF в регистре FLL_CTL0. А если используете прерывание Oscillator fault interrupt, то перед разрешением этого прерывания еще и флага OFIFG, сбрасывая его программно в цикле опроса
О работе модуля FLL+ можно почитать на русском в Компеловской книжке Семейство микроконтроллеров MSP430x4xx: руководство пользователя, которая является переводом одной из первых ревизий MSP430x4xx Family User's Guide - slau056d. Раньше она была доступна для скачивания в библиотеке Компела у них на сайте. Но сейчас видимо этот раздел прикрыли или перелопатили сайт так, что я ее не нашел. Могу выложить книгу для вас на какой-нибудь обменник. Или смотрите черновики перевода на сайте gaw.ru.
ArtemTom
rezident, большое спасибо, буду разбираться. Книга у меня есть.
ArtemTom
Интересно а можно ли как-то в процессе программы изменить настройки этих параметров скорости, если что-то не так?
Код
UBR10 = 0x01
UBR00 = 0xA0
UMCTL0 = 0xBB

Как-то определить, что пришло не то что надо и поменять значения в этих регистрах? Ошибки же UART'a никакой не происходит если параметры не угадал, и флаг не выставляется или происходит что-то?
Dog Pawlowa
Цитата(ArtemTom @ Jul 8 2010, 15:25) *
Как-то определить, что пришло не то что надо и поменять значения в этих регистрах? Ошибки же UART'a никакой не происходит если параметры не угадал, и флаг не выставляется или происходит что-то?

Вы все-таки решили учиться по советам на форуме вместо чтения документации? wink.gif
При несовпадении частоты обычно происходит ошибка фрейма.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.