суббота, 26 июля 2014 г.

Запускаем UART на MSP430 Launchpad

Это рукодство посвящено тому как запустить аппаратный UART на плате MSP430-Launchpad. Мы будем рассматривать старый Launchpad для контроллеров ValueLine. Он идёт в комплекте с двумя МК: MSP430G2452 и MSP430G2553. Аппаратный UART имеется только в микроконтроллере MSP430G2553, поэтому использовать будем его. Все действия я буду выполнять для ОС Linux, поэтому используется компилятор msp430-gcc. Предполагается что читатель знаком с базовыми принципами работы с MSP430 в ОС Linux, про которые можно прочитать например в серии статей вот здесь . Итак, под катом будет пример работающего кода для коммуникации MSP430 по UART.
Плата Launchpad иммет в своём составе преобразователь USB/UART. За эту функцию отвечает микросхема TUSB3410. UART выведен на джамеперы, котрыми соединяется верхняя и нижняя чать платы. Далее линии RX и TX апаратного UART подведены к ножкам P1.1. и P1.2 микроконтроллера. Возможна установка джамперов для аппартного и программного UART. Для работы с аппаратным UART они должны быть установлены горизонтально, так как показано на картинке, иначе ничего не зарботает. К сожалению, разработчики платы Launchpad ввели ограничение на скорость работы UART. Поэтому номально работает эта плата только на скоростях ниже 9600 бод. Более высокие скорости не работают.


















В ОС Linux Launchpad опознаётся как виртуальный последовательный порт /dev/ttyACM0. Вот вывод dmesg при поключении платы к USB:
vvk@linux-bmx0:~/MSP430/msp430-examples/uart> dmesg|tail
[ 6993.966349] usb 2-1.2: USB disconnect, device number 4
[ 6997.205366] usb 2-1.2: new full-speed USB device \
number 5 using ehci_hcd
[ 6997.315988] usb 2-1.2: New USB device found, \
idVendor=0451, idProduct=f432
[ 6997.315999] usb 2-1.2: New USB device strings: \
Mfr=1, Product=2, SerialNumber=3
[ 6997.316005] usb 2-1.2: Product: Texas Instruments MSP-FET430UIF
[ 6997.316012] usb 2-1.2: Manufacturer: Texas Instruments
[ 6997.316017] usb 2-1.2: SerialNumber: 56FF49ABB1C31F4B 
[ 6997.322097] cdc_acm 2-1.2:1.0: This device cannot \
do calls on its own. It is not a modem.
[ 6997.322107] cdc_acm 2-1.2:1.0: No union descriptor,\
 testing for castrated device
[ 6997.322151] cdc_acm 2-1.2:1.0: ttyACM0: USB ACM device
Здесь видим, что обнаружено новое USB-устройство и для него создан файл устройства виртуального последовательного порта /dev/ttyACM0.
В микроконтроллерах MSP430 за UART, SPI и I2C отвечает модуль USCI, и чтобы настроить UART нужно правильно установить его регистры. Возможна работа модуля только в одном из этих трёх режимах. То есть на одном канале можно задействовать или UART, или SPI, или I2C. За работу UART отвечает модуль UCA, а за I2C и SPI --- модуль UCB. Более подробно обо всех этих режимах можно прочитать в даташите
Теперь рассмотрим пример, реализующий работу с UART на скорости 9600 бод. Пример для работы с UART взят с сайта gpio.kaltpost.de и немного адаптирован. Автор оригинального пооекта --- Stefan Wendler. Пример состоит из четырёх файлов uart.h uart.c main.c и Makefle. Привожу их содержание с комментариями здесь.
Файл uart.h
  1. #ifndef __UART_H
  2. #define __UART_H
  3.  
  4. //Инициализация UART
  5. void uart_init(void);
  6.  
  7. //Установить обработчик прерывания по приёму данных на UART
  8. void uart_set_rx_isr_ptr(void (*isr_ptr)(unsigned char c));
  9.  
  10. //Считать один символ с UART
  11. unsigned char uart_getc();
  12.  
  13. //Переслать один символ по UART
  14. void uart_putc(unsigned char c);
  15.  
  16. //Переслать строку на UART
  17. void uart_puts(const char *str);
  18.  
  19. #endif
Файл uart.с Здесь собственно и производится настройко UART.
  1. #include "msp430.h"
  2. #include "uart.h"
  3.  
  4. #define RXD BIT1 // линии порта P1
  5. #define TXD BIT2 // задействованные под UART
  6.  
  7. /**
  8. * Callback handler for receive
  9. */
  10. void (*uart_rx_isr_ptr)(unsigned char c);
  11.  
  12. void uart_init(void)
  13. {
  14. uart_set_rx_isr_ptr(0L);
  15.  
  16. P1SEL = RXD + TXD; // настраиваем линии порта
  17. P1SEL2 = RXD + TXD;
  18. UCA0CTL1 |= UCSSEL_2; // Источник тактирования UART --- SMCLK
  19. UCA0BR0 = 104; // Настраиваем скорость 1MHz 9600
  20. UCA0BR1 = 0; // 1MHz 9600
  21. UCA0MCTL = UCBRS0; // Модуляция UCBRSx = 1
  22. UCA0CTL1 &= ~UCSWRST; // Инициализируем модуль USCI
  23. IE2 |= UCA0RXIE; // Разрешаем прерывания от UART.
  24. }
  25.  
  26. void uart_set_rx_isr_ptr(void (*isr_ptr)(unsigned char c))
  27. // Назначает обработчик прерывания от UART
  28. {
  29. uart_rx_isr_ptr = isr_ptr;
  30. }
  31.  
  32. unsigned char uart_getc()
  33. {
  34. while (!(IFG2&UCA0RXIFG)); // Буфер приёмника USCI_A0 готов?
  35. return UCA0RXBUF;
  36. }
  37.  
  38. void uart_putc(unsigned char c)
  39. {
  40. while (!(IFG2&UCA0TXIFG)); // Буфер передатчика готов
  41. UCA0TXBUF = c; // TX
  42. }
  43.  
  44. void uart_puts(const char *str)
  45. {
  46. while(*str) uart_putc(*str++);
  47. }
  48.  
  49. void usci0rx_isr(void) __attribute((interrupt(USCIAB0RX_VECTOR)));
  50.  
  51. void usci0rx_isr(void)
  52. {
  53. if(uart_rx_isr_ptr != 0L) { // Если пришёл символ
  54. (uart_rx_isr_ptr)(UCA0RXBUF); // то вызывам обработчик
  55. }
  56. }
