Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Опять UART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
aag
Тема уже забитая, но вот такой вопрос появился.

имеется код

Код
#include <msp430x16x.h>

#pragma vector=USART0RX_VECTOR
__interrupt void RxD()
{
    int byte = RXBUF0;
    DoSomething();
}

int main()
{
  WDTCTL = WDTPW + WDTHOLD;

  P3SEL = 0x30;

  U0CTL = CHAR;    // Установить длину данных - 8 бит
  UTCTL0 = 0x20;  // Источник тактирования ACLK

  U0BR0 = 0x03
  U0BR1 = 0x00;
  U0MCTL = 0x4A;

  // Включить модуль USART через SFR (прием и передача)
  ME1 |= (UTXE0 | URXE0);

  // Разрешить прерывания по приему
  IE1 |= URXIE0;

  // Очищаем SWRST бит
  U0CTL &= ~SWRST;

  _EINT();

  _BIS_SR(LPM0_bits | GIE);
}

стабилизирующий резонатор имеет частоту 32768 Гц. В Отладчике ставлю брейкпоинт в теле прерывания RxD(), чтобы отследить значения принятых данных. Данные не совпадают с теми, что отправляю с компьютера (скорость 9600). С четностями и стоповыми битами ошибок нет 100%.

Если назначить U0BR0 = 0x1b, U0MCTL = 0x03 (для скорости 1200 бод, на компьютере скорость соответственно тоже меняется), то все нормально работает.

А вопрос почему? в книжке написано, что при такой передаче ошибка составляет 15%. разве это много?


И еще: если использовать резонатор с бОльшей частотой (скажем 2 МГц), то U0BR0 и U0BR1 расчитываются из соотношения (частота резонатора) / скорость. А как расчитывается значение U0MCTL? Да и вообще для чего этот регистр нужен. Дайте, кто-нибудь ссылку, плз.

[добавлено]
Если использовать резонатор 2 МГц, конденсаторами какой емкости его лучше снабдить?
rezident
Во-первых инициализация UART у вас некорректная.
Код
P3SEL = 0x30;
U0CTL = SWRST;  // <- это обязательно требуется перед инициализацией UART
U0CTL |= CHAR;    // Установить длину данных - 8 бит
UTCTL0 = SSEL0;  // Источник тактирования ACLK
U0BR0 = 0x03;
U0BR1 = 0x00;
U0MCTL = 0x4A;
// Включить модуль USART через SFR (прием и передача)
ME1 |= (UTXE0 | URXE0);
// Очищаем SWRST бит
U0CTL &= ~SWRST;
// Разрешить прерывания по приему
IE1 |= URXIE0;

Во-вторых, с чего вы взяли, что у вас ошибка 15% составляет? Вы используете модулятор U0MCTL = 0x4A, который уменьшает ошибку до приемлимой величины (примерно до 4%). См. приложенный файл, который позволяет рассчитать значения для регистров USART при заданной частоте тактирования и скорости передачи.
Вообще же ошибка 15% конечно же недопустимо большая. При формате передачи "старт+8бит+стоп" максимальная накопленная ошибка не должна превышать 5,5% (0,5/9*100%).
P.S. величина нагрузочных конденсаторов кварцевого резонатора определяется его собственными характеристиками и доп. схемной емкостью. Для широко используемого часового кварца с CL=12.5пФ нужны доп. конденсаторы по 12пФ. Для многих высокочастотных кварцев можно ставить доп. конденсаторы 15-18пФ.
aag
Хм. странно все это:

В доке на ьыз написано, что UCTLx и UTCTLx можно менять только когда выставлен флаг SWRST. Так вот у меня наоборот все - если перед инициализацией uart написать
U0CTL = SWRST;
то ничего не работает (прерывание не срабатывает). а если не писать, тогда прерывание срабатывает, но принятый байт неправильный.

Попробовал разные кварцы: 2 Мгц, 1 Мгц, 100 кГц, 32 кГц (регистры естественно пересчитывал с помощью приложеного вами файла), uart так и не заработал sad.gif

Складывается впечатление, что частоты кварцев не те, которые на них написаны
rezident
Цитата(aag @ Aug 5 2007, 09:05) *
В доке на ьыз написано, что UCTLx и UTCTLx можно менять только когда выставлен флаг SWRST. Так вот у меня наоборот все - если перед инициализацией uart написать
U0CTL = SWRST;
то ничего не работает (прерывание не срабатывает). а если не писать, тогда прерывание срабатывает, но принятый байт неправильный.

