Pull to refresh

MSP430, учимся программировать и отлаживать железо

Programming microcontrollers *

Сегодня, уважаемый хабрапользователь, я постараюсь заполнить некоторый пробел, образовавшийся в статьях об MSP430, а именно азы и подход к программированию устройств на данном микроконтроллере.
Эта статья прежде всего направлена на новичков, поскольку я буду рассматривать ряд достаточно простых задач, таких как работа с SPI, мигание лампочкой и отладка в proteus.


Введение


В данной статье будет рассмотрено устройство, в основу которого легла отладочная плата eZ430-RF2500. На плате находится микроконтроллер MSP430F2274 и беспроводной модуль CC2500, который, надо заметить, не будет рассмотрен далее.
Моим коллегой, Соколовым С. А., была изготовлена небольшая надстройка для этого отладочного комплекта, она присоединена ко всем выводам. На надстройке расположен акселерометр LIS331DLH, с которым мы и будем взаимодействовать по SPI.

Должен заметить, что устройства STMicroelectronics, работающие по SPI, очень похожи и, соответственно, работа с ними будет выглядеть примерно также.

Что нам потребуется


Среда разработки

Для начала нужно скачать и установить среду разработки и компилятор. На сегодняшний день существует три варианта — Code Composer Studio, IAR Embedded Workbench for TI MSP430 и mspgcc.
Я буду использовать Workbench KickStart Edition. KickStart бесплатный, он имеет ограничение по количеству кода, но для изучения этого более чем достаточно.

Средство отладки

Если у вас нет под рукой осциллографа или логического анализатора, то часто возникают сложности, связанные с непониманием того, что же на самом деле происходит в вашем устройстве. Понять причины того, почему же устройство отказывается работать часто помогает Proteus.
В нём можно найти очень многие микроконтроллеры MSP430. К сожалению MSP430F2274 в Proteus не оказалось, но имеется аналог — MSP430F2272, его и будем использовать.

Приступим к написанию кода


Создание проекта

На данном этапе сложностей возникнуть не должно. В качестве языка программирования выбираем C++.
  • Заменяем стандартный #include «io430.h» на #include «msp430f2274.h» (заголовочный файл для нашего микроконтроллера);
  • В свойствах проекта на вкладке Debugger выбираем Driver: FET Debugger;
  • На вкладке General Options в окне Device выбираем MSP430F2274;
  • Для того чтобы убедиться, что всё сделано правильно нажимаем Ctrl+D (Download and Debug). Как только контроллер прошивка загрузится нажимаем F5 для её выполнения.

В случае если нужно скомпилировать файл для Proteus, на вкладке Debugger в окне Driver выбираем Simulator, а на вкладке Linker Output в окне Format ставим Other и Output format выбираем intel-standart, а в окне Output file меняем расширение на hex.

Работа с портами

Первое, что стоит освоить в микроконтроллере — это работа с портами. Давайте рассмотрим небольшой пример.
 
#include "msp430f2274.h"
 
void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
 
  P1DIR &= ~BIT2;
  P1REN |= BIT2;
 
  P1DIR |= BIT1 + BIT0;
 
  while(true)
  {
    if(P1IN & BIT2)
    {
      P1OUT |= BIT1;
      P1OUT &= ~BIT0;
    }
    else
    {
      P1OUT |= BIT0;
      P1OUT &= ~BIT1;
    }
  }
}
 


PxDIR отвечает за направление порта 1. Когда конкретный бит данного регистра установлен в 0, соответствующий пин работает на вход. И наоборот, если соответствующий бит установлена в 1, то пин работает на выход. В примере фигурируют 3 пина: P1.2 — кнопка, P1.0 — красный светодиод, P1.1 — зеленый светодиод.

PxREN включает внутренний резистор подтяжки. Кнопка замыкает пин на землю, и, соответственно, переводит его в состояние нуля. Когда кнопка не нажата пин ни к чему не подключен и для обеспечения логической единицы на нём требуется подключить его через резистор к питанию, что и делает регистр P1REN.

