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

Помогите разобраться с таймером

Реализовать при 12МГц задержку в 3 секунды возможно? если можно пример :laugh:
Да хоть на 300 секунд. ;) Примерно так.

#include	<msp430x24x.h>
#include	<stdint.h>

#define	FREQ_TACLK		12000000UL				//TimerA clock frequency
#define	LED_OUT				(1U<<0)						//P1.0 - LED output
#define	PULSE_IN			(1U<<2)						//P1.2 - Pulse Input (CCI1A)
#define	DELAY_LEDOUT	(FREQ_TACLK*3UL)	//Value ticks of TimerA = 3s*12MHz

int main(void)
{	WDTCTL = WDTPW | WDTHOLD;
/* Basic Clock module */	
BCSCTL3 = LFXT1S_3;
DCOCTL = CALDCO_12MHZ;
BCSCTL1 = CALBC1_12MHZ | XT2OF;
BCSCTL2 = 0;
/* Port1 input/output */
P1DIR = LED_OUT;
P1SEL = PULSE_IN;
P1OUT	= 0;
/* TimerA */
TACTL = TASSEL_2 | TACLR | TAIE;
TACCTL0 = 0;
TACCTL1 = CM_3 | CCIS_0 | SCS | CAP | CCIE;
TACCTL2 = 0;
TACTL |= MC_2;

__enable_interrupt();

for (;;)
{ 
	__bic_SR_register(LPM0_bits);
	__no_operation();
}
}

#pragma vector=TIMERA1_VECTOR
#pragma type_attribute=__interrupt
void TIMERA_ISR(void)
{	static uint32_t timeCntr, timeDly;
static uint16_t flag;
uint16_t CCRVal;

switch(TAIV)
{	case 0x02:					//TACCR1 vector, capture P1.2
		CCRVal=TACCR1;			
		timeDly=timeCntr + DELAY_LEDOUT + CCRVal;
		flag = 1;
		TACCTL1 &= ~CCIE;
		break;
	case 0x04:					//TACCR2 vector, compare
		P1OUT ^= LED_OUT;
		TACCTL2 &= ~CCIE;
		TACCTL1 |= CCIE;
		break;
	case 0x0A:					//TAR overflow vector, overflow counter
		timeCntr += 1UL<<16;
		if (flag != 0)
		{	if ((timeDly - timeCntr) < (1UL<<16))
			{	CCRVal=(uint16_t)(timeDly - timeCntr);
				TACCR2 = CCRVal;
				TACCTL2 |= CCIE;
				flag = 0;
			}
		}
		break;
	default:
		break;
}
}

P1.0 - выход, к которому подключен светодиод.

P1.2 - вход управления.

По любому перепаду уровня (1->0 или 0->1) на входе P1.2 через установленное время (в примере - 3 сек) светодиод на выходе P1.0 переключится в противоположное состояние. В это время вход P1.2 нечувствителен к перепадам уровня.

Весь функционал реализован на аппаратуре таймера A.

Используется вход захвата CCI1A (P1.2 для MSP430F24x), перепад на котором вызывает захват (capture) значения TAR и запись его в CCR1. При этом в преывании вычисляется величина временной отметки timeDly, отстоящая от данного события на установленное время задержки (3 сек в отсчетах таймера на частоте 12МГц).

CCR2 используется в режиме сравнения (compare) для более точного задания времени задержки.

Прерывание от переполнения используется для расширения разрядности таймера. По переполнению 32-х разрядный счетчик timeCntr инкрементируется на величину разрядности таймера (65536). При установленном флаге flag текущее значение timeDly сравнивается с временной отметкой timeCntr. Если разница укладывается в разрядность таймера (меньше, чем 65536), то остаток разности заносится в CCR2 и разрешается прерывание при событии совпадения TAR и CCR2.

Далее при наступлении события совпадения TAR и CCR2 в прерывании переключается состояние светодиода на пине P1.0 и вновь активируется вход управления.

Точность установки задержки примерно в 20 тактов, которые можно учесть при ее вычислении.

В этом примере есть один нюанс, влияющий на точность задержки, про который я пока умолчу. Если (тщательно изучая мануал) поймете и правильно сформулируете вопрос, то поясню как эту багу можно обойти. :)

P.S. в железе не проверялось :laughing:

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


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

Скажите, какой минимальный набор команд нужен, чтобы Таймер А считал в инкрементальном режиме до определенного числа?

 

Исходя из документации делаю так:

TACCR0 = 0x100; //Задаем модуль счета таймера

TACTL = 0x110; //Задаем MC0 = 1, то есть запускаем счетчик в режиме "вверх",

//Задаем TASSEL0 = 1, то есть задаем источник импульсов.

 

Но в итоге регистр TAR никак не меняется. Кажется я чего-то не понимаю

 

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


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

Исходя из документации делаю так:

TACCR0 = 0x100; //Задаем модуль счета таймера

TACTL = 0x110; //Задаем MC0 = 1, то есть запускаем счетчик в режиме "вверх",

//Задаем TASSEL0 = 1, то есть задаем источник импульсов.

Неправильно. Сначала следует проинициализировать регистры таймера (TASSEL и TACCR0) и только потом запускать счет, установив бит MC0 в TACTL. Т.е. минимально три команды. Хотя я предпочитаю все значащие регистры проинициализировать так, чтобы исключить "случайно возникающие" прерывания (от CCR0, CCR1, CCR2), которые программой не предусмотрены.

TACTL = TASSEL0 | TACLR; // ACLK/1 в качестве входного клока, сброс TAR, прерывание от переполнения запрещено
TACCR0 = 0x100 - 1; //без единицы, т.к. состояние 0x0000 тоже считается
TACCTL0 = 0; //режим сравнения, запрет прерывания от CCR0
TACCTL1 = 0; //режим сравнения, запрет прерывания от CCR1
TACCTL2 = 0; //режим сравнения, запрет прерывания от CCR2
TACTL |= MC0; //запуск счета, режим CountUp

Но в итоге регистр TAR никак не меняется. Кажется я чего-то не понимаю
В железе или в симуляторе? В симуляторе IAR периферия не симулируется!

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


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

В железе или в симуляторе? В симуляторе IAR периферия не симулируется!

 

Оу! А как же тогда проверить работу алгоритма на логику если нет железа?

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


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

Оу! А как же тогда проверить работу алгоритма на логику если нет железа?

 

Спаять макетку и проверять

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


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

Ага, понятно) Спасибо за помощь)

Еще такой вопрос, а в прерывания по таймеру программа тоже заходить не будет?

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


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

Еще такой вопрос, а в прерывания по таймеру программа тоже заходить не будет?
В симуляторе можно "вручную" имитировать вызов прерываний Simulator -> Forced Interrupt или настроить макрос для симуляции вызова Simulator -> Interrupt Setup.

 

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


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

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

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

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

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

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

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

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

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

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