Генератор прямоугольных импульсов на микроконтроллере MSP430.




  Допустим, нам необходим генератор прямоугольных импульсов на 100 кГц. Вопрос из чего его собрать? Вариантов много.

  Можно сделать генератор на двух транзисторах (мультивибратор), на таймере 555, или на отдельных логических элементах. При всей простоте это обрастает большим количеством резисторов, конденсаторов, которые нужно подбирать или подстраивать и дополнительными буферными каскадами, которые необходимы что бы нагрузка не влияла на частоту генераторов. Делается это, в общем то, не сложно. Но проблема возникает, когда непроходимо изменить частоту или длительность импульсов. Вот тут начинается подбор элементов, тыкание осциллографом и бесполезная потеря времени.

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

  Схема на микроконтроллере MSP430G2230. Любой микроконтроллер серии MSP430 будет работать не хуже. Справа программа, которая формирует прямоугольные импульсы на выходе P1.2.


#include <msp430.h>
int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;
  P1DIR |= BIT2;
  P1SEL |= BIT2;
  TA0CCTL1 = OUTMOD_4;
  TA0CCR0 = 4;
  TA0CTL = TASSEL_2 | MC_1;
}

  Код справа копипастится в Code Composer Studio. Микроконтроллер, который нужно запрограммировать, подсоединяется к launchpad с помощью четырех проводов, как это показано на следующем рисунке. Так можно запрограммировать любой микроконтроллер серии MSP430, если не забыть про систему сброса R1,C1.


  Если все запрограммировалось без ошибок, то получаем генератор чистого «меандра» (50%ON+50%OFF), с частотой около 120 кГц.

  Работа такого генератора основана на таймере, который есть в любом MSP430. Он считает тактовые импульсы, и когда значение достигает TA0CCR0, он сбрасывается. Одновременно значение на выводе P1.2 меняется на противоположное. Если в регистрTA0CCR0 заложить максимально возможное значение (65535), то частота следования импульсов будет около 8-ми Гц.



#include <msp430.h>
int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;
  P1DIR |= BIT2;
  P1SEL |= BIT2;
  TA0CCTL1 = OUTMOD_4;
  TA0CCR0 = 65535;
  TA0CTL = TASSEL_2 | MC_1;
}


  В таймере, один тактовый импульс теряется на перезагрузку счетчика. То есть, если Вы хотите разделить внутреннюю частоту на 10, то в регистр
TA0CCR0 нужно положить 9, если на 100, то 99, и так далее.

  При
TA0CCR0=4, внутренняя и выходная частоты должны отличаться в 10 раз. Если так и сделать, то частота на выходе P1.2 будет около 113,6 кГц. А нам нужно именно 100 кГц ... (вариант, подключить
внешний кварцевый резонатор на 1 МГц, не рассматриваем).

  В MSP430, по умолчанию, внутренняя тактовая частота вырабатывается генератором управляемым напряжением. Его частоту можно менять программно от 100 кГц до 20 МГц. Так же, в памяти микроконтроллера заложены калибровочные константы, с помощью которых можно настроить внутренний тактовый генератор на 1, 8, 12 или 16 МГц.

  Дополнительные две строчки ниже (слева), настраивают внутренний тактовый генератор на 1 МГц.

  Так как процессе работы таймера CPU не участвует, то последний можно выключить командой __bis_SR_register(CPUOFF). Это уменьшает общее потребление тока до 1 мА (16 МГц). Последняя строка, дополненная справа, отключает процессор.

 #include <msp430.h>
int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;

        BCSCTL1 = CALBC1_1MHZ;
        DCOCTL = CALDCO_1MHZ;

  P1DIR |= BIT2;
  P1SEL |= BIT2;
  TA0CCTL1 = OUTMOD_4;
  TA0CCR0 = 65535;
  TA0CTL = TASSEL_2 | MC_1;
}

 #include <msp430.h>
int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;

       BCSCTL1 = CALBC1_1MHZ;
       DCOCTL = CALDCO_1MHZ;

  P1DIR |= BIT2;
  P1SEL |= BIT2;
  TA0CCTL1 = OUTMOD_4;
  TA0CCR0 = 65535;
  TA0CTL = TASSEL_2 | MC_1;

      __bis_SR_register(CPUOFF);    }


  Теперь, когда тактовый генератор настроен на частоту 1 МГц, при
