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 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
oss
oss
7 лет назад

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

German
German
6 лет назад

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

German
German
6 лет назад

Есть вопрос по использованию 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
Reply to  German
6 лет назад

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

German
German
Reply to  Aveal
6 лет назад

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

German
German
6 лет назад

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

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Июнь 2020
Пн Вт Ср Чт Пт Сб Вс
« Май    
1234567
891011121314
15161718192021
22232425262728
2930  

© 2013-2020 MicroTechnics.ru