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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> задержка aka Delay, кто как пишет
CAHTA_1939
сообщение Aug 18 2007, 18:08
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



начал программировать жки ака MT-12864J. и столкнулся с необходимостью задержки на несколько нс.
for'ом уже не катит. пришла в голову мыслю использования прерывания, но вот как... хз.
нашел несколько примеров, но мне они показались странными...

напишите, кто как реализует задержку на несколько нс (сек)?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 18 2007, 20:31
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(CAHTA_1939 @ Aug 18 2007, 21:08) *
напишите, кто как реализует задержку на несколько нс (сек)?

Так несколько нс или несколько с?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 18 2007, 20:42
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



Цитата(Dog Pawlowa @ Aug 19 2007, 00:31) *
Так несколько нс или несколько с?



нс =)
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 18 2007, 20:52
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(CAHTA_1939 @ Aug 18 2007, 23:42) *
нс =)

Несколько нс (наносекунд) как-то сами образуются, там не только прерывания не нужны, там вообще ничего не нужно. smile.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 18 2007, 20:57
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



Цитата(Dog Pawlowa @ Aug 19 2007, 00:52) *
Несколько нс (наносекунд) как-то сами образуются, там не только прерывания не нужны, там вообще ничего не нужно. smile.gif



это если нужно 10нс...
мне нужно 140нс - 450нс - 1000нс
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 18 2007, 21:45
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(CAHTA_1939 @ Aug 18 2007, 23:57) *
это если нужно 10нс...
мне нужно 140нс - 450нс - 1000нс

У меня интервал между прерываниями по таймеру составляет 500 нс, и действительно делаю задержку с такой точностью с помощью прерывания от таймера. То есть 450 нс = Delay(1), 1000нс=Delay(2).
Задержку меньше 500 нс реализую с помощью встроенной в компилятор функции.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 18 2007, 21:55
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



а примерчик можешь дать?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 18 2007, 22:13
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(CAHTA_1939 @ Aug 19 2007, 00:55) *
а примерчик можешь дать?

Де жа вю...

//******* DELAY SUPPORT *******//
__no_init int delay_count;

void StartDelay(int t)
{ delay_count=t; }

void Delay(int t)
{ StartDelay(t); while(delay_count>0) CheckTimeAndResetWDT() ; }

void BackgroundService()
{ // Delay service
if (delay_count) delay_count--;
}

void TimerBConfiguration(void)
{ __bic_SR_register OSCOFF;
TBCTL = TBSSEL_2 + TBCLR + MC_0; // Timer B counts SMCLK clocks continuos
TBCCTL0 = CCIE; // module 0 configuration
TBCCR0 = MaxB; // period of timer overflow
TBCTL |= MC_1; // timer start to "UP" mode
};

#pragma vector=TIMERB0_VECTOR
__interrupt void TimerB_modul0()
{ __enable_interrupt();
ResetWDT1;
BackgroundService();
}


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 18 2007, 22:30
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



эм... чтото не воткну =)
выложи плиз все ф-ции. плиз

Сообщение отредактировал CAHTA_1939 - Aug 18 2007, 22:35
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 18 2007, 22:57
Сообщение #10


Гуру
******

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



Господа, вы обалдели что ли? 07.gif Судя по тому, что тема в разделе MSP430, то вопрос применительно к нему. Так про какие наносекунды гутарим-то? cranky.gif Ядро MSP430 кроме серии MSP430F2xxx может тактироваться частотой максимум 8МГц. Т.е. период клока - 125нс. Вход в прерывание - 6 тактов (>=750нс), выход из прерывания 5 тактов (>=625нс). О каком формировании интервала меньше 1,2мкс с помощью прерывания может вообще идти речь? Такие задержки на MSP430 только NOP-ами формируются! 1111493779.gif
P.S. на такт ошибся с прерываниями. Исправил.

Сообщение отредактировал rezident - Aug 18 2007, 23:21
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 18 2007, 23:06
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



вот блин... то есть задержки нужно мутить NOD'ами и осциллографом?
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 18 2007, 23:19
Сообщение #12


Гуру
******

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



Цитата(CAHTA_1939 @ Aug 19 2007, 05:06) *
вот блин... то есть задержки нужно мутить NOD'ами и осциллографом?

Можно и без осциллографа обойтись. Количество тактов за которое выполняется каждая команда в User's Manual описано. команда NOP за 1 такт выполняется. Если тактовая 8МГц, то два NOP дадут задержку 250нс, 4 NOP - 500нс. Формировать задержку с помощью прерываний имеет смысл только при временах в десятки-сотни мкс или больше.
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 19 2007, 12:54
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