TA0CCR0=4, выходная частота на выходе P1.2 будет очень близкой к 100 кГц, а при TA0CCR0=49999  -  ~10,04 Гц.

  Допустим, мы хотим получить частоту 10000 Гц. При тактовой частоте 1 МГц нее вкладывается 100 тактов или 50 на полупериод. Один импульс теряется - остается 49. Таким образом, если
TA0CCR0 = 49, то выходная частота должна быть 10 кГц. Так оно и получается, как это видно на следующем фото.


 #include <msp430.h>
int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;

       BCSCTL1 = CALBC1_1MHZ;
       DCOCTL = CALDCO_1MHZ;

  P1DIR |= BIT2;
  P1SEL |= BIT2;
  TA0CCTL1 = OUTMOD_4;
  TA0CCR0 = 49;
  TA0CTL = TASSEL_2 | MC_1; 

__bis_SR_register(CPUOFF); }

  Досадной неприятностью, является то, что каждые 16 импульсов (32 такта внутреннего генератора) возникает дрожание фазы сигнала, которые видны на фотографии. Для многих применений это не имеет никакого значения, но важно знать из-за чего она возникает.

  Рисунок показывает как формируются тактовые частоты в MSP430. Тракт кварцевого резонатора отсутствует в MSP430G2230, поэтому помечен серым цветом.

  Все становиться понятным, если напрячься и прочитать документацию. Если коротко, то из двух частот формируется промежуточная частота  которая, с помощью модулятора, подмешивается к основному тактовому сигналу. Основная тактовая частота (DCOCLK) получается не «меандр», конечно. Попытка исключить модулятор (DCOCTL &= ~(BIT0+BIT1+BIT2+BIT3+BIT4)) не устраняет проблемы. Дрожание остается. Единственным выходом из положения является применение кварцевого резонатора или внешнего генератора. Для MSP430G2230 это невозможно, но для других микроконтроллеров серии MSP430 является приемлемым решением.

  Положительным моментом является то, что ошибка фазы не накапливается и обнуляется каждые 32 цикла тактового сигнала. А это означает, что если Вы зарограммировали таймер на 10 кГц, то плучите именно 10 кГц.

  Всем этим лучше не заморачиваться. Ниже - две програмки, которые позволяют превратить

MSP430G2230 в генератор с частотой 1 Гц и 4 МГц. В первом случае применяется дополнительный программный делитель, на 8, между основным тактовым сигналом (DCOCLK) и тактом таймера (SMCLK). Во втором, тактовая частота поднята до 16 МГц, делитель не используется.

#include <msp430.h>
   /*For 1 Hz generator.*/
int main(void)
{     
  WDTCTL = WDTPW | WDTHOLD;
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL = CALDCO_1MHZ;
  BCSCTL2 |= BIT1 + BIT2;
  P1DIR |= BIT2;
  P1SEL |= BIT2;
  TA0CCTL1 = OUTMOD_4;
  TA0CCR0 = 62499;
  TA0CTL = TASSEL_2 | MC_1;
  __bis_SR_register(CPUOFF);    }
#include <msp430.h>
   /*For 4 MHz generator.*/
int main(void)
{     
  WDTCTL = WDTPW | WDTHOLD;
  BCSCTL1 = CALBC1_16MHZ;
  DCOCTL = CALDCO_16MHZ;
  P1DIR |= BIT2;
  P1SEL |= BIT2;
  TA0CCTL1 = OUTMOD_4;
  TA0CCR0 = 1;
  TA0CTL = TASSEL_2 | MC_1;
  __bis_SR_register(CPUOFF);
}

  Остальные частоты, в промежутке между 1 Гц и 4 МГц, можно получить комбинируя основную тактовую частоту, делитель для тактовой частоты и значения в регистре таймера. К слову,
TA0CCR0 = 0, останавливает таймер. Состояние выхода, при этом, сохраняется.


  Распиновка
MSP430G2230.

/* --- Сделано, исключительно, как справочная страничка для себя-самого. --- */



8.03.2016  SKootS

_

Make a free website with Yola