430_2.  MSP430. Простая программа генератора и эксперимент.



Если Вы хотите разобраться как работает MSP430Gxxx,
и  у  Вас есть время и желание,  то это нужно деалать.
Если   времени  нет,  то  нужно  выбрать  другой  путь.
На  данный момент,  есть оболочка програмир.  Energia,
которая  позволяет программировать быстро, используя
готовый код. Запрограммировать LCD display - 10 минут.
Сделать  многоканальный  вольтметр  -  еще  10 минут.
Вывести данные  и  сохранить на компьютере - еще 10.
Готовый вольтметр, который уже работает -  здесь.    .


 Не знаю как и кого, а меня данный микроконтроллер интересует с точки зрения потребления энергии. Одна из конструкций должна питаться от солнечной батареи, с которой при напряжении 3V можно получить только 10 мА (при хорошей погоде). При этом необходимо дополнительно заряжать два аккумулятора по 1,5V. Так что "сильно не разгуляешься".

  План такой. На микроконтроллере запустить программу и измерить ток, потребляемый ядром микроконтроллера, только. Что бы быть уверенным, что программа выполняется – включать и выключать светодиоды. Схема  и  программа – на рисунке, ниже.

#include <msp430g2452.h>
void main (void) {
WDTCTL = WDTPW + WDTHOLD;
P1DIR |=0x41; P1OUT |=0x01; P1OUT &= ~0x40;
    for(;;) {
        volatile unsigned int i;
        P1OUT ^= 0x41;
              i = 10000;
              do i--;
              while(i != 0); }}

   В программе два светодиода зажигаются по очереди, так что в любой момент времени горит один из них. Ход программы такой. После сброса програмно отключается таймер (WDTCTL = WDTPW + WDTHOLD;), биты «0» и «6» первого порта переключаются на выход (P1DIR |=0x41;), бит «0» устанавливается в «1» (P1OUT |=0x01;), бит «6» в «0» (P1OUT &= ~0x40;), программа переходит в бесконечный цикл (for(;;) {}) и формируется задержка (do-while). Описание программы на отдельной странице.

  Фотографию момента измерений Вы можете видеть на фотографии (контроллер MSP430G2452, напряжение питания - 2,6V, яркость светодиодов - нормальная).

  Результат следующий. При напряжении 2,6 V и тактовой частоте 1 МГц, микроконтроллер потребляет ток, около,  0,22 mA (0,00022 А). На плате «Launchpad», при той же частоте (1 МГц) и напряжении питания 3,55 V, микроконтроллер MSP430G2452 потребляет 0,35 mA, а MSP430G2553 - 0,4 mA.

  Можно посчитать на сколько времени хватит двух аккумуляторов 200 mA/h (AAA) или 250mA/h (2/3 AA), если не переводить микроконтроллер в режим пониженного энергопотребления. Но из практики, двух аккумуляторов с верхней фотографии хватает больше, чем на месяц непрерывной работы.

  Остается посмотреть с какого напряжения начинает работать микроконтоллер.


    Данный микроконтроллер MSP430G2452, при:

  1,5Vне работает,
  1,55V – начинает работать, но неустойчиво.
  1,6Vуже работает.

  По данным TI (Texas Instruments), минимальное рабочее напряжение – 2,2V. Ядро будет продолжать работать до напряжения 1,8V, но при этом не гарантируется запись в энергонезависимую память (EEPROM). Максимально допустимое напряжение - 3,9V (4,2V) и этого мы проверять не будем.

  Но вернемся к результатам. Как видно на фотографии, осциллограф (справа) измеряет частоту импульсов (на выходе P1.0). Частота переключения светодиодов, около 4 Гц. Таким образом микроконтроллер формирует импульсы, длинной, около 120 mS (0,12 секунды). Программа формирует задержку в цикле do-while, с начальным значением счетчика i = 10000. Вопрос следующий. Какую максимальную частоту можно получить на выходе микроконтроллера, и как влияет длинна цикла задержки ( i = ??? ) на эту частоту?

  Но в начале вернемся к программированию.

      Подпрограммы или как это выглядит.

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

#include <msp430g2452.h>

void main (void) 
{
WDTCTL = WDTPW + WDTHOLD;
P1DIR |=0x41; P1OUT |=0x01; P1OUT &= ~0x40;
    for(;;) {
        volatile unsigned int i;
        P1OUT ^= 0x41;
              i = 10000;
              do i--;
              while(i != 0); }}

