Перейти к содержанию
    

Вот код

#include  "msp430x471x7.h"

void main(void)
{
 volatile unsigned int i;
 P5DIR |= BIT7; 

 WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
 FLL_CTL0 |= XCAP14PF;                     // Configure load caps

 do
 {
   IFG1 &= ~OFIFG;                         // Clear OSCFault flag
   for (i = 0x47FF; i > 0; i--);           // Time for flag to set
 }
 while ((IFG1 & OFIFG));                   // OSCFault flag still set?

 P1SEL |= BIT6+BIT7;                       // P2.4,5 = USCI_A0 RXD/TXD
 UCA1CTL1 |= UCSSEL_1;                     // CLK = ACLK
 UCA1BR0 = 0x03;                           // 32k/9600 - 3.41
 UCA1BR1 = 0x00;                           //
 UCA1MCTL = 0x06;                          // Modulation
 UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
//  IE2 |= UCA1RXIE;                          // Enable USCI_A0 RX interrupt
 char c = 'A';
// _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3, interrupts enabled
  while(1)
 {

    while(!(IFG2&UCA1TXIFG));
     UCA1TXBUF = c;
     P5OUT ^= BIT7;
     for(i=2500;i>0;i--);
 }

}

 

Пытаюсь просто выводить в терминал символ 'A' и зажигать светодиод. Светодиод горит, на терминал выводится сами видите что (см. приложенное фото).

В чём может быть дело?

Ещё когда пробую проект "эхо"(посылаем символ с клавиатуры компьютера - MSP430 принимает его и кидает в компорт компьютера), то он работает со сбоями (сначала всё хорошо, потом символы не передаются, потом передаётся чепуха...)

 

Нужна помощь, всю голову сломал((

post-60464-1310535072_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Модуль тактирования проинициализируйте полностью!

 

У меня MSP430F47197 подклюен часовой кварц(32768) и кварцевый резонатор(16 мегагерц).

Если я правильно понял, то можно тактировать USCI модуль от разных источников:

DCO, SMCLK, ACLK. Я предпочёл ACLK (см. код выше).

Я делаю так

 

FLL_CTL0 |= XCAP0PF;                     // Set load capacitance
 FLL_CTL1 &= ~XT2OFF;                      // Turn on XT2
 FLL_CTL1 = SELS;                          // Select SMCLK source as XT2CLK
 FLL_CTL2 |= XT2S_2;

 

По-моему у серии MSP430F47XX несколько сложнее, чем у других, система тактирования (так как есть FLL).

 

Кто знает поправьте если что-то не так.

 

 

 

Изменено пользователем Zelepuk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто знает поправьте если что-то не так.

Типовое значение UMCTL для 32768/9600 равно 4А. (таблица в мануале)

Непонятно, из каких соображений у вас 6 торчит. Два бита подряд корректируются, остальные пошли вразнос.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто знает поправьте если что-то не так.

Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после POR) состояния. То же самое касается в отношении регистров USCI.

Еще возникает вопрос зачем использовать 32768 для UART? Да еще и при неверном значении регистра модуляции, на что вам MrYuran указал. Подстройте DCO по часовому кварцу к какой-либо типизированной частоте, которая нацело делиться для выбранной скорости UART. Например, 1,152МГц (9600*120=115200*10) или 1,8432МГц (9600*192=115200*16). И потом используйте DCO как источник SMCLK, а тот в свою очередь для тактирования USCI. Либо подключите кварц на XT2 с тем же критерием выбора частоты (нацело делится для стандартного ряда скоростей UART).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после POR) состояния. То же самое касается в отношении регистров USCI.

Еще возникает вопрос зачем использовать 32768 для UART? Да еще и при неверном значении регистра модуляции, на что вам MrYuran указал. Подстройте DCO по часовому кварцу к какой-либо типизированной частоте, которая нацело делиться для выбранной скорости UART. Например, 1,152МГц (9600*120=115200*10) или 1,8432МГц (9600*192=115200*16). И потом используйте DCO как источник SMCLK, а тот в свою очередь для тактирования USCI. Либо подключите кварц на XT2 с тем же критерием выбора частоты (нацело делится для стандартного ряда скоростей UART).

 

Может я совсем дуб, но как смог понять DCO применяется для умножения частоты часового кварца если нету кварца на XT2 (у меня там стоит кварц на 16 мегагерц).

 

