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

 
 
> MSP430 + Timer + Interrupt, Вопросы
Niketa
сообщение Feb 6 2014, 14:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 1-02-14
Пользователь №: 80 290



Читаю Student Guide and Lab Manual и Family User's Guide и стали мне непонятны некоторые строки из кода лабораторной.
В лабораторной 4 нашел пример кода.
Детально с ним разобрался,но некоторые вещи мне непонятны.


Код
#include <msp430g2553.h>

volatile unsigned int i;

void ConfigWDT(void);
void ConfigClocks(void);
void ConfigLEDs(void);
void ConfigTimerA2(void);

void main(void)
{
  ConfigWDT();
  ConfigClocks();
  ConfigLEDs();
  ConfigTimerA2();

  _BIS_SR(GIE);   // РАЗРЕШАЕМ ПРЕРЫВАНИЕ - ЭТО ПОНЯТНО

  while(1)
  {
   P1OUT |= BIT0;
   for (i = 100; i > 0; i--);
   P1OUT &= ~BIT0;
   for (i = 5000; i > 0; i--);
  }
}

void ConfigWDT(void)
{
WDTCTL = WDTPW + WDTHOLD;                     // Stop watchdog timer
}

void ConfigClocks(void)    // НЕПОНЯТНАЯ ЧАСТЬ,НО ОНА У ВСЕХ ПРИСУТСТВУЕТ,Я РЕШИЛ ОСТАВИТЬ
{
  BCSCTL1 = CALBC1_1MHZ;                     // Set range
  DCOCTL = CALDCO_1MHZ;                      // Set DCO step + modulation
}

void ConfigLEDs(void)
{
  P1DIR = BIT6 + BIT0;                      // P1.6 and P1.0 outputs
  P1OUT = 0;                                // LEDs off
}

void ConfigTimerA2(void)
  {
   TACCR0 = 62500 - 1;    // Период в 62,500 цикла, от 0 до 62,499.                    /// ПОЧЕМУ 62500 ОТСТЧЕТОВ ВСЕГО ????????
   TACCTL0 = CCIE;        // Разрешаем прерывание таймера по достижению значения CCR0.    // ЭТО ПОНЯТНО
   TACTL = TASSEL_2     // ПОНЯЛ ЧТО ЭТО ВЫБОР ИСТОЧНИКА ТАКТОВОГО СИГНАЛА, НО В ЧЕМ МЕЖДУ НИМИ РАЗНИЦА ? ГДЕ ПРОЧЕСТЬ ?
               + ID_3           // ЭТО ПОНЯТНО. НО КАКАЯ ИЗНАЧАЛЬНАЯ ЧАСТОТА КОТОРУЮ МЫ ДЕЛИМ ?
                + MC_1;     // ПОНЯТНО
  }

#pragma vector=TIMER0_A0_VECTOR          // НИ В ОДНОЙ ИЗ ВЫШЕ ОПИСАННЫХ КНИЖЕК НЕ НАПИСАНО ПОЧЕМУ ТАКОЙ СИНТАКСИС
__interrupt void Timer_A (void)                     // ПОЧЕМУ ТАКОЙ СИНТАКСИС ?
{
  P1OUT ^=BIT6;                                 
}



1. Если выше описано что в таймере 62500 отсчетов. А так же включен делитель частоты /8 - то изначальная частота была 8 *62500 = 500кГц ???
Т.е. SMCLK что в коде включен имеет такую частоту ?

2. Как мне реализовать 2 таймера ?
Мне нужно чтоб один обращался к прерыванию с частотой 48кГц , а второй 200 Гц.
Идея в том что 48кГц будет забираться данные с АЦП , потом еще и фильтроваться будет.
А 200гц - вывод на индикатор



Сообщение отредактировал Niketa - Feb 6 2014, 15:03
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Niketa
сообщение Feb 7 2014, 13:15
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 1-02-14
Пользователь №: 80 290



Вот я написал Код.
С частотой 40кГц считывается АЦП.
На Индикатор выводится в основной программе под циклом While. Вывод на индикатор в данном случае не так важно.

Код
#include <msp430g2553.h>

unsigned int digit; /// переменная для значения 1 разряда
unsigned int pos = 1;    /// номер разряда
unsigned int value;   // переменная для значения выводимого числа
unsigned int buffer;   // переменная для значения ADC

