Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с точностью таймера
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
Серега
msp430f149. На одну из ног повешен светодиод для контроля. По прерыванию от timerA, работающего на непрерывный счет, меняю состояние светодиода на противоположное. Проблема в том что частота переключения иногда меняется, т.е. например, 3 раза мигнул нормально, 2 раза быстрее, дальше опять все нормально, потом частота может уменьшится. Таймер тактируется от кварца, частота счета ~1Гц.
И еще: в user manual написано, что таймер в непрерывном режиме может считать от нуля до 0xFFFF, сбрасывается в нуль и опять по новой. Так вот такого я не заметил, по не добавил в прерывание таймера инициализацию таймера. Это так и надо?

И еще: когда прогоняю этот код в IAR С-Spy, то при выходе из прерывания програмный счетчик переходит неизвестно куда и приходится каждый раз перегружать проц.

IAR C/C++ Compiler for MSP430 V3.21A/W32 [Kickstart] (3.21.1.3)
IAR C-SPY Emulator Driver for MSP430
V3.21A/W32 [Kickstart] (3.21.1.3)

Помогите пожалуйста, а то забодался уже совсем. Неделю сидел разбирался и ничего sad.gif


Вот код на icc430 6.07A
Цитата
//ICC-MSP application builder [F149] : 14.10.2005 0:40:13
//Target 14x device

#include <msp430x14x.h>
#include <msp430def.h>

void clock_init()
{
    //DCO=0x00
    DCOCTL=0x00;
    BCSCTL2=0x08;//SELS
    BCSCTL1=0x00;//XTS
}

void timera_init()
//Clock source=SMCLK
//Divider=8
//TIMACLK=460,800KHz
//Frequency=7,0Hz (142,22mS)
{
    TACTL=0x00; //stop timer
    //channel0
    TACCTL0=0x00;
    TACCR0=0xFFFF;
    //channel1
    TACCTL1=0x00;
    TACCR1=0x00;
    //channel2
    TACCTL2=0x00;
    TACCR2=0x00;
    TAR=0x0000;//clear timer counter
    TACTL=0x2E6;//TASSEL.1,TAID.1,TAID.0,TAMC.1,1,TAIE
}

//call this routine to initialise all peripherals
void init_devices(void)
{
    //stop errant interrupts until set up
    DINT(); //disable all interrupts
    ME1=0X00; //disable sfr peripherals
    ME2=0X00;
    IE1=0x00; //disable sfr interrupts
    IE2=0x00;
    //watchdog initialisation including nmi function
    //WDTCTL=0x5A00 | 0x00;
    WDTCTL = WDTPW + WDTHOLD;
    //initialise other peripherals
    clock_init();
    //port_init();
    timera_init();

    ME1=0x00;
    ME2=0x00;
    IE1=0x00;
    IE2=0x00;

    P4DIR = 0xFF;
    P4SEL = 0x00;
    P4OUT = 0x00;
    P4OUT = 0x02;
    EINT(); //re-enable interrupts
}

#pragma interrupt_handler timera_1_isr:TIMERA1_VECTOR
void timera_1_isr(void)
{  
    TACTL=0x00; //stop timer
    //channel0
    TACCTL0=0x00;
    TACCR0=0xFFFF;
    TAR=0x0000;//clear timer counter
    TACTL=0x126;//TASSEL.0,TAMC.1,1,TAIE

    P4OUT ^= 0x02;
}

void main(void)
{
    init_devices();
while(1);
}
rezident
Ё-моё! Как все запущено! Читайте в UM внимательно раздел про Timer_A, а если с аглицким неважно, то вот перевод. Особенно про разные режимы работы таймера и вектора прерываний. Обращу лишь ваше внимание на тот факт, что у таймера есть два вектора прерывания. Вектор с адресом TIMERA0_VECTOR имеет источником событие совпадения значений TAR и TACCR0. Все остальные события могут вызывать другой вектор с адресом TIMERA1_VECTOR. При переходе на этот вектор нужно дополнительно определять источник события вызвавшего прерывание (от TACCR1, от TACCR2, переполнение (перезагрузка) TAR и пр.). Самый простой способ огранизовать программную "ногодрыгалку" с заданным периодом это задать полупериод в регистре CCR0, разрешить прерывание от CCR0 и запустить таймер в режиме Count_UP. Тогда будет вызываться вектор с адресом TIMERA0_VECTOR, а в обработчике этого прерывания будет единственная команда инвертирования состояния светодиода. Весь текст приводить лень. Вот лишь фрагменты.

Код
TACTL=TASSEL_2+ID_2+TACLR; // SMCLK как TACLK=SMCLK/4, сброс
TACCR0=57599; // период перезагрузки 0.5сек: =(0,5c*(460800Гц/4)-1)
TACCTL0=CCIE; // разрешим прерывание от CCR0
TACTL|=MC_1; // запустим таймер в режиме Count_UP
_EINT();


Код
#pragma vector=TIMERA0_VECTOR
__interrupt void Nogodryg (void)
{ P4OUT ^= BIT1;
}


Все остальные источники прерываний должны быть запрещены.
И еще совет. Раз уж вы пользуетесь обозначениями регистров предложенными TI, то пользуйтесь также и обозначениями битов от TI. Так будет проще воспринимать текст программы.
Серега
Вот спасибо, особенно за http://www.gaw.ru/html.cgi/txt/doc/micros/msp430/index.htm
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.