MSP430. IAR. Быстрый старт.

У меня уже не первый год пылится на полке отладочный комплект EZ430 – Chronos, представляющий из себя законченный девайс в виде часов на базе микроконтроллерной системы CC430F6137. В модуль CC430 помимо контроллера MSP430 интегрирован RF трансивер CC1101. То есть эти часики – полноценная отладочная плата с микроконтроллером MSP430, радиомодулем, графическим дисплеем, акселерометром и не только )
Отладочный комплект EZ430-Chronos
В комплекте с часами шел JTAG отладчик-программатор, беспроводной модуль для общения с комплектом по радиоканалу, ну и всякая мелочевка, типа отвертки итп. Работает все прямо из коробки, можно сразу же поставить родную программку на ПК, подключить часы по беспроводному интерфейсу и поиграться с акселерометром. На соответствующих графиках в программе Chronos Control Center от Texas Instruments можно увидеть колебания акселерометра.

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

Итак, в качестве среды разработки я выбрал IAR, а точнее IAR Embedded workbench for MSP430 IDE. Дружно устанавливаем и запускаем ) Пора создавать новый проект.

Заходим в меню 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 будем считать удавшимся 😉 До скорых встреч на нашем сайте!

Понравилась статья? Поделись с друзьями!

MSP430. IAR. Быстрый старт.: 10 комментариев
  1. эхх а я так и не успел на раздачу «слонов» MSP430 а купить сейчас хз где….прикольная статейка жду продолжения )))

    • Их когда то бесплатно раздавали даже) Я это тоже не застал, к сожалению, заказывал откуда то издалека, уже не помню откуда =)

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

  3. Есть вопрос по использованию 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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *