Top.Mail.Ru

MSP430. Быстрый старт с отладочным комплектом EZ430-Chronos.

У меня уже не первый год пылится на полке отладочный комплект EZ430 – Chronos, представляющий из себя законченный девайс в виде часов на базе микроконтроллерной системы CC430F6137. В модуль CC430 помимо контроллера MSP430 интегрирован RF трансивер CC1101. То есть эти часики – полноценная отладочная плата с микроконтроллером MSP430, радиомодулем, графическим дисплеем, акселерометром и не только!

В комплекте с часами шел JTAG отладчик-программатор, беспроводной модуль для общения с комплектом по радиоканалу, ну и всякая мелочевка, типа отвертки и т. п. Работает все прямо из коробки, можно сразу же поставить родную программу для ПК, подключить часы по беспроводному интерфейсу и поиграться с акселерометром. На соответствующих графиках в программе Chronos Control Center от Texas Instruments можно увидеть колебания акселерометра.

Короче, вот к чему все это... Решил я организовать что-то вроде учебного курса по программированию MSP430, так что у нас на сайте появляется новая рубрика, посвященная этим микроконтроллерам. И сегодня будет описание быстрого старта с MSP430, создание нового проекта и пример небольшой программы.

Итак, в качестве среды разработки я выбрал IAR, а точнее IAR Embedded workbench for MSP430. Устанавливаем, запускаем и создаем новый проект... Заходим в меню Project и жмем Create New Project. В появившемся окне говорим IAR’у, что будем создавать C project:

Создание нового проекта для MSP430

Заботливый компилятор сам вставит для нас файл с пустой функцией main() в проект и даже пропишет туда остановку WatchDog’а:

Пустая функция main()

Нам осталось только поправить настройки проекта, и на этом, собственно, все. В категории General Options нужно выбрать наш микроконтроллер, соответственно, выбираем CC430F6137.

Выбор микроконтроллера в IAR

Теперь идем во вкладку Debugger и выбираем там наш программатор/отладчик.

Выбор отладчика

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

А с этим все просто. Есть в памяти контроллера определенные адреса, по которым расположены байты, биты которых отвечают за определенный сегмент дисплея. Вот смотрите на картинку:

Карта сегментов
  • a0 - 0xA20, a1 - 0xA21, a2 - 0xA22, a3 - 0xA23, a4 - 0xA24, a5 - 0xA25, a6 - 0xA26, a7 - 0xA27, a8 - 0xA28, a9 - 0xA29, a10 - 0xA2A, a11 - 0xA2B.

Адреса я тут обозначил символами a0, a1 … a11. Видим, например, что рядом с символом сердечка на дисплее написано a1.3. Что это значит? А вот что: адрес a1 у нас означает 0xA21. А цифра 3 означает третий бит. То есть, чтобы зажечь сердечко на часах, надо по адресу 0xA21 записать байт, третий бит которого равен 1. Так вот, давайте в качестве примера в первой позиции верхней строки дисплея (то есть на месте самой левой цифры в первой строке) будем зажигать поочередно цифры 0, 1, 2, 3 ,4, 5, 6, 7, 8, 9.

Рассмотрим, что нам нужно и куда записать, чтобы высветилась, например цифра 2. Итак, смотрим на карту сегментов – за первый элемент верхней строки отвечает переменная по адресу a1 (0xA21). И чтобы зажечь двойку, надо всего лишь в байте, расположенному по этому адресу выставить четвертый, пятый, первый, второй и седьмой биты.

Вроде во всем разобрались, пора уже наконец-то заняться программированием:

/***************************************************************************************/
#include  "cc430x613x.h"


/***************************************************************************************/
// Указатель для обращения к памяти контроллера
unsigned char* segmentPointer;


/***************************************************************************************/
// Простая функция задержки
// Для того, чтобы не нагружать пример здесь задержка сделана просто циклом,
// но в "боевых" проектах, конечно же, всегда нужно использовать для этого таймеры
void simpleDelay(unsigned int delayValue)
{
	for (unsigned int i = 0; i < delayValue; i++);
}


/***************************************************************************************/
// А это функция для того, чтобы в первой позиции дисплея высветилась цифра, переданная в функцию в качестве параметра
void showNum(unsigned char num)
{
	segmentPointer = ((unsigned char*)0x0A21);
	if (num == 0)
	{
		*segmentPointer = (unsigned char)(BIT0 + BIT2 + BIT4 + BIT5 + BIT6 + BIT7);
	}
	
	if (num == 1)
	{
		*segmentPointer = (unsigned char)(BIT5 + BIT6);
	}
	
	if (num == 2)
	{
		*segmentPointer = (unsigned char)(BIT1 + BIT2 + BIT4 + BIT5 + BIT7);
	}
	
	if (num == 3)
	{
		*segmentPointer = (unsigned char)(BIT1 + BIT4 + BIT5 + BIT6 + BIT7);
	}
	
	if (num == 4)
	{
		*segmentPointer = (unsigned char)(BIT0 + BIT1 + BIT5 + BIT6);
	}
	
	if (num == 5)
	{
		*segmentPointer = (unsigned char)(BIT0 + BIT1 + BIT4 + BIT6 + BIT7);
	}
	
	if (num == 6)
	{
		*segmentPointer = (unsigned char)(BIT0 + BIT1 + BIT2 + BIT4 + BIT6 + BIT7);
	}
	
	if (num == 7)
	{
		*segmentPointer = (unsigned char)(BIT4 + BIT5 + BIT6);
	}
	
	if (num == 8)
	{
		*segmentPointer = (unsigned char)(BIT0 + BIT1 + BIT2 + BIT4 + BIT5 + BIT6 + BIT7);
	}
	
	if (num == 9)
	{
		*segmentPointer = (unsigned char)(BIT0 + BIT1 + BIT4 + BIT5 + BIT6 + BIT7);
	}
}


/***************************************************************************************/
int main( void )
{
	// Сброс watchdog'а
	WDTCTL = WDTPW + WDTHOLD;

	// Очистка памяти дисплея 
	LCDBMEMCTL |= LCDCLRBM + LCDCLRM;

	// Настройка дисплея 
	// LCD_FREQ = ACLK / 16 / 8 = 256Hz
	// Frame frequency = 256Hz / 4 = 64Hz, LCD mux 4, LCD on
	LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON;

	// Настраиваем нужные пины для работы с дисплеем
	P5SEL |= (BIT5 | BIT6 | BIT7);
	P5DIR |= (BIT5 | BIT6 | BIT7);

	// Нужные сегменты дисплея
	LCDBPCTL0 = 0xFFFF; // Select LCD segments S0 - S15
	LCDBPCTL1 = 0x00FF; // Select LCD segments S16 - S22*/

	while(1)
	{
		// Поочередно зажигаем цифры на дисплее, затем задержка, и потом следующая цифра – и так по кругу 
		showNum(0);
		simpleDelay(64000);

		showNum(1);
		simpleDelay(64000);

		showNum(2);
		simpleDelay(64000);

		showNum(3);
		simpleDelay(64000);

		showNum(4);
		simpleDelay(64000);

		showNum(5);
		simpleDelay(64000);

		showNum(6);
		simpleDelay(64000);

		showNum(7);
		simpleDelay(64000);

		showNum(8);
		simpleDelay(64000);

		showNum(9);
		simpleDelay(64000);
	}
	return 0;
}


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

Вот такая вот получилась программка для EZ430-Chronos. На дисплее поочередно высвечиваются цифры от 0 до 9.

На этом все, быстрый старт с программированием MSP430 будем считать удавшимся ) До скорых встреч на нашем сайте!

Подписаться
Уведомить о
guest

10 комментариев
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии
oss
oss
11 лет назад

эхх а я так и не успел на раздачу "слонов" MSP430 а купить сейчас хз где....прикольная статейка жду продолжения )))

German
German
10 лет назад

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

German
German
10 лет назад

Есть вопрос по использованию RTC, пример для этого контроллера не запускается.
#include "cc430x613x.h"

void main(void)
{
WDTCTL = WDTPW+WDTHOLD;

P1OUT |= 0x01;
P1DIR |= 0x01;

// Setup RTC Timer
RTCCTL01 = RTCTEVIE + RTCSSEL_2 + RTCTEV_0; // Counter Mode, RTC1PS, 8-bit ovf
// overflow interrupt enable
RTCPS0CTL = RT0PSDIV_2; // ACLK, /8, start timer
RTCPS1CTL = RT1SSEL_2 + RT1PSDIV_3; // out from RT0PS, /16, start timer

__bis_SR_register(LPM3_bits + GIE);
}

#pragma vector=RTC_VECTOR
__interrupt void RTC_ISR(void)
{
switch(__even_in_range(RTCIV,16))
{
case 0: break; // No interrupts
case 2: break; // RTCRDYIFG
case 4: // RTCEVIFG
P1OUT ^= 0x01;
break;
case 6: break; // RTCAIFG
case 8: break; // RT0PSIFG
case 10: break; // RT1PSIFG
case 12: break; // Reserved
case 14: break; // Reserved
case 16: break; // Reserved
default: break;
}
}

German
German
Ответ на комментарий  German
10 лет назад

Все заработало...

German
German
Ответ на комментарий  Aveal
10 лет назад

было бы неплохо если бы ответили как использовать трансивер, хотя бы без протокола Simpliciti и как получать данные от акселерометра, лучше всего конечно в IAR.

German
German
10 лет назад

я покупал часики на ebay в том году

10
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x