|
|
  |
Опять UART, нужна подсказка |
|
|
|
Aug 3 2007, 13:37
|

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

|
Тема уже забитая, но вот такой вопрос появился. имеется код Код #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 МГц, конденсаторами какой емкости его лучше снабдить?
Сообщение отредактировал aag - Aug 3 2007, 13:38
|
|
|
|
|
Aug 3 2007, 16:48
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Во-первых инициализация 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пФ.
|
|
|
|
|
Aug 5 2007, 03:05
|

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

|
Хм. странно все это: В доке на ьыз написано, что UCTLx и UTCTLx можно менять только когда выставлен флаг SWRST. Так вот у меня наоборот все - если перед инициализацией uart написать U0CTL = SWRST; то ничего не работает (прерывание не срабатывает). а если не писать, тогда прерывание срабатывает, но принятый байт неправильный. Попробовал разные кварцы: 2 Мгц, 1 Мгц, 100 кГц, 32 кГц (регистры естественно пересчитывал с помощью приложеного вами файла), uart так и не заработал Складывается впечатление, что частоты кварцев не те, которые на них написаны
|
|
|
|
|
Aug 5 2007, 16:49
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(aag @ Aug 5 2007, 09:05)  В доке на ьыз написано, что UCTLx и UTCTLx можно менять только когда выставлен флаг SWRST. Так вот у меня наоборот все - если перед инициализацией uart написать U0CTL = SWRST; то ничего не работает (прерывание не срабатывает). а если не писать, тогда прерывание срабатывает, но принятый байт неправильный. Это явно указывает на то, что проблема не в кристалле, а в вашей программе. Цитата(aag @ Aug 5 2007, 09:05)  Попробовал разные кварцы: 2 Мгц, 1 Мгц, 100 кГц, 32 кГц (регистры естественно пересчитывал с помощью приложеного вами файла), uart так и не заработал Складывается впечатление, что частоты кварцев не те, которые на них написаны Скорее всего вы наступили на другие типовые грабли при инициализации источников тактирования  Приведенный ниже код для кристалла 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; //разрешим прерывание от детектора ошибки кварц.резонатора ... ... ... }
|
|
|
|
|
Aug 6 2007, 10:58
|

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

|
Цитата Дело скорее всего в скорости приема/передачи, но вот только никак не могу понять, почему она не соответствует ожидаемой? Выведите MCLK на ножку и посмотрите ее осциллографом... Как это сделать, см. примеры или даташит.
--------------------
Если зайца бить, его можно и спички научить зажигать Сколько дурака не бей - умнее не будет. Зато опытнее
|
|
|
|
|
Aug 7 2007, 11:22
|

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

|
Отличаются ли программы? Огромное спасибо за вопрос!! На первый взгляд один в один (только в рабочей сначала инициализируется uart, а потом все остальное, а в нерабочей uart последним инициализировался). Но при детальном сравнении нашел ошибку  оказывается в нерабочей программе значения U0BR0 и U0BR1 местами поменял (при расчете скорости перепутал старший и младший байты). Блин, день убил из-за такой оплошности. а вот почему кварцы отзываться стали до сих пор понять не могу (но теперь уже все равно, раз заработали)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|