unsigned int i;   // счетчик

void init_led(void)    // инициализация индикатора (описание смотрите в даташите)
{
    P1REN &= ~(BIT1+BIT2+BIT3+BIT4+BIT5+BIT6);
    P2REN &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5);
    P2REN &= ~(BIT3+BIT4+BIT5);
    P1REN &= ~BIT6;
    P2DIR |= (BIT0+BIT1+BIT2);
    P1DIR |= (BIT1+BIT2+BIT3+BIT4+BIT5);
    P2OUT |= (BIT0+BIT1+BIT2);
    P1OUT |= (BIT1+BIT2+BIT3+BIT4+BIT5);
    P2DIR |=(BIT3+BIT4+BIT5);
    P1DIR |=BIT6;
    P2OUT |=(BIT3+BIT4+BIT5);
    P1OUT |=BIT6;
}

void clear_led(void) {            // обнуление. выключаем все регистры и цифры.
    P2OUT |= (BIT0+BIT1+BIT2);
    P1OUT |= (BIT1+BIT2+BIT3+BIT4+BIT5);
    P2OUT |= (BIT3+BIT4+BIT5);
    P1OUT |= BIT6;
}

void show_number(number) {     // сопоставление ножек установки числа
    switch (number) {
        case 0 :
            P1OUT &=~(BIT1+BIT2+BIT3+BIT5);
            P2OUT &=~(BIT0+BIT2);
            break;
        case 1:
            P1OUT &=~(BIT3+BIT5);
            break;
        case 2:
            P1OUT &=~(BIT1+BIT3+BIT4);
            P2OUT &=~(BIT0+BIT2);
            break;
        case 3:
            P1OUT &=~(BIT1+BIT3+BIT4+BIT5);
            P2OUT &=~(BIT0);
            break;
        case 4:
            P1OUT &=~(BIT2+BIT3+BIT4+BIT5);
            break;
        case 5:
            P1OUT &=~(BIT1+BIT2+BIT4+BIT5);
            P2OUT &=~(BIT0);
            break;
        case 6:
            P1OUT &=~(BIT1+BIT2+BIT4+BIT5);
            P2OUT &=~(BIT0+BIT2);
            break;
        case 7:
            P1OUT &=~(BIT1+BIT3+BIT5);
            break;
        case 8:
            P1OUT &=~(BIT1+BIT2+BIT3+BIT4+BIT5);
            P2OUT &=~(BIT0+BIT2);
            break;
        case 9:
            P1OUT &=~(BIT1+BIT2+BIT3+BIT4+BIT5);
            P2OUT &=~(BIT0);
            break;
    }
}

void show_registr(registr) {   // сопоставление ножек управления регистра
    switch (registr) {
        case 4:
            P1OUT &=~BIT6;
            break;
        case 3:
            P2OUT &=~BIT5;
            break;
        case 2:
            P2OUT &=~BIT4;
            break;
        case 1:
            P2OUT &=~BIT3;
            break;
    }

}

void init_ADC(void) {
    ADC10CTL1 |= CONSEQ_0;        // single channel, single conversion
    ADC10CTL1 |= INCH_0
               + SHS_0            // use ADC10SC bit to trigger sampling
               + ADC10DIV_3    // clock divider = 4
               + ADC10SSEL_3;    // clock source = SMCLK

    ADC10CTL0 |= SREF_0        // reference voltages are Vss and Vcc
               + ADC10SHT_3    // 64 ADC10 clocks for sample and hold time (slowest)
               + ADC10ON
               + ENC;

    ADC10AE0 = BIT0;      // Разрешаем вход АЦП на порту P1.0
}

void ConfigClocks(void)
{
    BCSCTL1 = CALBC1_16MHZ;                     // Set range
    DCOCTL = CALDCO_16MHZ;                      // Set DCO step + modulation
}

void ConfigTimerA(void)
  {
    TACCR0 = 50;    // Обеспечиваем обращение к прерыванию 16MHZ/ 8 / 50 = 40kHz
    TACCTL0 = CCIE;        // Разрешаем прерывание таймера по достижению значения CCR0.
    TACTL = TASSEL_2 + ID_3 + MC_1;
  }