ну лан, с "нс" я понял , а что делать с "мс" ? как их мутить? нужна задержка от 100мс до 1000мс с шагом примерно 20-50мс

помогите плиз
Go to the top of the page
 
+Quote Post
VAI
сообщение Aug 19 2007, 13:48
Сообщение #14


Профессионал
*****

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



Цитата
как их мутить? нужна задержка от 100мс до 1000мс с шагом примерно 20-50мс

У меня тикает прерывание каждую милисекунду и есть глобальная переменная
Код
volatile unsigned long tick_ms;        // милисекундные тики, хватит на 49 дней непрерывной работы прибора

тогда милисекундная задержка выглядит так
Код
void delay( unsigned long del )
{
  for ( del += tick_ms; del > tick_ms; )
;
}

получается от 1мс до 49 дней, с шагом 1 мс


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 19 2007, 17:53
Сообщение #15


Гуру
******

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



Цитата(VAI @ Aug 19 2007, 19:48) *
У меня тикает прерывание каждую милисекунду и есть глобальная переменная
Код
volatile unsigned long tick_ms;        // милисекундные тики, хватит на 49 дней непрерывной работы прибора

тогда милисекундная задержка выглядит так
Код
void delay( unsigned long del )
{
  for ( del += tick_ms; del > tick_ms; )
;
}

получается от 1мс до 49 дней, с шагом 1 мс

+1. Только у меня в зависимости от задачи тикает с периодом от 1мс до 32мс. Но отсчет времени все равно в мс идет. Просто инкремент тиков на величину периода происходит.
Код
#define SYSTEM_TICK_MS 10UL  //период системных тиков 10мс

tick_ms+=SYSTEM_TICK_MS; //инкремент счетчика системных тиков

Сформировать задержку очень просто
Код
unsigned long tmp=tick_ms;
while ((tick_ms-tmp)<5000); //задержка на 5 сек

При таком способе даже момент переполнения счетчика tick_ms не влияет на отсчет временного интервала, т.к. в цикле ожидания вычитание беззнаковых величин происходит.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 19 2007, 18:29
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(rezident @ Aug 19 2007, 01:57) *
Господа, вы обалдели что ли? 07.gif

ни фига себе пьяный был sad.gif Нс с мкс перепутал 05.gif Пойду лучше, а то уже пиво открыто...
Господа, делать забор на даче так приятно... Это не микроконтроллеры программировать smile.gif

Аффтар, те фукнции, что не описаны, можно считать пустыми.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 19 2007, 19:14
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



а можно поподробней. как настроить тикание =) ибо я чтото представить не могу что и как...
имею ввиду прерывание
помогите плиз +)

Сообщение отредактировал CAHTA_1939 - Aug 19 2007, 19:28
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 19 2007, 20:57
Сообщение #18


Гуру
******

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



Для кварца 8Мгц используемого в качестве источника тактирования SMCLK

Код
#define SYSTEM_TICK_MS 1UL  //период системного тика

unsigned long tick_ms;  //счетчик системных тиков

//===================================//
// функция инициализации TimerA      //
//===================================//
void initTimerA(void) //инициализация таймераА на период счета 1мс
{ TACTL=TASSEL_2 | TACLR; //TACLK=SMCLK
  TACCR0=7999; //период (7999+1)/8000000=1мс
  TACCTL0=CCIE; //разрешим прерывание от регистра сравнения CCR0
  TACTL|=MC_1;  //запускаем в режиме счета CountUp
}
//===================================//
// обработчик прерывания CCR0 TimerA //
//===================================//
#pragma vector=TIMERA0_VECTOR
#pragma type_attribute=__interrupt
void TIMERA0_ISR(void)
{ tick_ms += SYSTEM_TICK_MS; //инкремент переменной системных тиков на заданную величину
}
//===================================//
// обработчик прерывания ошибки      //
// осциллятора                       //
//===================================//
#pragma vector=NMI_VECTOR
#pragma type_attribute=__interrupt
void osc_fault(void)
{ BCSCTL2=SELM_0|DIVM_0|DIVS_0;  //MCLK=DCO, SMCLK=DCO
  DCOCTL=DCO2|DCO1|DCO0;
  BCSCTL1=DIVA_0|RSEL2|RSEL1|RSEL0;  //ACLK=LFXT
  while ((IFG1&OFIFG)!=0) IFG1&=~OFIFG;   //Ожидаем стабилиз. колебаний кварца XT2
  BCSCTL2=SELM_0|DIVM_0|DIVS_0|SELS;  //MCLK=DCO, SMCLK=XT2/1=8МГц
  IE1|=OFIE;                  //разр. прерывание от детектора ошибки
}

//===================================//
// основной суперцикл программы      //
//===================================//
#pragma type_attribute=__task
void main(void)
{ WDTCTL=WDTPW+WDTHOLD; //остановим WDTimer
  IFG1|=OFIFG; //принудительно установим флаг ошибки осциллятора
  IE1|=OFIE;  //разрешим прерывание от детектора ошибки осциллятора
  initTimerA(); //вызов функции инициализации TimerA
//
// тут ваш код
//
}
Go to the top of the page
 
+Quote Post
CAHTA_1939
сообщение Aug 19 2007, 21:52
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 11-08-07
Пользователь №: 29 713



ппц как мудрено. а попроше нет ничего? я же тока начинаю осваивать =)
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 19 2007, 22:10
Сообщение #20


Гуру
******

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



Куда уж проще-то? 07.gif И так ничего лишнего. Только main, функция инициализации таймера, функция инициализации источников тактирования (совмещенная с обработчиком прерывания от детектора ошибки осциллятора) и обработчик прерывания от таймера.
Go to the top of the page
 
+Quote Post
aag
сообщение Aug 24 2007, 06:38
Сообщение #21


Частый гость
**

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



По идее можно код обработки прерывания ошибки кварца выкинуть.

Вообще это критично или нет? Я то обычно без него обходился, но правильно ли это?
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 24 2007, 13:51
Сообщение #22


Гуру
******

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



Цитата(aag @ Aug 24 2007, 12:38) *
По идее можно код обработки прерывания ошибки кварца выкинуть.

Вообще это критично или нет? Я то обычно без него обходился, но правильно ли это?

Выкинуть-то можно, но только в случае если какая-нибудь помеха собьет генерацию, то MCLK перейдет на тактирование от DCO (и скорее всего с понижением частоты тактирования, если кварц на частоту выше 5,5МГц стоит), а SMCLK не будет вообще, если его источником был кварцевый генератор.
Go to the top of the page
 
+Quote Post
FREEKER
сообщение Sep 12 2007, 19:25
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 24-06-06
Пользователь №: 18 330



Вот очень элементарный пример задержки smile.gif
Функция Delay() - небольшая задержка в 550мкс и функция Big_Delay() - несколько секунд, а мож и больше smile.gif зависит от Delay() также. При кварце 8MHz.

Код
void Delay(void)
{
unsigned int t;
for (t=730; t>0; t--);          //(4 такта For)
}

void Big_Delay(void)
{
unsigned int y;
for (y=5000; y>0; y--)
Delay();
}


Но с таймером мне тоже не всё понятно. Разъясните. Как сделать следующее. Допустим тикает таймер. Нужно остановить его и замерить время по приходу на порт P2.2 логической "1", т.е. по перепаду с 0 на 1. или наоборот.
Flag = P2IFG & 0x04; //Устанавливается флаг при перепаде 1>0
Либо замерить время единичного импулься. т.е. по перепадам 0-1 и 1-0.
Можно пример!? На примере понятней, особенно с коментами.
beer.gif
Rezident. Вам отдельная благодарность.
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 12 2007, 20:40
Сообщение #24


Гуру
******

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



Цитата(FREEKER @ Sep 13 2007, 01:25) *
Но с таймером мне тоже не всё понятно. Разъясните. Как сделать следующее. Допустим тикает таймер. Нужно остановить его и замерить время по приходу на порт P2.2 логической "1", т.е. по перепаду с 0 на 1. или наоборот.

Ну для этого таймер останавливать не обязательно. Используйте функцию захвата таймера.
Код
#define CAP_TICKOVFCNTR 0x00010000

volatile unsigned long smplTime, smplOvfCntr;

