Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MSP430g2553 TA.1.2
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
A_lex_sander
Нужно таймером померять частоту( временные интервалы ) на " лапке " кто знает как это сделать подскажите
adnega
Цитата(A_lex_sander @ Jun 13 2014, 19:47) *
Нужно таймером померять частоту( временные интервалы ) на " лапке " кто знает как это сделать подскажите

В зависимости от диапазона измеряемой частоты решения могут быть различными.
Опишите задачу по-подробнее (частота от и до, точность, быстродействие), так и решение быстрее найдется.
A_lex_sander
надо таймером отличать частоты 20 и 22 килогерца
thrush007
Настраиваете тактирование таймера-счетчика и выбираете режим счета "вверх до переполнения" в регистре TA1CTL. Потом выбираете режим захвата, захват по нарастающему (или спадающему) фронту, синхронный захват в регистре TA1CCTLx. Запускаете таймер. Теперь по фронту сигнала на выводе CCIxA в регистре TA1CCRx будет защелкиваться значение таймера-счетчика и вызываться прерывание. При первом прерывании надо сбросить (и обнулить) таймер-счетчик и опять его запустить. При втором прерывании считать значение регистра TA1CCRx (это будет период сигнала на выводе CCIxA) и сбросить, обнулить, запустить опять таймер. И так далее.
A_lex_sander
Цитата(thrush007 @ Jun 13 2014, 23:55) *
Настраиваете тактирование таймера-счетчика и выбираете режим счета "вверх до переполнения" в регистре TA1CTL. Потом выбираете режим захвата, захват по нарастающему (или спадающему) фронту, синхронный захват в регистре TA1CCTLx. Запускаете таймер. Теперь по фронту сигнала на выводе CCIxA в регистре TA1CCRx будет защелкиваться значение таймера-счетчика и вызываться прерывание. При первом прерывании надо сбросить (и обнулить) таймер-счетчик и опять его запустить. При втором прерывании считать значение регистра TA1CCRx (это будет период сигнала на выводе CCIxA) и сбросить, обнулить, запустить опять таймер. И так далее.


Сделал как ты сказал , заработало в прерывание попадаю , но вне зависимости от частоты заначение TAR счетного регистра одно и тоже

Вот моя настройка

{
TA1CCR0 = time;
TA1CCR2 =(unsigned int )time/2;
TA1CCTL2 = OUTMOD_4+CM_1+CCIE+CCIS1+SCS ;
TA1CTL = TASSEL_2| MC_1;
}

потом я попадаю в прерывание


#pragma vector=TIMER1_A1_VECTOR
__interrupt void Timer1_A1 (void)
{
uint16_t currentValue = TAR; // тут смотрю в дебагере значение счетчика
uint16_t currentValue = TA1CCR2;

}
значения TAR и TA1CCR2 почемуто от частоты не зависят



thrush007
Цитата(A_lex_sander @ Jun 16 2014, 17:18) *
Сделал как ты сказал , заработало в прерывание попадаю , но вне зависимости от частоты заначение TAR счетного регистра одно и тоже

Вот моя настройка

{
TA1CCR0 = time;
TA1CCR2 =(unsigned int )time/2;
TA1CCTL2 = OUTMOD_4+CM_1+CCIE+CCIS1+SCS ;
TA1CTL = TASSEL_2| MC_1;
}

потом я попадаю в прерывание


#pragma vector=TIMER1_A1_VECTOR
__interrupt void Timer1_A1 (void)
{
uint16_t currentValue = TAR; // тут смотрю в дебагере значение счетчика
uint16_t currentValue = TA1CCR2;

}
значения TAR и TA1CCR2 почемуто от частоты не зависят



Ты забыл установить бит CAP в регистре TA1CCTL2 (режим захвата). В русском переводе даташита ошибка.
A_lex_sander
поставил CAP теперь в прерывание не заходит sad.gif
thrush007
Цитата(A_lex_sander @ Jun 16 2014, 18:29) *
поставил CAP теперь в прерывание не заходит sad.gif


CCIS1 - что означает? Проверь, на какой вывод МК надо подавать сигнал. Регистры PxSEL, PxSEL2 как установлены?
A_lex_sander
void main(void)
{
unsigned int a=0;

WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
P1SEL|=BIT6+BIT7;
P1SEL2|=BIT6+BIT7;

P2DIR &= ~(BIT2 | BIT3 | BIT4 | BIT5);
P2REN |= BIT2 | BIT3 | BIT4 | BIT5;
P2OUT |= BIT2 | BIT3 | BIT4 | BIT5;
P2SEL|=BIT5;

P3DIR &= ~(BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT6 | BIT7);
P3REN |= BIT0 | BIT1 | BIT2 | BIT4 | BIT5 |BIT7;
P3OUT |= BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT7;


Set_DCO();

}
__enable_interrupt();

