|
|
  |
"Быстрое" прерывание |
|
|
|
Jul 7 2007, 07:34
|
Группа: Новичок
Сообщений: 11
Регистрация: 30-06-07
Пользователь №: 28 801

|
Здравствуйте, подскажите пожалуйста как сделать быстрое (Т=1мс) прерывание на MSP430F149. Сейчас делаю так: TBCTL = CNTL_3 + TBSSEL_1 + MC_1; TBCCR0 = 33; //32768/1000 TBCCTL0 = CCIE;
#pragma vector = TIMERB0_VECTOR __interrupt void TIMERB0_VECTOR_code( void ) { rtc_msec++; }
Частота ACLK = 32768. При периоде прерывания в Т=10мс основная программа работает, при уменьшении периода до 5мс основной цикл уже не выполняется. (Похоже, что программа "задыхается" в обработчике прерывания и процессор рестартится).
Ещё раз вопрос: Как правильно сделать прерывание с периодом T=1мс на MSP430F149 ?
|
|
|
|
|
Jul 7 2007, 09:52
|

тут может быть ваша реклама
    
Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280

|
Цитата(condor @ Jul 7 2007, 12:35)  Для МСП430 1кГц прерывание это совсем не быстро. А какая MCLK? +1 Цитата(Salazar @ Jul 7 2007, 11:34)  Здравствуйте, подскажите пожалуйста как сделать быстрое (Т=1мс) прерывание на MSP430F149. Сейчас делаю так: TBCTL = CNTL_3 + TBSSEL_1 + MC_1; TBCCR0 = 33; //32768/1000 TBCCTL0 = CCIE;
#pragma vector = TIMERB0_VECTOR __interrupt void TIMERB0_VECTOR_code( void ) { rtc_msec++; }
Частота ACLK = 32768. При периоде прерывания в Т=10мс основная программа работает, при уменьшении периода до 5мс основной цикл уже не выполняется. (Похоже, что программа "задыхается" в обработчике прерывания и процессор рестартится).
Ещё раз вопрос: Как правильно сделать прерывание с периодом T=1мс на MSP430F149 ? 1 мс это 1кГц. У вас проц если работает на пусть даже 1 Мгц это в 1000 раз быстрее. Значит между прерываниями успевает выполняться примерно (на самом деле чуть поменьше) 1000 инструкций. В условиях 5 мс прерывания и 1 Мгц MCLK - 5000 интрукций. Либо у вас такой большой основной цикл, что он не успевает на вашей MCLK полностью выполняться. Либо... чето не так с настройками камня. Приведите весь код, если не трудно
|
|
|
|
|
Jul 7 2007, 23:10
|
Группа: Новичок
Сообщений: 11
Регистрация: 30-06-07
Пользователь №: 28 801

