Уроки MSP430 LaunchPad. Урок 12: Всё познаётся в сравнении

Как мы можем видеть, микроконтроллеры широко применяются в цифровой технике; как в бытовых приборах, так и в научных разработках. Тем не менее, цифрами не всегда возможно адекватно передать ситуацию. В этом уроке, мы будем работать с аналоговыми сигналами, используя 1-битный аналогово-цифровой преобразователь, или, по-другому, компаратор.

Многие MSP430 имеют встроенный компаратор (называется Comparator_A+, модуль аналогового компаратора А+), включая MSP430G2211, идущий с LaunchPad. (В LaunchPad версии 1.5, оба микроконтроллера G2553 и G2452, имеют модуль компаратора. – Прим. пер.). До этого урока, все примеры программ можно было запускать как на G2211, так и на G2231, просто заменив в инструкции #include, имя заголовочного файла. Для этого урока, необходимо использовать G2211. (G2553 и G2452 тоже подойдут. – Прим. пер.).

Обзор модуля Comparator_A+




Модуль компаратора, очень гибко настраивается, он позволяет подключать разные выводы микроконтроллера как свой вход, и имеет много настроек опорного источника напряжения. Компаратор имеет два входа, неинвертирующий (V+) и инвертирующий (V-). Неинвертирующий вход может быть соединен с одним из трех выводов микроконтроллера. Инвертирующий вход может быть соединен с одним из семи выводов (два из них пересекаются с неинвертирующим входом). Компаратор имеет выход, значение которого можно прочесть программно, он может вызвать прерывание компаратора, и вызвать прерывание таймера. Весь этот функционал, делает компаратор гибким и полезным инструментарием разработчика.

Посмотрите спецификацию на G2211, и найдите там страницу с изображением схемы выводов. Выводы, которые можно использовать в качестве входов компаратора, обозначены как CAx. CA(0-2) могут быть неинвертирующим входом, CA(1-7) инвертирующим входом. Так же, обозначение CAOUT на выводе, означает, что он может служить внешним выходом модуля компаратора.

Настройка модуля Comparator_A+


Модуль компаратора имеет три регистра для настройки: CACTL1, CACTL2 и CAPD. Эти регистры описываются на страницах 447-455 руководства по семейству микроконтроллеров x2xx. Выделим основные моменты здесь:



  • CAREFx (биты 5 и 4) и CARSEL (бит 6) контролируют внутренний генератор опорного напряжения. Битами 4 и 5, выбирается величина напряжения, бит 6 выбирает вход для опорного напряжения. Генератор может формировать три разных опорных напряжения, два из них, дробная величина от напряжения питания – ½ Vcc и ¼ Vcc. Если вы запитываете LaunchPad от USB (3.6 В), это даст 1.8 В и 0.9 В соответственно. (Точность 1%). Третье опорное напряжение, равно пороговому напряжению транзистора ~0.55 В. Но точность менее высокая, и есть зависимость от температуры.
  • CAIFG, CAIE, CAIES (биты 0-2) контролируют прерывание компаратора. Бит 0 – флаг прерывания, очищается автоматически при вызове обработчика. Бит 1 – разрешает прерывание, бит 2 – выбор фронта для генерации прерывания: 0, по нарастающему фронту; 1, по спадающему фронту.
  • CAON (бит 3) – включение компаратора. Этот бит включает компаратор (если установлен в 1). Когда компаратор выключен, его потребляемый ток равен нулю. Генератор опорного напряжения включается и выключается независимо от компаратора.
  • CAEX (бит 7) – перестановка входов компаратора. При установленном бите CAEX входы компаратора меняются местами, а выходной сигнал компаратора инвертируется, для компенсации изменений. Это бывает необходимо, для проверки очень близких значений, но не нужно при обычном применении.


  • P2CAx (биты 2-6) используется для выбора выводов микроконтроллера для входа компаратора. Неинвертирующий выбирается в P2CA0 и P2CA4, инвертирующий выбирается в P2CA1-P2CA3. В руководства по семейству микроконтроллеров x2xx на странице 455, расписаны конфигурации битов для всех вариантов выбора.
  • CAF (бит 1) подключает выход компаратора к RC фильтру, для сглаживания генерации колебаний выходного сигнала, которые всегда возникают, если значения на входах очень близки. Не всегда нужная функция, но может оказаться очень полезной, если вы сравниваете слабо изменяющиеся сигналы.
  • CAOUT (бит 0) значение выхода компаратора. Доступен только для чтения.
  • CASHORT (бит 7) замыкает входы компаратора. Звучит странно, но бывает необходимо в определенных ситуациях. В обычном применении компаратора, эта функция не используется.


  • CAPD, регистр аналогичный регистрам портов микроконтроллера. Каждый его бит соответствует входам CA0-CA7. Смысл этого регистра в отключении цифровой схемы портов ввода/вывода от вывода микроконтроллера, если он используется для работы с аналоговым сигналом. Если напряжение аналогового сигнала будет близко к переходному напряжению цифрового блока, подключенного к входу, то цифровая схема начнет генерировать сигнал из быстрых переходов состояний 1 и 0. Этот эффект может привести к деградации цифрового блока, поэтому его лучше отключить, при работе с аналоговым сигналом. По факту, как только вывод настраивается как вход компаратора, цифровой блок отключается автоматически, поэтому отключение цифрового блока через CAPD, избыточен, если вы используете только один вывод микроконтроллера как вход компаратора. Но если, например, вам нужно использовать компаратор на нескольких сигналах одновременно, только один вывод может служить входом компаратора за один раз, но их можно переключать из программы. Установка бита в регистре CAPD, предотвратит подключение цифрового блока к выводу, пока вы переключились на другой. Это нужно, т.к. аналоговый сигнал по прежнему подведен к предыдущему выводу.