ADC_init();

freq ( 100 );
while(1)
{
}

}

void freq (unsigned int time)
{
TA1CCR0 = time;
TA1CCR2 =(unsigned int )time/2;
TA1CCTL2 = OUTMOD_4+CM_1+CCIE+CCIS1+SCS ;
TA1CTL = TASSEL_2| MC_1;
}

#pragma vector=TIMER1_A1_VECTOR
__interrupt void Timer1_A1 (void)
{
uint16_t currentValue = TA1CCR2;
last =TA1R;
TA1R = 0;
old=last;

}
вроде все установлено
thrush007
Цитата(A_lex_sander @ Jun 16 2014, 18:46) *
void main(void)
{
unsigned int a=0;

WDTCTL = WDTPW + WDTHOLD; // Stop WDT
{
P1SEL|=BIT6+BIT7;
P1SEL2|=BIT6+BIT7;

P2DIR &= ~(BIT2 | BIT3 | BIT4 | BIT5);
P2REN |= BIT2 | BIT3 | BIT4 | BIT5;
P2OUT |= BIT2 | BIT3 | BIT4 | BIT5;
P2SEL|=BIT5;

P3DIR &= ~(BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT6 | BIT7);
P3REN |= BIT0 | BIT1 | BIT2 | BIT4 | BIT5 |BIT7;
P3OUT |= BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT7;


Set_DCO();

}
__enable_interrupt();

ADC_init();

freq ( 100 );
while(1)
{
}

}

void freq (unsigned int time)
{
TA1CCR0 = time;
TA1CCR2 =(unsigned int )time/2;
TA1CCTL2 = OUTMOD_4+CM_1+CCIE+CCIS1+SCS ;
TA1CTL = TASSEL_2| MC_1;
}

#pragma vector=TIMER1_A1_VECTOR
__interrupt void Timer1_A1 (void)
{
uint16_t currentValue = TA1CCR2;
last =TA1R;
TA1R = 0;
old=last;

}
вроде все установлено


А на какой вывод сигнал подаешь?
A_lex_sander
Р.2.5
thrush007
Цитата(A_lex_sander @ Jun 16 2014, 18:55) *
Р.2.5


Надо на вход захвата сигнал подавать. Посмотри на распиновку выводов (таблица 2 из даташита). CCI1A input - P1.2, CCI0A input - P2.0. ПОсмотри еще, что у тебя биты CCISx задают.
A_lex_sander
Цитата(thrush007 @ Jun 16 2014, 18:12) *
Надо на вход захвата сигнал подавать. Посмотри на распиновку выводов (таблица 2 из даташита). CCI1A input - P1.2, CCI0A input - P2.0. ПОсмотри еще, что у тебя биты CCISx задают.

Выставлены правильно(CCI2B) это как бы проверял.
thrush007
Цитата(A_lex_sander @ Jun 17 2014, 11:38) *
Выставлены правильно(CCI2B) это как бы проверял.


Можно попробовать отключить подтяжку от вывода P2.5.
A_lex_sander
Цитата(thrush007 @ Jun 17 2014, 15:52) *
Можно попробовать отключить подтяжку от вывода P2.5.

Делал не помогло.
У вас случаем нет примера рабочего такого типа (я понимаю что такая просьба наглость ,но.. ) просто все, что можно попробывал уже .
thrush007
Цитата(A_lex_sander @ Jun 17 2014, 18:43) *
Делал не помогло.
У вас случаем нет примера рабочего такого типа (я понимаю что такая просьба наглость ,но.. ) просто все, что можно попробывал уже .


Примера на захват нету, но могу попробовать ваш пример на плате погонять. Прикрепите main.
A_lex_sander
Прикрепил весь проект спс за помощ
thrush007
Цитата(A_lex_sander @ Jun 17 2014, 19:11) *
Прикрепил весь проект спс за помощ


Посмотрел твой проект, решил создать новый sm.gif Надо отлаживать новую периферию по частям, а не пытаться завести проект с АЦП, таймером, UART, режимами сна и т.д. Привожу рабочий код из CCSv5, по фронту на P2.5 значение таймера-счетчика записывается в TA1CCR2 и меняется состояние светодиода на P1.0.


#include "msp430g2553.h"

