У меня уже не первый год пылится на полке отладочный комплект 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:
Заботливый компилятор сам вставит для нас файл с пустой функцией main() в проект и даже пропишет туда остановку WatchDog’а:
Нам осталось только поправить настройки проекта, и на этом, собственно, все. В категории General Options нужно выбрать наш микроконтроллер, соответственно, выбираем CC430F6137.
Теперь идем во вкладку 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 будем считать удавшимся ) До скорых встреч на нашем сайте!
эхх а я так и не успел на раздачу "слонов" MSP430 а купить сейчас хз где....прикольная статейка жду продолжения )))
Их когда то бесплатно раздавали даже) Я это тоже не застал, к сожалению, заказывал откуда то издалека, уже не помню откуда =)
Всем доброго времени суток. Тоже имею сей девайс, только дальше дисплея и кнопок не смог уйти. Нашел несколько статей по использованию пьезо-пищалки и трансивера но пока все усилия тщетны...
Есть вопрос по использованию 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;
}
}
Все заработало...
Не успел ничего ответить =)
было бы неплохо если бы ответили как использовать трансивер, хотя бы без протокола Simpliciti и как получать данные от акселерометра, лучше всего конечно в IAR.
Я вообще этим раньше на работе занимался, а сейчас даже часов этих нет по-моему. Поищу что-нибудь. А вообще лучше купить нормальную плату с CC430
я покупал часики на ebay в том году
Была у меня отличная плата с этим же контроллером, не могу что-то найти ее в инете