Тогда наверное нужно в качестве SMCLK указать что используется кварц на XT2?

___________________________________________________________________________

 

Дабы не плодить темы.

Подскажите как нормально инициализировать систему тактирования, если, у меня есть на плате два кварца (часовой и 16Мгц), не планируется использовать внутренние ёмкости и нужно добится максимальной скорости тактирования ядра, а кроме того от часового кварца работают часы реального времени.

нужен ли тогда вообще DCO или нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нужен ли тогда вообще DCO или нет?

DCO нужен всегда! По крайней мере для тактирования MCLK нужен.

Плюсы DCO.

- есть во всех кристаллах MSP430;

- не требует внешних элементов/компонентов;

- весьма широкий диапазон программной перестройки частоты, возможность подстройки от внешнего сигнала;

- это внутренний генератор, поэтому он наименее подвержен воздействию внешних помех;

- быстрый запуск (единицы мкс), удобно использовать в режимах энергосбережения - быстро проснулся, быстро (на высокой частоте) выполнил необходимые операции, снова уснул;

Минусы DCO:

- зависимость от температуры и величины напряжения питания.

При наличии часового кварца минус DCO нивелируется периодической подстройкой его частоты или задействованием FLL для синхронизации его от LFXT. См. структурную блок-схему модуля FLL+ в User's Guide Figure 5−3.MSP430x47x3/4 and MSP430F471xx Frequency-Locked Loop и описание в разделе Chapter 5. FLL+ Clock Module.

post-3882-1310669400_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще возникает вопрос зачем использовать 32768 для UART? Да еще и при неверном значении регистра модуляции, на что вам MrYuran указал. Подстройте DCO по часовому кварцу к какой-либо типизированной частоте, которая нацело делиться для выбранной скорости UART. Например, 1,152МГц (9600*120=115200*10) или 1,8432МГц (9600*192=115200*16). И потом используйте DCO как источник SMCLK, а тот в свою очередь для тактирования USCI. Либо подключите кварц на XT2 с тем же критерием выбора частоты (нацело делится для стандартного ряда скоростей UART).

 

Я подключаю кварц на XT2 (16000кГц) и делю его частоту на скорость UART(115200) получается 138 целых, а дробную часть просто не учитываю (именно так делают TI в своих примерах).

 

 

Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после POR) состояния. То же самое касается в отношении регистров USCI.

 

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

 

Просто у меня есть большая апликуха от TI и там такой подход не практикуется.

 

 

 

DCO нужен всегда! По крайней мере для тактирования MCLK нужен.

 

MCLK: основное тактирование. Модуль MCLK программно выбирается как LFXT1CLK, XT2CLK (если доступен) или DCOCLK. MCLK делится на 1, 2, 4 или 8. MCLK используется ЦПУ и системой.

 

Это прочитано из русского руководства. Получается, если есть два кварца на плате, можно вообще без DCO обойтись.

Изменено пользователем Zelepuk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я подключаю кварц на XT2 (16000кГц) и делю его частоту на скорость UART(115200) получается 138 целых, а дробную часть просто не учитываю (именно так делают TI в своих примерах).

В ваших предыдущих примерах генератор XT2 отключен!

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

 

Просто у меня есть большая апликуха от TI и там такой подход не практикуется.

Я что-то не пойму, вам "шашечки" или ехать? :rolleyes:

Это прочитано из русского руководства. Получается, если есть два кварца на плате, можно вообще без DCO обойтись.

Я наверное для себя предыдущее сообщение писал, да? Вы либо его не читали, либо смысла не поняли. Перечитайте еще раз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

получается 138 целых, а дробную часть просто не учитываю (именно так делают TI в своих примерах).

Неграмотные индусы нанятые TI для написания кучи мусора для еще более неграмотных "программистов" округлять до целого не умеют. Но Вы для себя могли-бы и постараться и НЕ отбрасывать всегда безусловно дробную часть.

Просто у меня есть большая апликуха от TI и там такой подход не практикуется.

См. выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после POR) состояния. То же самое касается в отношении регистров USCI.

Еще возникает вопрос зачем использовать 32768 для UART? Да еще и при неверном значении регистра модуляции, на что вам MrYuran указал. Подстройте DCO по часовому кварцу к какой-либо типизированной частоте, которая нацело делиться для выбранной скорости UART. Например, 1,152МГц (9600*120=115200*10) или 1,8432МГц (9600*192=115200*16). И потом используйте DCO как источник SMCLK, а тот в свою очередь для тактирования USCI. Либо подключите кварц на XT2 с тем же критерием выбора частоты (нацело делится для стандартного ряда скоростей UART).

 

