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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
Zelepuk
сообщение Jul 13 2011, 05:34
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Вот код
CODE
#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 принимает его и кидает в компорт компьютера), то он работает со сбоями (сначала всё хорошо, потом символы не передаются, потом передаётся чепуха...)

Нужна помощь, всю голову сломал((
Эскизы прикрепленных изображений
 Р В Р’ Р’ Р в‚¬Р В РЎВ˜Р В Р’µР Р…ьшено Р Т‘Р С• 60%
Прикрепленное изображение
434 x 290 (141.59 килобайт)
 
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 13 2011, 12:23
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Модуль тактирования проинициализируйте полностью!
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Jul 14 2011, 05:40
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(rezident @ Jul 13 2011, 16:23) *
Модуль тактирования проинициализируйте полностью!


У меня MSP430F47197 подклюен часовой кварц(32768) и кварцевый резонатор(16 мегагерц).
Если я правильно понял, то можно тактировать USCI модуль от разных источников:
DCO, SMCLK, ACLK. Я предпочёл ACLK (см. код выше).
Я делаю так

CODE
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 - Jul 14 2011, 05:57
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 14 2011, 07:40
Сообщение #4


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Zelepuk @ Jul 14 2011, 09:40) *
Кто знает поправьте если что-то не так.

Типовое значение UMCTL для 32768/9600 равно 4А. (таблица в мануале)
Непонятно, из каких соображений у вас 6 торчит. Два бита подряд корректируются, остальные пошли вразнос.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 14 2011, 15:51
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Zelepuk @ Jul 14 2011, 10:40) *
Кто знает поправьте если что-то не так.

Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после POR) состояния. То же самое касается в отношении регистров USCI.
Еще возникает вопрос зачем использовать 32768 для UART? Да еще и при неверном значении регистра модуляции, на что вам MrYuran указал. Подстройте DCO по часовому кварцу к какой-либо типизированной частоте, которая нацело делиться для выбранной скорости UART. Например, 1,152МГц (9600*120=115200*10) или 1,8432МГц (9600*192=115200*16). И потом используйте DCO как источник SMCLK, а тот в свою очередь для тактирования USCI. Либо подключите кварц на XT2 с тем же критерием выбора частоты (нацело делится для стандартного ряда скоростей UART).
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Jul 14 2011, 17:12
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(rezident @ Jul 14 2011, 19:51) *
Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после 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 или нет?
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 14 2011, 18:50
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Zelepuk @ Jul 14 2011, 22:12) *
нужен ли тогда вообще 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.
Эскизы прикрепленных изображений
 Р В Р’ Р’ Р в‚¬Р В РЎВ˜Р В Р’µР Р…ьшено Р Т‘Р С• 75%
Прикрепленное изображение
689 x 853 (30.75 килобайт)
 
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Jul 15 2011, 14:17
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(rezident @ Jul 14 2011, 19:51) *
Еще возникает вопрос зачем использовать 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 в своих примерах).


Цитата(rezident @ Jul 14 2011, 19:51) *
Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после POR) состояния. То же самое касается в отношении регистров USCI.


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

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



Цитата(rezident @ Jul 14 2011, 22:50) *
DCO нужен всегда! По крайней мере для тактирования MCLK нужен.


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

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

Сообщение отредактировал Zelepuk - Jul 15 2011, 14:26
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 15 2011, 14:20
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Zelepuk @ Jul 15 2011, 19:10) *
Я подключаю кварц на XT2 (16000кГц) и делю его частоту на скорость UART(115200) получается 138 целых, а дробную часть просто не учитываю (именно так делают TI в своих примерах).

В ваших предыдущих примерах генератор XT2 отключен!
Цитата(Zelepuk @ Jul 15 2011, 19:10) *
Вы имеете ввиду, что нужно проинициализировать все регистры (см. приложенный рисунок) и каждый бит определить требуемым значением (если даже оно и не особо надо)???

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

Я что-то не пойму, вам "шашечки" или ехать? rolleyes.gif
Цитата(Zelepuk @ Jul 15 2011, 19:17) *
Это прочитано из русского руководства. Получается, если есть два кварца на плате, можно вообще без DCO обойтись.

Я наверное для себя предыдущее сообщение писал, да? Вы либо его не читали, либо смысла не поняли. Перечитайте еще раз.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 15 2011, 17:34
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Zelepuk @ Jul 15 2011, 16:17) *
получается 138 целых, а дробную часть просто не учитываю (именно так делают TI в своих примерах).

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

См. выше.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Jul 16 2011, 12:22
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(rezident @ Jul 14 2011, 19:51) *
Я же вам сказал полностью нужно проинициализировать! Т.е. прописать явными значениями все регистры модуля тактирования, а не накладывать маски на дефолтные (после 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
Строго целое не получится никогда.
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Jul 16 2011, 13:36
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



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

CODE
#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.gif
единственное что могло прийти в голову - номиналами конденсаторов программно поиграться - непомогло... (а это может влиять вплоть до неработоспособности?)

Сообщение отредактировал Zelepuk - Jul 16 2011, 13:47
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 17 2011, 00:26
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Есть несколько вариантов организации тактирования 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 мне реализовывать уже было лень sm.gif Можете попробовать сами его реализовать, учитывая, что имеется возможность внутренне скоммутировать ACLK на вход захвата CCI2B TimerA. Это указано в таблице TIMER_A3 SIGNAL CONNECTIONS в datasheet MSP430F47197. Пример подстройки DCO для такого способоа где-то был в примерах исходников от TI по-моему. Частота DCO программно корректируется до тех пор, пока отношение частот DCO и 32768Гц (полученное с помощью схемы захвата TimerA) не будет равно заданному.
CODE
#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 - Jul 17 2011, 10:43
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Jul 17 2011, 19:00
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(rezident @ Jul 17 2011, 04:26) *
Есть несколько вариантов организации тактирования 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 мне реализовывать уже было лень sm.gif Можете попробовать сами его реализовать, учитывая, что имеется возможность внутренне скоммутировать ACLK на вход захвата CCI2B TimerA. Это указано в таблице TIMER_A3 SIGNAL CONNECTIONS в datasheet MSP430F47197. Пример подстройки DCO для такого способоа где-то был в примерах исходников от TI по-моему. Частота DCO программно корректируется до тех пор, пока отношение частот DCO и 32768Гц (полученное с помощью схемы захвата TimerA) не будет равно заданному.
CODE
#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.gif
За код ещё раз спасибо.

Сообщение отредактировал Zelepuk - Jul 17 2011, 19:11
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 17 2011, 21:16
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Zelepuk @ Jul 18 2011, 00:00) *
А может вся эта система не запускаться из-за того, что неправильно кондесаторы на кварцах подобраны?

А какие конденсаторы у вас стоят? Если часовой кварц типовой (с нагрузочной емкостью 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.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 13:56
Рейтинг@Mail.ru


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