Нужно обратить внимание как настраивается скорость UART. Она задаётся регистрами UCA0BR0 и UCA0BR1 и вычисляется по формуле:

Baud = (Fclk)/(UCA0BR0 + 256*UCA0BR1)
То есть в нашем случае для источника тактирования SMCLK тактовая частота Fclk=1 MHz=1000000 Hz. Получаем:
Baud = (1000000)/(104 + 256*0)=9615
Это примерно равно скорости 9600 бод. Для другой скорости нужно пересчитать значения данной пары регистров. Для типовых скоростей они указаны в даташите.
Файл main.c
  1. #include "msp430.h"
  2. #include "uart.h"
  3.  
  4. #define LED_RED BIT0
  5. #define LED_GREEN BIT6
  6.  
  7. void uart_rx_isr(unsigned char c)
  8. {
  9. switch (c) { // Обработчик прерывания от UART
  10. case '1': P1OUT ^=LED_RED; // Если пришла единица
  11. uart_puts("Red led toggled\n"); // то переключим красный
  12. break; // светодиод
  13. case '2': P1OUT ^= LED_GREEN; // Если пришла двойка
  14. uart_puts("Green led toggled\n"); // то переключим зелёный
  15. break;
  16. default: uart_putc(c);
  17. break;
  18. }
  19. }
  20. int main(void)
  21. {
  22. WDTCTL = WDTPW + WDTHOLD; // Стопорим WatchDog Timer
  23. BCSCTL1 = CALBC1_1MHZ; // Тактовая частота 1MHz
  24. DCOCTL = CALDCO_1MHZ;
  25. P1DIR = LED_RED + LED_GREEN; // Настраиваем GPIO
  26. P1OUT = LED_RED + LED_GREEN; // Включим светодиоды
  27.  
  28. uart_init(); // Инициализируем UART
  29.  
  30. // register ISR called when data was received
  31. uart_set_rx_isr_ptr(uart_rx_isr);
  32. // Регистрируем обработчик прерывания по UART
  33.  
  34. __bis_SR_register(GIE);
  35.  
  36. uart_puts("\n***************\n"); // Напечатем приветствие
  37. uart_puts("MSP430 harduart\n");
  38. uart_puts("***************\n");
  39.  
  40. __bis_SR_register(LPM0_bits+GIE);
  41. // уходим в спячку и ждём прерывания
  42. for(;;);
  43.  
  44. }
Файл Makefile
  1. CC=msp430-gcc
  2. LD=msp430-gcc
  3. MCU=msp430g2553
  4. CFLAGS= -mmcu=$(MCU) -Wall -Os -c
  5.  
  6. TARGET=demo-uart.elf
  7.  
  8. $(TARGET): main.o uart.o
  9. $(LD) -mmcu=$(MCU) main.o uart.o -o $(TARGET)
  10.  
  11. main.o: main.c
  12. $(CC) $(CFLAGS) main.c -o main.o
  13.  
  14. uart.o: uart.c uart.h
  15. $(CC) $(CFLAGS) uart.c -o uart.o
  16.  
  17. install:
  18. mspdebug rf2500 "prog $(TARGET)"
  19.  
  20. clean:
  21. rm -f *.o *.elf
Все четыре файла нужно положить в один каталог. Компилируем проект командой make.
Для проверки работы нашей программы требуется терминальная программа. Для начинающего можно использовать например простую и понятную программу CuteCOM. В ней нужно установить скорость и параметры порта. Она уже наверняка есть в вашем дистрибутиве Linux. В openSUSE её можно установить командой
zypper in cutecom
Теперь прошиваем плату командой make install и в итоге мы должны получить вот такой вывод в эмуляторе терминала. В качестве устройства последовательного порта в CuteCOM нужно указать /dev/ttyACM0 : ***************
MSP430 harduart
***************
Green led toggled
Red led toggled

Вот скриншот CuteCOM:
В следующей части будет рассказано, как управлять последовательным портом на плате Launchpad из консоли Linux.
Исходники для данного проекта доступны на Гитхабе.

1 комментарий:

  1. т.е. в самом типовом случае применения микроконтроллеров: аппаратный интерфейс/конвертер USBSerial->GPIO/SPI вся линейка MSP430G в пролете т.к. не умеет аппаратно в UART+SPI?

    ОтветитьУдалить