PxIN и PxOUT содержат в себе состояние пинов порта. Устанавливая ноль или единицу в регистр PxOUT мы меняем напряжение на лапке микроконтроллера, тем самым включая и выключая светодиод. Читая конкретный бит из регистра PxIN мы получаем логический сигнал, который сейчас подан на пин.

PxSEL выбирает функцию пина. В datasheet на изображении микроконтроллера функции обычно указывают через знак «/».

Например на рисунке P2.7 работает как обычный пин в случае, если P2SEL имеет 0 в соответствующем разряде. По умолчанию, в данном случае, там установлена единица, что означает, что эта лапка предназначена для подключения внешнего часового кварцевого резонатора.

Константы BIT0..BITF содержатся в файле msp430f2274.h и представляют собой 16-ти разрядные слова в заданном разряде которых содержится 1, все остальные разряды содержат 0.

Надо заметить, что файл msp430f2274.h содержит много полезной информации. Там находятся все константы контроллера с комментариями на английском.

В примере используются побитовые операции Си, «|=» установит соответствующий значению справа бит в регистре слева в единицу, а «&= ~» напротив установит его в 0.

Что получилось:



Работа с SPI

Сразу начну с примера
 
#include "msp430f2274.h"
 
unsigned char spi(unsigned char data, unsigned char dataEx = 0x00);
 
void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
 
  P1DIR |= BIT0 + BIT1;
  P1OUT &= ~BIT0;
  P1OUT &= ~BIT1;
 
  P3SEL = BIT1 + BIT2 + BIT3;
  P3DIR |= BIT0;
  P3OUT |= BIT0; // Отключаем CC2500 (устанавливаем 1 на CS)
 
  P2SEL &= ~BIT6;
  P2SEL &= ~BIT7;
  P2DIR |= BIT6 + BIT7;
  P2OUT |= BIT6; // Отключаем датчик температуры (тоже подключен к SPI)
  P2OUT |= BIT7; // Отключаем акселерометр
 
 
  // Конфигурируем SPI
  UCB0CTL0 |= UCMSB + UCMST + UCSYNC;
  UCB0CTL1 |= UCSSEL_2;
  UCB0BR0 = 0x02;
  UCB0BR1 = 0;
  UCB0CTL1 &= ~UCSWRST;
 
  if(spi(0x8F) == 0x32)
  {
    P1OUT |= BIT1; // Красный светодиод
  }
  P1OUT |= BIT0; // Зеленый светодиод
}
 
unsigned char spi(unsigned char data, unsigned char dataEx)
{
  unsigned char RX;
 
  P2OUT &= ~BIT7; // Включаем акселерометр
 
  while (!(IFG2 & UCB0TXIFG)); // Ожидаем готовность буфера отправки
  UCB0TXBUF = data;
  while (!(IFG2 & UCB0RXIFG)); // Ожидаем готовность буфера приёма
  RX = UCB0RXBUF;
 
  while (!(IFG2 & UCB0TXIFG));
  UCB0TXBUF = dataEx;
  while (!(IFG2 & UCB0RXIFG));
  RX = UCB0RXBUF;
 
  P2OUT |= BIT7;
 
  return RX;
}

В примере запрашивается значение регистра по адресу 0x8F, там содержится код, который идентифицирует устройство. Этот код указан в datasheet. Это позволяет убедиться в том, что обмен данными произошел. В случае успеха включаем красный светодиод.
Соответственно все остальные устройства подключенные к SPI необходимо отключить от интерфейса. Для этого CS на них устанавливается в единицу.

Заключение


В следующий раз постараюсь рассказать подробнее про работу с LIS331DLH, добраться до прерываний, поработать со встроенным в программатор мостом USB-UART и рассказать немного про watchdog.

Я надеюсь, что эта статья оказалась полезна тебе, читатель.
Tags:
Hubs:
Total votes 41: ↑37 and ↓4 +33
Views 69K
Comments Comments 12