|
Видимо, как и положено начинающему, я неправильно инициализирую процессор. Может у кого есть пример, ка завести МСП430Ф149 на частоте достаточной для моего (1мс) прерывания не используя внешний кварц?
Систему тактирования сейчас инициализирую так:
// Может, моя проблема в значении параметра Delta? Delta = 375; BCSCTL1 &= 0xc0; //Set ACLCK to 32768 and rsel to 0 BCSCTL1 |= 0x21; //Now Set ACLCK to 32768/4 and rsel to 7! CCTL2 = 0x5100; // CCR2 forced into Rising adge, source is aclock, set capture mode TACTL = 0x220; // System clock as input to counter cont. UP counting. TACTL |= 0x4; //Reset Counter
DCOCTL=0x80; do { Ovf2=0; while (((CCTL2 & 0x01) != 0x01) && (Ovf2++ <30000)); // Wait until capture occured! CCTL2 &= 0xfffe ; // Capture occured, clear flag and overflow Compare = CCR2; // Get current captured SMCLK Gap = Compare - Oldcapture; // SMCLK difference Oldcapture = CCR2; // Save current captured SMCLK R_Sel=BCSCTL1&0x07; if(Delta == Gap) { Err=0; break; } else if (Delta < Gap) { // DCO is too fast, slow it down DCOCTL--; if (DCOCTL ==0xff && R_Sel>0)BCSCTL1--; // Did DCO role under? Select next lower RSEL } else { DCOCTL++; if (DCOCTL ==0x00 && R_Sel<7)BCSCTL1++; // Did DCO role over? } }while(++Ovf<30000); CCTL2 = 0; // Stop CCR2 function TACTL = 0; // Stop Timer_A BCSCTL1 &= 0xcf; // Set ACLCK to 32768
Сообщение отредактировал Salazar - Jul 7 2007, 23:19
|
|
|
|
|
Jul 8 2007, 17:58
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Просмотрел "по диагонали", но вроде алгоритм верный. 32768/4*375=3072000Гц. Вам нужна частота около 3МГц? ИМХО ваш алгоритм несколько усложнен. ИМХО достаточно было бы провести натурный эксперимент с выводом MCLK на пин, чтобы примерно подобрать значение DCO, MOD и RSEL и "плясать" уже от найденного значения. Тогда подстройка частоты происходила быстрее бы. Я бы взял начальные условаия RSEL=7 и DCO=3. Потом DCO и MOD определить программно. Хотя если у вас батарейное питание, а не фиксированное, тогда делаете вполне разумно. И все-таки остается непонятным, почему же при тактовой 3МГц не успевают обрабатываться 1мс прерывания? P.S. если хотите, чтобы желание разобраться в вашем исходнике возникло у бОльшего кол-ва людей, то пользуйтесь стандартными для TI обозначениями битов и оформляйте вставку кода в сообщение тэгами [ code ] [ /code ]. P.P.S. кстати, вы контролировали генерацию на часовом кварце или частоту ACLK? Он стартует надежно? Именно на частоте 32768? В даташите рекомендуется притягивать выход генератора XOUT к DVss резистором 5,1МОм при питании 2,5В и меньше. Но опытным путем (и не только мной) было выяснено, что этот резистор отнюдь не мешает и при более высоком напряжении питании (3,3В например). С этим резистором LFXT генератор стартует более надежно и с любыми часовыми кварцами, правда выход на нормальный режим колебаний увеличивается почти до 1с. Некоторые люди решили, что притягивать XOUT нужно не к DVss, а к DVcc. Но я пока не проверял эффективности этого способа. См. вот эти ветки обсуждений. http://caxapa.ru/87886.html?todo=full и http://caxapa.ru/88056.html?todo=fullP.P.P.S. еще вспомнил про одну ошибку начинающих. Если вы используете обычный часовой кварц с CL=12,5pF (а именно такие чаще всего продаются), то встроенных в LF-генератор MSP430 конденсаторов 12,5pF недостаточного! Нужно дополнительно на XIN и XOUT подключить еще по конденсатору на 12pF.
Сообщение отредактировал rezident - Jul 8 2007, 18:06
|
|
|
|
|
Jul 9 2007, 06:59
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Salazar @ Jul 8 2007, 02:10)  Может у кого есть пример, ка завести МСП430Ф149 на частоте достаточной для моего (1мс) прерывания не используя внешний кварц? Я просто делаю DCO немного быстрее, с запасом относительно частоты 8 МГц, чтобы ее не превысить при изменении температуры и прочих факторов, и проверяю наличие генерации кварца. Код void ClockConfiguration(void) { // DCOCTL= 0x56; // without change after reset BCSCTL1=0x87; // CPU faster RSEL=7 // XT2 off, XT1 - low frequency ... // divider for ACLK = 1 }
void CheckOscillator(void) { OnWorkRed1; do { TACTL=TASSEL_1+TACLR+MC_2; // Timer A counts ACLK clocks continuos for (del=0;del<31000;del++) PulseWDI ; //105 ms TACTL=TASSEL_1+MC_0; // stop timer del=TAR; ToggleWorkRed; } while ((del<5000) | (del>8000)); OffWork; ... };
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jul 9 2007, 08:07
|
Группа: Новичок
Сообщений: 11
Регистрация: 30-06-07
Пользователь №: 28 801

|
Хм. Прочтя всё вышенаписанное сделал так: Код TBCTL = CNTL_0 + TBSSEL_2 + MC_1; TBCCR0 = 3072; // 3072000/1000 TBCCTL0 = CCIE; Выбрал в качестве источника не ACLK, а SMCLK. Всё работает. Это верное решение?
Сообщение отредактировал Salazar - Jul 9 2007, 08:08
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|