Читая даташит, я понял что fdcoclk задаётся путём умножения частоты кварца (32768 в моём случае) на константу, а так же возможно деление значения на число из ряда 1, 2, 4 или 8.

Так задавшись частотой 1,152МГц я никак не могу подобрать точное значение множителей, что бы 1152000 делилось без остатка на 115200 или 9600.

 

fdcoclk = ((x+1)/y)*fcrystal

1152000 = ((x+1)/y)*32768

если y = 2 (задаём в регистре SCFI0 биты FLLDx), то x = 69.3125

принимаю x = 69

Строго целое не получится никогда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Теперь пробую инициализировать явно все регистры модуля тактирования и модуля USCI.

 

#include  "msp430x471x7.h"

void main(void)
{
 volatile unsigned int i;

 WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
 P5DIR |= BIT7;

//-----------------------------------------------------------------------------
// Инициализация модуля тактирования (SMCLK = Fdcoclk = 1048576)
//-----------------------------------------------------------------------------
 SCFQCTL = 52;                           // модуляции нет, множитель DCO = 52
 SCFI0 = 0;                           // диапахон DCO 0.65 to 6.1 MHz
 // SCFI1 нет трогаю
 FLL_CTL0 = 0; 
 FLL_CTL0 |= (DCOPLUS)|(1<<5)|(1<<4);  // не используем предделитель кварц на XT1 на 10пФ
 FLL_CTL1 = 0;                               
 FLL_CTL1  |= SELM1;         //SMCLK от DCO, MCLK от 16Mhz кварца
 FLL_CTL2 |= (XT2S1)|(XT2S0);        //диапазон частоты XT2 от 0.4 до 16 Mhz

 do
 {
   IFG1 &= ~OFIFG;                         // Clear OSCFault flag
   for (i = 0x47FF; i > 0; i--);           // Time for flag to set
 }
 while ((IFG1 & OFIFG));                   // OSCFault flag still set?


//-----------------------------------------------------------------------------
// Инициализация USCI модуля в режиме UART
//-----------------------------------------------------------------------------
 P1SEL |= BIT6+BIT7;                       // P1.6,7 = USCI_A1 RXD/TXD
 UCA1CTL0 = 1; //нет контроля чётности, 8N1 LSB first, Synchronous Mode
 UCA1CTL1 = 0;
 UCA1CTL1 |= (1<<7);                     // CLK = SMCLK
 UCA1BR0 = 0x6D;                           // 1146880/9600 = 119.46
 UCA1BR1 = 0x00;                           //
 UCA1MCTL = 0x03;                          // Modulation
 UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
 UC1IE |= UCA1RXIE;                          // Enable USCI_A1 RX interrupt

 while(1) // main loop
 {
     while(!(IFG2&UCA1TXIFG));
     UCA1TXBUF = 'A';
     P5OUT ^= BIT7;
     for(i=2500;i>0;i--);
 } 
}

 

Значение Fdcoclk = 1048576 а так же

UCA1BR0 = 0x6D; // 1146880/9600 = 119.46

UCA1BR1 = 0x00; //

UCA1MCTL = 0x03; // Modulation

 

взяты из даташита (страница 17-16).

 