void main(void)
{

WDTCTL = WDTPW + WDTHOLD; // Отключение сторожевого таймера

// Тактирование микроконтроллера от встроенного
// генератора с калибровкой на 16 МГц
// основной тактовый сигнал MCLK от DCOCLK

BCSCTL1 = CALBC1_16MHZ; // basic clock system
BCSCTL2 = DIVS0; // тактирование MCLK без предделителя, тактирование SMCLK = 16/2 MHz
DCOCTL = CALDCO_16MHZ; // digital controlled oscillator

P1OUT = 0x00;
P2OUT = 0x00; // не сбрасываются после перезапуска
P3OUT = 0x00;

P1SEL = 0x00; // Все выводы портов 1,2 настроить как линии портов ввода-вывода
P1SEL2 = 0x00;
P2SEL = 0x00;
P2SEL2 = 0x00;

P2SEL2 |= BIT5; // вывод P2.5 использовать как вывод основного периферийного модуля

P1DIR = 0xFF; // All P1.x outputs
P1REN = 0x00; // отключение внутренних подтягивающих резисторов от всех выводов порта 1
P1OUT = 0x00; // All P1.x reset

P2DIR = 0xFF; // Все выводы порта 2 настроить как выходы
P2REN = 0x00; // отключение внутренних подтягивающих резисторов от всех выводов порта 2
P2OUT = 0x00; // All P2.x reset

TA1CCTL2 = CM_1 + CCIS_1 + SCS + SCCI + CAP + CCIE;
// CM_1 (1*0x4000u) Capture mode: 1 - pos. edge
// CCIS_1 (1*0x1000u) Capture input select: 1 - CCIxB

TA1CTL = TASSEL_2 | ID_3 | TACLR; // настройка таймера 1
// TASSEL_2 - тактирование таймера-счетчика от SMCLK (8 МГц)
// ID_3 - коэффициент предделителя для тактового сигнала таймера-счетчика равен 8

TA1CTL |= MC_2; // запуск, счет вверх до переполнения
__enable_interrupt(); // общее разрешение прерываний

while (1);

}

#pragma vector = PORT1_VECTOR

__interrupt void PORT1_ISR(void)
{
return;
}

#pragma vector = PORT2_VECTOR
__interrupt void P2_ISR (void)

{
return;
}

#pragma vector = TIMER1_A0_VECTOR
__interrupt void T1_CCR0_ISR(void)
{

// Код обработки прерывания от таймера-счетчика 1 при равенстве TA1R = TA1CCR0

return;
}

#pragma vector = TIMER1_A1_VECTOR
__interrupt void T1_CCR1_ISR(void) // общее прерывание для регистров захвата/сравнения TA1CCR1 и TA1CCR2.
{

TA1IV = 0x00;
P1OUT ^= BIT0;
return;

}

#pragma vector = TIMER0_A0_VECTOR
__interrupt void T0_CCR0_ISR(void)
{
return;
}

#pragma vector = TIMER0_A1_VECTOR
__interrupt void T0_CCR1_ISR(void)
{
return;
}


// Обработчики неиспользуемых прерываний

#pragma vector = ADC10_VECTOR

__interrupt void ADC_ISR(void)
{
return;
}

#pragma vector = COMPARATORA_VECTOR

__interrupt void COMPARATORA_ISR(void)
{
return;
}

// Echo back RXed character, confirm TX buffer is ready first
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
IFG2 = 0x00; // обнуление регистра флагов прерываний окончания приема или передачи UART
return;
}

#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
IFG2 = 0x00;
return;
}


#pragma vector=WDT_VECTOR // прерывание от сторожевого таймера
__interrupt void watchdog_timer (void)
{
return;
}

#pragma vector=NMI_VECTOR // вектор немаскируемого прерывания по активному фронту на выводе ~RST
__interrupt void nmi_ (void)
{
return;
}

A_lex_sander
Цитата(thrush007 @ Jun 17 2014, 20:36) *
Посмотрел твой проект, решил создать новый sm.gif Надо отлаживать новую периферию по частям, а не пытаться завести проект с АЦП, таймером, UART, режимами сна и т.д. Привожу рабочий код из CCSv5, по фронту на P2.5 значение таймера-счетчика записывается в TA1CCR2 и меняется состояние светодиода на P1.0.


#include "msp430g2553.h"