//================================================//
// Инициализация таймера захвата входной частоты  //
//------------------------------------------------//
//аргументы :нет                                  //
//возвращает:нет                                  //
//================================================//
void initTimerCAP(void)
{ TACTL=TASSEL_2|ID_0|TAIE|TACLR;                 //TACLK=SMCLK/1, прерыв. от переполнения
                                                  //разрешено
  TACCR0=0;                                       //результат захвата
  TACCTL0=CM_1|CCIS_1|CAP;                        //режим захвата по нараст. фронту
                                                  //вход захвата CCI0B (P2.2)
  P2SEL|=BIT2;                                    //P2.2 - CCI0B
  P2DIR&=~BIT2;                                   //P2.2 - вход
  TACTL|=MC_2;                                    //пуск в режиме Continous
}
//================================================//
// Запуск таймера сэмплирования                   //
//------------------------------------------------//
//аргументы :нет                                  //
//возвращает:текущую метку времени                //
//================================================//
unsigned long fStartTimerCap(void)
{ unsigned int buf;
  TACCTL0=CM_3|CCIS_3|CAP;                        //режим захвата по любому фронту
                                                  //вход захвата=VCC
  TACCTL0^=CCIS0;                                 //формируем программно перепад
  buf=TACCR0;                                     //получаем текущее значение TAR
  TACCTL0=CM_1|CCIS_1|CAP;                        //режим захвата по нараст. фронту
  smplTime=smplOvfCntr+buf;                       //получим текущую временную метку
  TACCTL0|=CCIE;                                  //разрешим прерывание при захвате
  return(smplTime);
}
//================================================//
// Обработчик прерывания таймера сэмплирования    //
//------------------------------------------------//
//аргументы :нет                                  //
//возвращает:нет                                  //
//================================================//
#pragma vector=TIMERA0_VECTOR
#pragma type_attribute=__interrupt
void TimerA0_ISR(void)
{ unsigned int buf;
  buf=TACCTL0;                                    //временная метка захвата
  smplTime=smplOvfCntr+buf;                       //просуммирует с таймером переполнений
  TACCTL0&=~CCIE;                                 //сбросим разреш. прерывания захвата
}
//================================================//
// Обработчик прерывания переполнений таймера     //
//------------------------------------------------//
//аргументы :нет                                  //
//возвращает:нет                                  //
//================================================//
#pragma vector=TIMERA1_VECTOR
#pragma type_attribute=__interrupt
void TimerA1_ISR(void)
{ switch(TAIV)
  { default:
    case 0x02:
    case 0x04:
      break;
    case 0x0A:
      smplOvfCntr+=CAP_TICKOVFCNTR;               //инкремент счетчика переполнений
      break;
  }
}

Таймер в моем примере считает постоянно на максимальной частоте SMCLK c переполнением (от 0 до 0xFFFF и дальше). Чтобы расширить измеряемый временной интервал введена 32-битная переменная smplTime, которая суммируется с 32-битным счетчиком переполнений smplOvfCntr. Максимальный временной интервал измеряемый при этом может быть вычислен как число 0xFFFFFFFF деленное на значение частоты SMCLK. Для SMCLK=8MHz этот интервал составляет почти 9 минут.
initTimerCAP - функция начальной инициализации ТаймераА
fStartTimerCap - функция запуска периода ожидания срабатывания ловушки перехода 0->1 на входе P2.2. Она возвращает начальную метку времени. После ее запуска нужно ожидать сброса бита разрешения прерывания CCIE в регистре TACCTL0. Сброс бита будет означать, что ловушка сработала и в переменной smplTime мы имеет соответствующую метку времени. Разница между текущим значением smplTime и значением которая вернула функция fStartTimerCap будет искомым интервалом ожидания от момента запуска до срабатывания ловушки. Для пересчета этой величины в привычные секунды smplTime нужно поделить на значение тактирующей частоты SMCLK.
P.S. еще пояснение. "Хитрая" манипуляция в функции fStartTimerCap
Код
  TACCTL0=CM_3|CCIS_3|CAP;
  TACCTL0^=CCIS0;

обсуловлена тем, что в общем случае MCLK и SMCLK могут быть асинхронными. Например, MCLK от DCO тактируется, а SMCLK от кварцевого генератора. Если при таких условиях попытаться впрямую считать значение TAR без останова таймера, то можно получить неверное значение.
Go to the top of the page
 
+Quote Post
a1ex
сообщение Dec 3 2007, 16:47
Сообщение #25





Группа: Новичок
Сообщений: 13
Регистрация: 29-11-07
Из: Jurmala
Пользователь №: 32 821



Вот я задержку пишу так:

void delay(unsigned int a)
{unsigned int k;
for(k=0;k!=a;++k)
{
}

Ну и соответсвенно, чтобы точно задержку задать, приходиться смотреть осцилографом, и все время значение а подгонять.. Может кто знает как вычислить сколько такой цикл занимает тактов?
Пример: а =10000;(MCLK) DCO = ~800kHz;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 3 2007, 17:22
Сообщение #26


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(a1ex @ Dec 3 2007, 18:47) *
Может кто знает как вычислить сколько такой цикл занимает тактов?
Во-первых объявлять k как volatile (иначе при высоком уровне оптимизации цикл может быть выкинут вообще). Во-вторых сгенерить листинт, посмотреть, из каких команд складывается цикл, в даташите посмотреть количество тактов, за которое выполняется каждая команда, дальше простая арифметика.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 28th July 2025 - 09:31
Рейтинг@Mail.ru


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