Теперь даже не мигает светодиод.... накосячил опять где-то наверное((( :laughing:

единственное что могло прийти в голову - номиналами конденсаторов программно поиграться - непомогло... (а это может влиять вплоть до неработоспособности?)

Изменено пользователем Zelepuk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть несколько вариантов организации тактирования UART.

Вариант 1.

XT2 → SMCLK → BRCLK → |BRCLK divider| → BITCLK

Вариант 2.

LFXT →
     +  FLL → SMCLK → BRCLK → |BRCLK divider| → BITCLK
DCO →

Вариант 3.

LFXT → ACLK  
(откалиброванный по ACLK) DCO → SMCLK → BRCLK → |BRCLK divider| → BITCLK

Кварцевый генератор служит опорой, поэтому в первую очередь нужно обеспечить его функционирование. И только дождавшись когда колебания стабилизируются, можно использовать его для тактирования внутренних сигналов. Следовательно в первую очередь следует инициализировать регистры FLL_CTL0 и FLL_CTL2 (если собираетесь использовать XT2).

Колебания генератора часового кварца стабилизируются гораздо медленне, чем высокочастотного. А для вариантов 2 и 3 генератор 32768Гц к тому же является опорным. Поэтому сначала ждем именно его готовности. К тому же OFIFG нельзя будет сбросить до тех пор, пока оба кварцевых генератора и FLL не будут функционировать нормально.

Ниже привожу пример программы, которая с периодом около 100мс отсылает через UART символы из буфера и мерцает светодиодом на выводе P5.7 с частотой 1Гц.

В программе используется тактирование по варианту 2: часовой кварц и DCO, синхронизированный от него с помощью FLL. Частота DCO должна получаться 9830400Гц. SMCLK = DCO и вплоть до baudrate = 38400 делится нацело, поэтому регистр модуляции не используется. Но даже и для более высоких значений baudrate (56700, 115200) при такой частоте регистр модуляции можно не использовать. Т.к. ошибка установки baudrate будет составлять менее 0,4% что вполне допустимо. Это же замечание относится к варианту 1, когда используется ВЧ кварцевый генератор частота 16МГц.

Для варианта тактирования 1 нужно раскоментировать закоментированные строки.

Вариант 3 мне реализовывать уже было лень :) Можете попробовать сами его реализовать, учитывая, что имеется возможность внутренне скоммутировать ACLK на вход захвата CCI2B TimerA. Это указано в таблице TIMER_A3 SIGNAL CONNECTIONS в datasheet MSP430F47197. Пример подстройки DCO для такого способоа где-то был в примерах исходников от TI по-моему. Частота DCO программно корректируется до тех пор, пока отношение частот DCO и 32768Гц (полученное с помощью схемы захвата TimerA) не будет равно заданному.

#include  <msp430x471x7.h>
#include  <stdint.h>

#define FREQMCLK        9830400UL   //MCLK
#define FREQSMCLK       9830400UL   //SMCLK
//#define FREQSMCLK       16000000UL   //SMCLK
#define FREQACLK        32768UL     //ACLK
#define BAUDRATE        9600UL      //baudrate
#define TICK_MS_ADDVAL  100U        //инкремент таймера тиков [мс]
#define BLINK_TIME_MS   500U        //полупериод мерцания LED [мс]

int __low_level_init(void)
{ WDTCTL = WDTPW | WDTHOLD;         //останов WDTimer
 return 1;
}

uint16_t tick_ms;                   //счетчик миллисекунд
uint8_t	uart_buf[]={'0','1','2','3','4','5','6','7','8','9','\n','\r'};//буфер UART

void main(void)
{ uint16_t tickStamp, idx;
 uint32_t lTmp;
 //Инициализация системы тактирования
 FLL_CTL1 = XT2OFF;                //D=2, MCLK=fDCOCLK/D, SMCLK=fDCOCLK/D, ACLK=LFXT/1, XT2=off
//  FLL_CTL1 = 0;                     //D=2, MCLK=fDCOCLK/D, SMCLK=fDCOCLK/D, ACLK=LFXT/1
 FLL_CTL2 = XT2S1;                 //для работы XT2=16МГц
 FLL_CTL0 = XCAP11PF;              //XT1=LF, DCO/D, XCAP=11пФ
 while ((FLL_CTL0 & LFOF) != 0);   //ждем готовности генератора 32768Гц
//  while ((FLL_CTL0 & XT2OF) != 0);  //ждем готовности генератора 16МГц
 SCFI0 = FLLD_4 | FN_2;            //D=4, fDCOCLK =  1.4-12MHz
 SCFQCTL = SCFQ_M + (75U-1U);      //fDCOCLK=32768*(75)*4=9830400Гц, DCO=fDCOCLK/4
 while ((FLL_CTL0 & DCOF) != 0);   //ждем готовности FLL
 FLL_CTL0 |= DCOPLUS;              //MCLK=DCO/1, SMCLK=DCO/1
//  FLL_CTL1 |= SELS;                 //MCLK=DCO, SMCLK=XT2, ACLK=LFXT/1
 do
 { IFG1 &= OFIFG;
 } while ((IFG1&OFIFG) != 0);      //ждем готовности всей системы тактирования
 //Инициализация UART
 UCA1CTL1 |= UCSWRST;              //Reset USCI
 UCA1CTL0 = 0;                     //Parity=disable, 8bit, 1stop-bit
 UCA1CTL1 = UCSSEL_2 | UCSWRST;    //BRCLK=SMCLK
 lTmp=FREQSMCLK/BAUDRATE;
 UCA1BR1 = (uint8_t)(lTmp>>8UL);   //
 UCA1BR0 = (uint8_t)(lTmp);        //BITCLK=BRCLK/(UCAxBR1*256+UCAxBR0)
 UCA1MCTL = 0;                     //регистр модуляции
 UCA1STAT = 0;                     //сброс всех битов ощибок
 UCA1IRTCTL = 0;                   //IRDA disable
 UCA1CTL1 &= ~UCSWRST;
 P1SEL |= BIT6 | BIT7;             //P1.6 = USCI TXD, P1.7 = USCI RXD
 UC1IE &= ~(UCA1TXIE | UCA1RXIE);  //запретим прерывания USCI_A1
 UC1IFG &= ~UCA1RXIFG;             //сбросим флаг готовности буфера приемника
 UC1IFG |= UCA1TXIFG;              //установим флаг готовность буфера передатчика
 //Иницализация TimerA
 TACTL = TASSEL_1 | TACLR;         //TACLK=ACLK/1
 TACCR0=(uint16_t)(FREQACLK/10UL); //период около 100мс
 TACCTL0 = CCIE;                   //разр. прерывание от CCR0
 TACCTL1 = 0;
 TACCTL2 = 0;
 TACTL |= MC_1;                    //запустить таймер в режиме CountUP
 //Инициализация LED
 P5DIR |= BIT7;
 P5SEL &= ~BIT7;
 P5OUT &= ~BIT7;
 idx=0;
 tickStamp = tick_ms;              //зафиксировать временную метку
 __enable_interrupt();             //разрешим прерывания
 for (;;)
 { if ((tick_ms - tickStamp) >= BLINK_TIME_MS)//полупериод мерцания закончился?
   { tickStamp = tick_ms;          //запомним новое значение метки времени
     P5OUT ^= BIT7;                //инвертируем состояние LED
   }
   if ((UC1IFG & UCA1TXIFG) != 0)  //буфер передатчика готов?
   { UCA1TXBUF=uart_buf[idx];      //вывод текущего символа
     if (idx < (sizeof(uart_buf)-1))//увеличение индекса
       idx += 1;
     else
       idx = 0;
   }
   __bis_SR_register(LPM0_bits + GIE);//переход в режим энергосбережения LPM0
 }
}

#pragma vector=TIMERA0_VECTOR
#pragma type_attribute=__interrupt
void TimerA0_ISR (void)
{ 
 tick_ms += TICK_MS_ADDVAL;        //инкремент счтечика тиков [мс]
 __bic_SR_register_on_exit(LPM0_bits);//выход из режима энергосбережения при выходе из прерывания
}

Программа на железе не проверялась ввиду отсутствия оного.

 

Update. Исправил форматирование исходника. Изменил команду выхода из режима энергосбережения в прерывании. В принципе код генерился одинаковый, но так корректнее.

Изменено пользователем rezident

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть несколько вариантов организации тактирования UART.

Вариант 1.

XT2 → SMCLK → BRCLK → |BRCLK divider| → BITCLK

Вариант 2.

LFXT →
     +  FLL → SMCLK → BRCLK → |BRCLK divider| → BITCLK
DCO →

Вариант 3.

LFXT → ACLK  
(откалиброванный по ACLK) DCO → SMCLK → BRCLK → |BRCLK divider| → BITCLK

Кварцевый генератор служит опорой, поэтому в первую очередь нужно обеспечить его функционирование. И только дождавшись когда колебания стабилизируются, можно использовать его для тактирования внутренних сигналов. Следовательно в первую очередь следует инициализировать регистры FLL_CTL0 и FLL_CTL2 (если собираетесь использовать XT2).

Колебания генератора часового кварца стабилизируются гораздо медленне, чем высокочастотного. А для вариантов 2 и 3 генератор 32768Гц к тому же является опорным. Поэтому сначала ждем именно его готовности. К тому же OFIFG нельзя будет сбросить до тех пор, пока оба кварцевых генератора и FLL не будут функционировать нормально.

Ниже привожу пример программы, которая с периодом около 100мс отсылает через UART символы из буфера и мерцает светодиодом на выводе P5.7 с частотой 1Гц.

В программе используется тактирование по варианту 2: часовой кварц и DCO, синхронизированный от него с помощью FLL. Частота DCO должна получаться 9830400Гц. SMCLK = DCO и вплоть до baudrate = 38400 делится нацело, поэтому регистр модуляции не используется. Но даже и для более высоких значений baudrate (56700, 115200) при такой частоте регистр модуляции можно не использовать. Т.к. ошибка установки baudrate будет составлять менее 0,4% что вполне допустимо. Это же замечание относится к варианту 1, когда используется ВЧ кварцевый генератор частота 16МГц.

Для варианта тактирования 1 нужно раскоментировать закоментированные строки.

Вариант 3 мне реализовывать уже было лень :) Можете попробовать сами его реализовать, учитывая, что имеется возможность внутренне скоммутировать ACLK на вход захвата CCI2B TimerA. Это указано в таблице TIMER_A3 SIGNAL CONNECTIONS в datasheet MSP430F47197. Пример подстройки DCO для такого способоа где-то был в примерах исходников от TI по-моему. Частота DCO программно корректируется до тех пор, пока отношение частот DCO и 32768Гц (полученное с помощью схемы захвата TimerA) не будет равно заданному.

#include  <msp430x471x7.h>
#include  <stdint.h>

#define FREQMCLK        9830400UL   //MCLK
#define FREQSMCLK       9830400UL   //SMCLK
//#define FREQSMCLK       16000000UL   //SMCLK
#define FREQACLK        32768UL     //ACLK
#define BAUDRATE        9600UL      //baudrate
#define TICK_MS_ADDVAL  100U        //инкремент таймера тиков [мс]
#define BLINK_TIME_MS   500U        //полупериод мерцания LED [мс]

int __low_level_init(void)
{ WDTCTL = WDTPW | WDTHOLD;         //останов WDTimer
 return 1;
}

uint16_t tick_ms;                   //счетчик миллисекунд
uint8_t	uart_buf[]={'0','1','2','3','4','5','6','7','8','9','\n','\r'};//буфер UART

void main(void)
{ uint16_t tickStamp, idx;
 uint32_t lTmp;
 //Инициализация системы тактирования
 FLL_CTL1 = XT2OFF;                //D=2, MCLK=fDCOCLK/D, SMCLK=fDCOCLK/D, ACLK=LFXT/1, XT2=off
//  FLL_CTL1 = 0;                     //D=2, MCLK=fDCOCLK/D, SMCLK=fDCOCLK/D, ACLK=LFXT/1
 FLL_CTL2 = XT2S1;                 //для работы XT2=16МГц
 FLL_CTL0 = XCAP11PF;              //XT1=LF, DCO/D, XCAP=11пФ
 while ((FLL_CTL0 & LFOF) != 0);   //ждем готовности генератора 32768Гц
//  while ((FLL_CTL0 & XT2OF) != 0);  //ждем готовности генератора 16МГц
 SCFI0 = FLLD_4 | FN_2;            //D=4, fDCOCLK =  1.4-12MHz
 SCFQCTL = SCFQ_M + (75U-1U);      //fDCOCLK=32768*(75)*4=9830400Гц, DCO=fDCOCLK/4
 while ((FLL_CTL0 & DCOF) != 0);   //ждем готовности FLL
 FLL_CTL0 |= DCOPLUS;              //MCLK=DCO/1, SMCLK=DCO/1
//  FLL_CTL1 |= SELS;                 //MCLK=DCO, SMCLK=XT2, ACLK=LFXT/1
 do
 { IFG1 &= OFIFG;
 } while ((IFG1&OFIFG) != 0);      //ждем готовности всей системы тактирования
 //Инициализация UART
 UCA1CTL1 |= UCSWRST;              //Reset USCI
 UCA1CTL0 = 0;                     //Parity=disable, 8bit, 1stop-bit
 UCA1CTL1 = UCSSEL_2 | UCSWRST;    //BRCLK=SMCLK
 lTmp=FREQSMCLK/BAUDRATE;
 UCA1BR1 = (uint8_t)(lTmp>>8UL);   //
 UCA1BR0 = (uint8_t)(lTmp);        //BITCLK=BRCLK/(UCAxBR1*256+UCAxBR0)
 UCA1MCTL = 0;                     //регистр модуляции
 UCA1STAT = 0;                     //сброс всех битов ощибок
 UCA1IRTCTL = 0;                   //IRDA disable
 UCA1CTL1 &= ~UCSWRST;
 P1SEL |= BIT6 | BIT7;             //P1.6 = USCI TXD, P1.7 = USCI RXD
 UC1IE &= ~(UCA1TXIE | UCA1RXIE);  //запретим прерывания USCI_A1
 UC1IFG &= ~UCA1RXIFG;             //сбросим флаг готовности буфера приемника
 UC1IFG |= UCA1TXIFG;              //установим флаг готовность буфера передатчика
 //Иницализация TimerA
 TACTL = TASSEL_1 | TACLR;         //TACLK=ACLK/1
 TACCR0=(uint16_t)(FREQACLK/10UL); //период около 100мс
 TACCTL0 = CCIE;                   //разр. прерывание от CCR0
 TACCTL1 = 0;
 TACCTL2 = 0;
 TACTL |= MC_1;                    //запустить таймер в режиме CountUP
 //Инициализация LED
 P5DIR |= BIT7;
 P5SEL &= ~BIT7;
 P5OUT &= ~BIT7;
 idx=0;
 tickStamp = tick_ms;              //зафиксировать временную метку
 __enable_interrupt();             //разрешим прерывания
 for (;;)
 { if ((tick_ms - tickStamp) >= BLINK_TIME_MS)//полупериод мерцания закончился?
   { tickStamp = tick_ms;          //запомним новое значение метки времени
     P5OUT ^= BIT7;                //инвертируем состояние LED
   }
   if ((UC1IFG & UCA1TXIFG) != 0)  //буфер передатчика готов?
   { UCA1TXBUF=uart_buf[idx];      //вывод текущего символа
     if (idx < (sizeof(uart_buf)-1))//увеличение индекса
       idx += 1;
     else
       idx = 0;
   }
   __bis_SR_register(LPM0_bits + GIE);//переход в режим энергосбережения LPM0
 }
}

#pragma vector=TIMERA0_VECTOR
#pragma type_attribute=__interrupt
void TimerA0_ISR (void)
{ 
 tick_ms += TICK_MS_ADDVAL;        //инкремент счтечика тиков [мс]
 __bic_SR_register_on_exit(LPM0_bits);//выход из режима энергосбережения при выходе из прерывания
}

Программа на железе не проверялась ввиду отсутствия оного.

 

Update. Исправил форматирование исходника. Изменил команду выхода из режима энергосбережения в прерывании. В принципе код генерился одинаковый, но так корректнее.

 

Спасибо огромное, rezident, за внимание! Но вроде код грамотный и всё разжёвано... но ваш код не запускается вовсе... светодиод не горит, в терминалке ничего не выводится...(((

А может вся эта система не запускаться из-за того, что неправильно кондесаторы на кварцах подобраны?

Разбираюсь дальше :smile3046:

За код ещё раз спасибо.

Изменено пользователем Zelepuk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А может вся эта система не запускаться из-за того, что неправильно кондесаторы на кварцах подобраны?

А какие конденсаторы у вас стоят? Если часовой кварц типовой (с нагрузочной емкостью 12,5пФ), то в обвязке его должны быть по 12пФ. С учетом предположения именно такой нагрузочной емкости выбраны установки битов XCAP11PF. В обвязке 16МГц-кварца должны быть по 15пФ. И, кстати, какой именно часовой кварц вы используете? Я недавно напоролся на проблемы с запуском LFXT на MSP430F2618TPW. Пробовал все что было под рукой: KX-327NHT, KX-327LT от Geyer и DT-38LT (noname) , но ни с одним из них запустить LF-генератор не получалось. Разбор полетов, чтение документации (включая Errata), запросы на форум выявили особенность этого генератора в серии 2xxx. Там очень жесткие требования к допустимому диапазону ESR кварца. Кое-как удалось запустить лишь на DT-26L неизвестного производителя. Коллеги рекомендовали использовать MS1V-T1K от швейцарской фирмы Micro Crystal. Якобы с ним проблем не бывает. Так что проверьте с помощью отладчика или трассировки с помощью того же светодиода, в каком именно месте циклится программа? Если я правильно догадываюсь, то зацикливание должно происходить на ожидании готовности LFXT - там, где проверяется бит LFOF.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...