void main(void)
{

WDTCTL = WDTPW + WDTHOLD; // Отключение сторожевого таймера

// Тактирование микроконтроллера от встроенного
// генератора с калибровкой на 16 МГц
// основной тактовый сигнал MCLK от DCOCLK

BCSCTL1 = CALBC1_16MHZ; // basic clock system
BCSCTL2 = DIVS0; // тактирование MCLK без предделителя, тактирование SMCLK = 16/2 MHz
DCOCTL = CALDCO_16MHZ; // digital controlled oscillator

P1OUT = 0x00;
P2OUT = 0x00; // не сбрасываются после перезапуска
P3OUT = 0x00;

P1SEL = 0x00; // Все выводы портов 1,2 настроить как линии портов ввода-вывода
P1SEL2 = 0x00;
P2SEL = 0x00;
P2SEL2 = 0x00;

P2SEL2 |= BIT5; // вывод P2.5 использовать как вывод основного периферийного модуля

P1DIR = 0xFF; // All P1.x outputs
P1REN = 0x00; // отключение внутренних подтягивающих резисторов от всех выводов порта 1
P1OUT = 0x00; // All P1.x reset

P2DIR = 0xFF; // Все выводы порта 2 настроить как выходы
P2REN = 0x00; // отключение внутренних подтягивающих резисторов от всех выводов порта 2
P2OUT = 0x00; // All P2.x reset

TA1CCTL2 = CM_1 + CCIS_1 + SCS + SCCI + CAP + CCIE;
// CM_1 (1*0x4000u) Capture mode: 1 - pos. edge
// CCIS_1 (1*0x1000u) Capture input select: 1 - CCIxB

TA1CTL = TASSEL_2 | ID_3 | TACLR; // настройка таймера 1
// TASSEL_2 - тактирование таймера-счетчика от SMCLK (8 МГц)
// ID_3 - коэффициент предделителя для тактового сигнала таймера-счетчика равен 8

TA1CTL |= MC_2; // запуск, счет вверх до переполнения
__enable_interrupt(); // общее разрешение прерываний

while (1);

}

#pragma vector = PORT1_VECTOR

__interrupt void PORT1_ISR(void)
{
return;
}

#pragma vector = PORT2_VECTOR
__interrupt void P2_ISR (void)

{
return;
}

#pragma vector = TIMER1_A0_VECTOR
__interrupt void T1_CCR0_ISR(void)
{

// Код обработки прерывания от таймера-счетчика 1 при равенстве TA1R = TA1CCR0

return;
}

#pragma vector = TIMER1_A1_VECTOR
__interrupt void T1_CCR1_ISR(void) // общее прерывание для регистров захвата/сравнения TA1CCR1 и TA1CCR2.
{

TA1IV = 0x00;
P1OUT ^= BIT0;
return;

}

#pragma vector = TIMER0_A0_VECTOR
__interrupt void T0_CCR0_ISR(void)
{
return;
}

#pragma vector = TIMER0_A1_VECTOR
__interrupt void T0_CCR1_ISR(void)
{
return;
}


// Обработчики неиспользуемых прерываний

#pragma vector = ADC10_VECTOR

__interrupt void ADC_ISR(void)
{
return;
}

#pragma vector = COMPARATORA_VECTOR

__interrupt void COMPARATORA_ISR(void)
{
return;
}

// Echo back RXed character, confirm TX buffer is ready first
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
IFG2 = 0x00; // обнуление регистра флагов прерываний окончания приема или передачи UART
return;
}

#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
IFG2 = 0x00;
return;
}


#pragma vector=WDT_VECTOR // прерывание от сторожевого таймера
__interrupt void watchdog_timer (void)
{
return;
}

#pragma vector=NMI_VECTOR // вектор немаскируемого прерывания по активному фронту на выводе ~RST
__interrupt void nmi_ (void)
{
return;
}


все хорошо кроме одного частота на Р.1.0 есть всегда sad.gif что это за частота такая ?
почему то стабильно держит частоту 27 кГц а должен 22 к видеть и частота 27 не меняется от частоты 22 .
thrush007
Цитата(A_lex_sander @ Jun 18 2014, 10:41) *
все хорошо кроме одного частота на Р.1.0 есть всегда sad.gif что это за частота такая ?
почему то стабильно держит частоту 27 кГц а должен 22 к видеть и частота 27 не меняется от частоты 22 .


Изменение состояния вывода P1.0 в прерывании я сделал просто для отладки, чтобы видеть, заходит МК в прерывание или нет. В этом примере шаг таймера 1 мкс (тактирование от 1 МГц). Для измерения временных интервалов в десятки мкс лучше увеличить разрешающую способность таймера, т.е. коэффициент предделителя тактового сигнала сделать не 8, а 1 или 2. И тогда уже смотреть на регистр TA1CCR2.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.