int main(void) {
    WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer
    ConfigClocks();
    ConfigTimerA();
    init_led();
    init_ADC();

    _BIS_SR(GIE);

    while (1)
    {
        if (value == 0) {
            value=buffer;  // присваиваем результат к АЦП
            pos = 1;
        }
        digit = value % 10;    /// взятие остатка от деления
        clear_led();
        show_number(digit);    // выбор числа
        show_registr(pos);     // выбор сегмента
        value /= 10;           // деление без остатка. отбпрасываем число которое показали
        pos++;
    }
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_CC0 (void)
{
/////////////////////////////////////C Частотой 40кГц работает ADC///////////////////////
    ADC10CTL0 |= ADC10SC; // включаем считвание с ацп
    while (ADC10CTL1 & ADC10BUSY); // ждем пока все считает
    buffer = ADC10MEM;
/////////////////////////////////////////////////////////////////////////////////////////

}



Вопросы:

1.Что делаю неправильно ?

2.В дальнейшем я планирую сделать фильтрацию частоты 15кГц. Т.е. счиитывается с частотой 40кГц а я ППФ спроектирую которsй будет вырезать где то 15кГц +-300Гц. И собственно вопрос. Сколько у меня запас по отсчетам есть микропроконтроллера до следующего считывания АЦП и так чтоб мигание вело себя корректно.

3.
Цитата
Если нужны точные частоты и временные интервалы, то лучше поставить кварцевый резонатор.

Не совсем понял что это за резонатор. Исходя из мануала я вычитал что это какой то генератор. Но в чем он лучше ?

4.Как настроить второе прерывание с другой частотой ? По CC1 сравнивал чтоб в другом прерывании код выполнял. В описании g2553h есть такой пункт. Но что то он не работает.А в мануале не написано как настроить сравнение с CC1.
Сейчас while(1) выводит информацию на индикатор(с прерыванием на АЦП).
НО! Я хочу и не спрашивайте почему (для практики) сделать так чтоб :
-buffer - Значение АЦП меняется с частотой 40кГЦ
-value - то значение что выводится на индкатор (=buffer_2)
-buffer_2 - с частотой 20Гц(примерно) = buffer

пока реализовано это в том же прерывании
Код
    if (i==40000/10) {
        i=0;
        buffer_2=buffer;
    }
    i++;

Но хочу чтоб было в отдельном прерыании, просто для практики

Сообщение отредактировал Niketa - Feb 7 2014, 13:49
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Niketa   MSP430 + Timer + Interrupt   Feb 6 2014, 14:17
- - E.V.G.   1. Частота прерываний от TACCR0=SMCLK/ID3/TACCR0=1...   Feb 6 2014, 20:23
- - Mihey_K   1. Смотрите внимательно юзер мануал Пример реализ...   Feb 7 2014, 14:52
- - Niketa   1. Я знаю что что неправильно АЦП включать в преры...   Feb 7 2014, 17:13
- - Mihey_K   Цитата3. Частота маловата. в комплекте есть такой ...   Feb 8 2014, 03:39
|- - rezident   Цитата(Mihey_K @ Feb 8 2014, 08:39) Чтобы...   Feb 8 2014, 11:46
- - Mihey_K   Rezident, хорошее пояснение. Скажу честно, не замо...   Feb 8 2014, 13:17
|- - rezident   Цитата(Mihey_K @ Feb 8 2014, 18:17) Друго...   Feb 8 2014, 17:54
- - Niketa   АЦП считывает с частотой 40кГц по таймеру Так же ...   Feb 9 2014, 22:27
|- - rezident   Цитата(Niketa @ Feb 10 2014, 03:27) АЦП с...   Feb 10 2014, 03:46
- - Mihey_K   Ёшкин кот, зачем математику-то всю в прерывание за...   Feb 10 2014, 06:41
- - Niketa   RE: MSP430 + Timer + Interrupt   Feb 15 2014, 20:43
- - Niketa   //////////////////////////////////////////////////...   Feb 16 2014, 13:13
- - PRidon   Куча примеров на сайте TI. Прям под твой МК. И уар...   Feb 17 2014, 07:22


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

 


RSS Текстовая версия Сейчас: 19th August 2025 - 06:39
Рейтинг@Mail.ru


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