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

Господа, вы обалдели что ли? :07:

ни фига себе пьяный был :( Нс с мкс перепутал :05: Пойду лучше, а то уже пиво открыто...

Господа, делать забор на даче так приятно... Это не микроконтроллеры программировать :)

 

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

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


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

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

имею ввиду прерывание

помогите плиз +)

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

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


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

Для кварца 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
//
// тут ваш код
//
}

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


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

ппц как мудрено. а попроше нет ничего? я же тока начинаю осваивать =)

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


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

Куда уж проще-то? :07: И так ничего лишнего. Только main, функция инициализации таймера, функция инициализации источников тактирования (совмещенная с обработчиком прерывания от детектора ошибки осциллятора) и обработчик прерывания от таймера.

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


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

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

 

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

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


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

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

 

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

Выкинуть-то можно, но только в случае если какая-нибудь помеха собьет генерацию, то MCLK перейдет на тактирование от DCO (и скорее всего с понижением частоты тактирования, если кварц на частоту выше 5,5МГц стоит), а SMCLK не будет вообще, если его источником был кварцевый генератор.

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


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

Вот очень элементарный пример задержки :)

Функция Delay() - небольшая задержка в 550мкс и функция Big_Delay() - несколько секунд, а мож и больше :) зависит от 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:

Rezident. Вам отдельная благодарность.

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


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

Но с таймером мне тоже не всё понятно. Разъясните. Как сделать следующее. Допустим тикает таймер. Нужно остановить его и замерить время по приходу на порт 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 без останова таймера, то можно получить неверное значение.

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


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

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

 

void delay(unsigned int a)

{unsigned int k;

for(k=0;k!=a;++k)

{

}

 

Ну и соответсвенно, чтобы точно задержку задать, приходиться смотреть осцилографом, и все время значение а подгонять.. Может кто знает как вычислить сколько такой цикл занимает тактов?

Пример: а =10000;(MCLK) DCO = ~800kHz;

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


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

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

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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