Это явно указывает на то, что проблема не в кристалле, а в вашей программе.
Цитата(aag @ Aug 5 2007, 09:05) *
Попробовал разные кварцы: 2 Мгц, 1 Мгц, 100 кГц, 32 кГц (регистры естественно пересчитывал с помощью приложеного вами файла), uart так и не заработал sad.gif

Складывается впечатление, что частоты кварцев не те, которые на них написаны

Скорее всего вы наступили на другие типовые грабли при инициализации источников тактирования smile.gif
Приведенный ниже код для кристалла MSP430 с двумя кварцами XT1=32768Гц, XT2=7327,8кГц
Код
// Инициализация источников тактирования ACLK, MCLK, SMCLK
#pragma vector=NMI_VECTOR
#pragma type_attribute=__interrupt
void osc_fault(void)
{ BCSCTL2=SELM_0+DIVM_0+DIVS_0;                   //сначала перейдем на такт. DCO
  BCSCTL1=DIVA_0+RSEL2+RSEL1+RSEL0;               //ACLK=XT1/1=32768кГц
  DCOCTL=DCO0+DCO1+DCO2;                          //DCO около 6МГц
  while ((IFG1&OFIFG)!=0) IFG1&=~OFIFG;           //Ожидаем стабилиз. колебаний
                                                  //кварца XT2
  BCSCTL2=SELM_2+DIVM_0+SELS+DIVS_0;              //MCLK=XT2/1=7327,8кГц,
                                                  //SMCLK=XT2/1=7327,8кГц
  IE1|=OFIE;                                      //разр. прерывания от детектора
}

#pragma type_attribute=__task
void main(void)
{
  WDTCTL=WDTPW+WDTHOLD;                           //остановим WDT
  IFG1|=OFIFG;                                    //установим принудительно флаг OFIFG
  IE1=OFIE;                   //разрешим прерывание от детектора ошибки кварц.резонатора
...
...
...
}
jorikdima
Цитата(aag @ Aug 5 2007, 07:05) *
Хм. странно все это:

В доке на ьыз написано, что UCTLx и UTCTLx можно менять только когда выставлен флаг SWRST. Так вот у меня наоборот все - если перед инициализацией uart написать
U0CTL = SWRST;
то ничего не работает (прерывание не срабатывает). а если не писать, тогда прерывание срабатывает, но принятый байт неправильный.



Вы уверены, что разрешаете прерывания с USART ПОСЛЕ того, как убираете SWRST? В отладчике после инциализации проверьте разрешены ли прерывания и прочие настройки
aag
Именно так. Все в строгой последовательности. Поэтому мне и кажется, что дело не в программе, а связке кварц-конденсаторы.
Перепробовал различные емкости (от 5 до 30 пф), результат один и тот же: прерывание происходит, но в RXBUF0 оказывается не то, что отправлено с компьютера. Дело скорее всего в скорости приема/передачи, но вот только никак не могу понять, почему она не соответствует ожидаемой? или емкости тут не причем совсем?

С источниками тактирования пока еще разбираюсь... просто в примерах от ti.com перед инициализацией uart-а ничего подобного не написано, вот и думаю как же так...
VAI
Цитата
Дело скорее всего в скорости приема/передачи, но вот только никак не могу понять, почему она не соответствует ожидаемой?

Выведите MCLK на ножку и посмотрите ее осциллографом...
Как это сделать, см. примеры или даташит.
aag
Посмотрел осциллографом, что же происходит на плате...

На одном из выходов кварца постоянно 2 В, на втором - постоянно десятая часть вольта. то есть получается, что кварцы не заводяться. прямо мистика какая-то...
aag
Не знаю в чем прикол был, но... создал новый проект, переписал программу заного. и все заработало smile.gif
jorikdima
Поздравляю. Но программа то отличается от того что было?
aag
Отличаются ли программы?

Огромное спасибо за вопрос!! На первый взгляд один в один (только в рабочей сначала инициализируется uart, а потом все остальное, а в нерабочей uart последним инициализировался). Но при детальном сравнении нашел ошибку smile.gif оказывается в нерабочей программе значения U0BR0 и U0BR1 местами поменял (при расчете скорости перепутал старший и младший байты). Блин, день убил из-за такой оплошности.

а вот почему кварцы отзываться стали до сих пор понять не могу (но теперь уже все равно, раз заработали)
rezident
Цитата(aag @ Aug 7 2007, 17:22) *
а вот почему кварцы отзываться стали до сих пор понять не могу (но теперь уже все равно, раз заработали)

- наконец попали с номиналами нагрузочных конденсаторов,
- смотрели сигналы щупом без делителя.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.