Пример программы


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

Вот часть кода, в которой настраивается модуль компаратора:

CACTL1 = CAREF1 + CARSEL + CAIE; // опорное напряжение 0.5 Vcc,
                                       // на инвертирующем входе,
                                       // прерывание разрешено,
                                       // по нарастающему фронту (по умолчанию)
CACTL2 = P2CA4 + CAF; // неинвертирующий вход CA1, выход фильтруется
CAPD = AIN1;          // отключаем цифровой блок на P1.1 (технически
                      // этот шаг избыточен)

Названия битов, используемые здесь, можно найти в заголовочном файле для G2211. Установка бита CAREF1 выбирает ½ Vcc как опорное напряжение, CARSEL подключает опорное напряжение к инвертирующему (V-) входу. Установка бита P2CA4 выбирает неинвертирующий (V+) вход CA1, это P1.1 на G2211. AIN1 определен в заголовке программы как BIT1, так что в этой программе, цифровой блок на P1.1 постоянно отключен. Этот шаг не обязателен, так как мы не собираемся менять входы компаратора в нашем примере.

После настройки всей периферии, компаратор будет включен командой CACTL1 |= CAON (оператор |= используется, что бы внести изменение только в один бит регистра, не трогая остальные) и микроконтроллер погружается в режим экономии LPM0.

Таймер, периодически, вызывает прерывание, в котором выводит на выход P1.0 значение переменной flash. Пока бит выхода компаратора CAOUT равен 0, светодиод не горит, т.к. переменная flash, всё время обнуляется. Как только CAOUT принимает значение 1, в переменную flash, записывается значение LED1 (равное BIT0) и диод начинает мигать.

Вот так выглядит обработчик прерывания компаратора:

#pragma vector = COMPARATORA_VECTOR
__interrupt void COMPA_ISR(void) {
  if ((CACTL2 & CAOUT)==0x01) {
    CACTL1 |= CAIES;    // значение высокое, ждем спадания фронта
    flash = LED1;       // разрешаем светодиоду мигать
  }
  else {
    CACTL1 &= ~CAIES;   // значение низкое, ждем возрастания фронта 
    flash = 0;          // отключаем светодиод
    P1OUT = 0;          // обнуляем выход порта P1
  }  
} // COMPA_ISR

Ни один из примеров на сайте TI, не показывал, как использовать прерывание модуля Comparator_A+. Чтобы разобраться с синтаксисом, я изучил заголовочный файл msp430g2211.h. Помните, что имя вектора прерывания должно быть таким, как компилятор ожидает (в нашем случае COMPARATORA_VECTOR). Заголовочный файл, самое надежное место, для нахождения имён векторов прерываний. Имя обработчика прерывания может быть любым, но нужно что бы оно было понятным. Для этого примера я выбрал COMPA_ISR(). Обработчик проверяет вначале значение CAOUT, и если оно 1, это означает, что напряжение на неинвертирующем входе выше, чем на инвертирующем. Следующее прерывание должно возникнуть, когда значение на входе опустится ниже опорного напряжения, это настраивается установкой спадающего фронта. Одновременно переменной flash, присваивается ненулевое значение, и светодиод начинает мигать. Если CAOUT равен 0, значит напряжение неинвертирующего входа ниже опорного напряжения. Устанавливается срабатывание по возрастающему фронту, flash обнуляется, а значит, диод не мигает и P1OUT обнуляется, что бы диод погас (если горел).