#include <msp430g2452.h>

void Flush_LEDs (void);

void main (void) {  Flush_LEDs ();  }

void Flush_LEDs (void)
{ WDTCTL = WDTPW + WDTHOLD;
  P1DIR |=0x41; P1OUT |=0x01; P1OUT &= ~0x40;
  for(;;)       { P1OUT ^= 0x41;
  volatile unsigned int i;
  i = 10000; do i--; while(i != 0);}}

  Правило очень простое. Подпрограмма объявляется (";" ) до начала функции main, используется (";" в теле функции  main , описывается (без ";" после функции  main  (после последней фигурной скобки функции  main ).

  Применение подпрограммы , в нашем примере, только усложнило программу. Но чаще бывает по другому. К примеру, следующая программа легко читается. Если программист был в «здравом уме и трезвой памяти», то эта программа делает то, что написано (независимо от программной реализации).

/**************************************************************************/

#include <msp430g2452.h>

void Flush_Both_LEDs_1_Time (void);                  //  Объявляем. Если человеческим языком, то 

void Flush_LED_Green_5_Time (void);                  // официально предупреждаем компилятор

void Flush_LED_Red_5_Time (void);                     // что будут 4-ре подпрограммы, которые

void Flush_ Both_LEDs_NonStop_EndLess_Loop (void);       // необходимо включить 

                                                                                        // в конечный файл.     

void main (void) 

{

Flush_Both_LEDs_1_Time ();          //  Вызываем подпрограммы на исполнение.

Flush_LED_Green_5_Time ();          //  Если программист был нормальный, то ход программы

Flush_LED_Red_5_Time ();                  // понятен из названий подпрограмм.

Flush_ Both_LEDs_NonStop_EndLess_Loop ();

}

void  Flush_LED_Green_5_Time (void)                //  Описываем каждую подпрограмму.

{…}                                //   В скобках {…} – программная реализация.

void  Flush_LED_Red_5_Time (void)  {…}

void  Flush_Both_LEDs_1_Time (void)  {…}

void  Flush_ Both_LEDs_NonStop_EndLess_Loop (void)  {…}

/**************************************************************************/  

   Это основа программы, где видна логика происходящего. Ее можно написать, даже, не зная языка Си. Дальше, необходимо наполнить подпрограммы содержанием (операторами языка Си, константами, переменными и так далее). Тут уже «на вкус и цвет» ...

   Почему мы говорим о подпрограммах именно сейчас? Есть три причины. Во первых, при написании подпрограмм, мелкие неточности в синтаксисе выливаются в длинные бессонные ночи. Во вторых, программы пишутся именно так. Любая программа делится на маленькие кусочки, которые пишутся (чаще «копипастятся»)  и отлаживаются отдельно, а потом все собирается вместе. В третьих, это позволяет использовать одну и ту же подпрограмму по несколько раз.  А еще подпрограммы (или функции) можно вызывать рекурсивно ... , но без этого можно прожить.

   Полезно знать что делает компилятор. Все объявленные подпрограммы раскладываются в памяти и вызовы этих подпрограмм (в основной программе main.c) заменяются на ссылки на их расположение. Если подпрограммы не объявлены, то текст после последней фигурной скобки функции main.c – игнорируется. Компилятор пытается найти разумное объяснение неизвестным  подпрограммам / функциям  в файле  msp430g2452.h , где их не находит, и сообщает об ошибке.

        Настало время измерить частоту.

  Можно, конечно, посчитать длительности импульсов по тактам процессора, но это не спортивно. Значительно проще и скорее это можно сделать с помощью обычного осциллографа, «зацепившись» за один из выходов микроконтроллера.

  Программу пришлось дописать. Не потому, что старая не работала, а потому, что значение задержки значительно удобнее менять вне тела программы. Глобальная переменная "k" объявлена в начале программы. Эта переменная используется как аргумент подпрограммы Flush_LEDs (k).

 #include <msp430g2452.h>


void Flush_LEDs (void);


void main (void) {  Flush_LEDs ();  }


void Flush_LEDs (void)

{ WDTCTL = WDTPW + WDTHOLD;

  P1DIR |=0x41; P1OUT |=0x01; P1OUT &= ~0x40;

  for(;;)       

  { P1OUT ^= 0x41;

   volatile unsigned int i;

  i = 10000;

  do i--; while(i != 0);}

}

 #include <msp430g2452.h>

volatile unsigned int k = 60000;

void Flush_LEDs (unsigned int aaa);


void main (void) {  Flush_LEDs (k);  }


void Flush_LEDs (unsigned int aaa)

{ WDTCTL = WDTPW + WDTHOLD;

  P1DIR |=0x41; P1OUT |=0x01; P1OUT &= ~0x40;

  for(;;)

  { P1OUT ^= 0x41;

  volatile unsigned int i;

  i = aaa;

  do i--; while(i != 0);}

}

   С точки зрения программирования, переменные бывают глобальные и локальные. Глобальные, объявляются перед программой main, живут постоянно и «видны» всем подпрограммам и функциям. Локальные переменные (временные), объявляются в теле программ, подпрограмм, циклов и т.д.  и существуют только во время их работы. То есть, переменная i, в цикле do-while, исчезнет, как только цикл закончится, и появится снова при следующем использовании цикла.

   Вернемся к длительности импульсов на выходах портов  P1.0  и  P1.6 .  Результаты  для  счетчиков цикла   k = i = 1000, 100, 10 и 1 – на фотографии ниже.  Результат для  k = i = 10000  -  4,15 Гц,  Вы могли видеть в начале страницы.

  Так же, было интересно узнать какую максимальную частоту (минимальную длину импульсов) можно получить.  Для этого надо убрать цикл do-while. После этого, инверсия  состояния  битов порта P1 будет происходить, только, в бесконечном цикле for(;;).

  Для микроконтроллера MSP430G2452, (работающем на внутренней частоте 1 МГц*, при напряжении питания 3,55V) удалось получить импульсы с длительностью около 5,5 мкс. Таким образом, частота следования импульсов - около 90 кГц. Я думаю, что это неплохой результат для 16-ти битного микроконторллера, при токе потребления 0,35 мА.


    Итак, что мы узнали.

1.    Плату
«Launchpad» можно использовать как программатор для микросхем MSP430Gxxxx. При этом, запрограммированная микросхема прекрасно работает отдельно (и без кварцевого резонатора!). То есть проблему с программатором мы сняли.
2.    Основная программа легко разбивается на подпрограммы. Это немного улучшает «читаемость» и «вспоминаемость». Но главное, что это позволяет набирать сложную программу из отдельных подпрограмм (часто не своих).
3.    Благодаря тому, что «Техас Инструмент» продумал систему сброса (по питанию), мы можем использовать микроконтроллер не задумываясь о внутренней конфигурации (как «черный ящик»). То есть, после подачи питания, в микроконтроллере включается внутренний тактовый генератор (1 МГц) и начинается выполнение программы.
4.    WatchDogTimer является единственным модулем, который включается после сброса «по умолчанию». Если его не выключить строкой «WDTCTL = WDTPW + WDTHOLD;», то он будет регулярно «рестартовать» микроконтроллер, мешая нормальной работе программы. Остальные внутренние модули можно включить программно, если есть желание.
5.    Мы использовали микроконтроллер MSP430Gxxxx как программный автомат. То есть программировали последовательность действий, а микроконтроллер их выполнял. Это позволило реализовать генератор прямоугольных импульсов с частотой до 90 кГц при тактовой частоте процессора 1 МГц. Добавив две команды (BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ;) можно увеличить тактовую частоту процессора до 16 МГц (выбор 1, 8, 12 или 16 МГц). Соответственно увеличится максимальная частота выходных импульсов. Согласитесь, что генератор до частоты 1,5 МГц, на одной микросхеме – это заманчиво.


    Дальше.

  Пользуясь логикой «программного автомата», можно написать («скопипастить») простую программу, для работы с LCD дисплеем. А дальше, на дисплей можно выводить все что угодно, текст, цифры, числа, показания вольтметра (результат работы АЦП), частоту и так далее.

              «Вы можете это сделать! Это очень просто!».


  На фотографии универсальная заготовка устройства, которая УЖЕ работает. Можно превратить во что угодно (зависит от фантазии и необходимости).

  Техническая реализация следующая. Порты микроконтроллера P2.0-P2.3 соединены с D4-D7 индикатора, P2.4 с EN, P2.5 с RS. Вывод R/W индикатора соединен с «общим проводом». При напряжении 3,5V добиться  изображения на экране – не возможно. Поэтому дополнительная батарейка, 1,5V (в правом нижнем углу фотографии), решает эту проблему.

  На следующей странице - схема и простейшая программа, которая позволяет это сделать.



 Дальше -->

25.06.2012  SKootS

_

Make a free website with Yola