Для проверки работы программы, вы можете подсоединить переменный резистор (любой больше 1 кОм) между питанием (Vcc) и землей, а контакт щётки (обычно средний) подсоединить к P1.1 на LaunchPad. Вращая переменный резистор, можете увидеть в какие моменты светодиод начинает мигать (это означает, что напряжение на выводе ниже 1.8 В). Если у вас нет переменного резистора, можно попробовать сделать это с двумя обычными резисторами разного сопротивления. Поставьте один резистор между питанием и P1.1, а второй между P1.1 и землёй. Если резистор с меньшим сопротивлением между питанием и выводом микроконтроллера, напряжение должно быть больше половины питания, и светодиод начнёт мигать. Если в этом месте резистор с большим сопротивлением, напряжение будет ниже ½ Vcc, светодиод не будет гореть вообще. (Желательно, если перед тем как подсоединять резисторы, вы будете отключать питание от LaunchPad).

Упражнение: Поменяйте программу так, чтобы светодиод не мигал, а просто зажигался и гас, в зависимости от значения в CAOUT. Потом настройте таймер, так, чтобы он периодично менял значение опорного напряжения между ½ Vcc и ¼ Vcc. Когда сравниваем ½ Vcc, должен зажигаться красный светодиод (P1.0), если напряжение на входе ниже опорного. Когда сравниваем ¼ Vcc, должен зажигаться зеленый светодиод (P1.6), если напряжение на входе ниже опорного. Покрутите переменный резистор, и понаблюдайте, как зажигаются разные светодиоды, в зависимости от уровня напряжения на неинвертирующем входе компаратора.

Листинг программы (оригинал bcompG2211.c):

/* bcompG2211: Этот пример демонстрирует базовые функции модуля Comparator A+
 *  Светодиод (P1.0) мигает, когда напряжение, на аналоговом входе CA1 (P1.1), 
 *  ниже половины напряжения питания 
 */

#include <msp430g2211.h>

#define LED1	BIT0
#define AIN1	BIT1

/*  Глобальные переменные  */
char flash = 0;				// начинаем с потухшим светодиодом

/*  Объявление функций  */

void main(void) {
	
	WDTCTL = WDTPW + WDTHOLD;	// отключаем сторожевой таймер

	P1OUT = 0;
	P1DIR = LED1;			// светодиод на P1.0
	
CACTL1 = CAREF1 + CARSEL + CAIE; // опорное напряжение 0.5 Vcc,
                                 // на инвертирующем  входе,
                                 // прерывание разрешено,
                                 // по нарастающему фронту (по умолчанию)
CACTL2 = P2CA4 + CAF;// неинвертирующий  вход CA1, выход фильтруется
CAPD = AIN1;         // отключаем цифровой блок на P1.1 (технически
                     // этот шаг избыточен)
	
	TACCR0 = 60000;	  // Задержка таймера для мигания, 60000 циклов
	TACCTL0 = CCIE;   // разрешаем прерывание таймер по достижении CCR0
	TACTL = TASSEL_2 + ID_3 + MC_1 + TACLR; // SMCLK, делитель 8,
                                                // прямой счёт, обнуление таймера
	CACTL1 |= CAON;		  // включаем компаратор	
	_BIS_SR(LPM0_bits + GIE); // включаем режим экономии  LPM0 и разрешаем прерывания

} // main

/*  Обработчики прерываний  */

#pragma vector = TIMERA0_VECTOR
__interrupt void CCR0_ISR(void) {
	P1OUT ^= flash;			// если flash == 0, светодиод не горит
					// если flash == LED1, мигаем светодиодом
} // CCR0_ISR

#pragma vector = COMPARATORA_VECTOR
__interrupt void COMPA_ISR(void) {
  if ((CACTL2 & CAOUT)==0x01) {
    CACTL1 |= CAIES;    // значение высокое, ждем спадания фронта
    flash = LED1;       // разрешаем светодиоду мигать
  }
  else {
    CACTL1 &= ~CAIES;   // значение низкое, ждем возрастания фронта 
    flash = 0;          // отключаем светодиод
    P1OUT = 0;          // обнуляем выход порта P1
  }  
} // COMPA_ISR

Архив с программой.

Примечание переводчика: В IAR всё работает.

Оригинал статьи на английском: Tutorial 12: Making Comparisons

Предыдущий урок этого цикла: Урок 11: Экономия, должна быть экономной!
Следующий урок этого цикла: Урок 13: Комбинируем периферию
  • +15
  • 17 ноября 2012, 07:06
  • Tabke
  • 1
Файлы в топике: bcompG2211.zip

Комментарии (1)

RSS свернуть / развернуть
Спасибо!
Не поленились перевести и поделиться со всеми.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.