Ранее на нашем сайте мы уже рассматривали подключение к MSP430 ЖК дисплея с помощью Energia IDE, в этой же статье мы рассмотрим этот процесс с помощью программного обеспечения Code Composer Studio (CCS), являющимся официальным инструментом для программирования микроконтроллеров серии MSP430. Сразу отметим что это будет несколько сложнее чем с помощью Energia IDE, поскольку CCS требует большего погружения в принципы работы микроконтроллера. Основы работы с Code Composer Studio мы рассматривали в этой статье.
Ранее на нашем сайте мы уже рассматривали подключение ЖК дисплея 16x2 к следующим микроконтроллерам (платам):
- к микроконтроллеру AVR;
- к микроконтроллеру PIC;
- к плате Arduino;
- к плате Raspberry Pi;
- к плате Raspberry Pi Pico;
- к плате Raspberry Pi Zero;
- к плате STM32 Blue Pill;
- к модулю ESP32.
Необходимые компоненты
- Плата MSP430G2 LaunchPad (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Макетная или перфорированная плата.
- Соединительные провода.
Основные принципы работы ЖК дисплея 16х2
ЖК дисплей 16х2 содержит в своем составе микросхему контроллера hd44780 (показан на рисунке ниже овалом красного цвета), который может хранить поступающие команды и данные. ЖК дисплей 16х2 имеет 16 контактов, 8 из которых являются контактами данных, 4 – для подачи питания и управления фоновой подсветкой, 3 контакта управления и 1 контакт для регулировки контрастности.
В данном проекте для подключения ЖК дисплей 16х2 к микроконтроллеру MSP430 мы будем использовать библиотеку, разработанную Dennis Eichmann. Она очень удобна в использовании и позволяет выводить на экран дисплея данные различных типов. Также она поддерживает различные типы подключения дисплея, в данном проекте мы будем использовать 8 контактов данных для подключения дисплея.
Назначение контактов (распиновка) ЖК дисплея 16х2 показано на следующем рисунке.
Всего ЖК дисплей 16x2 содержит 16 контактов, которые можно условно разделить на следующие 4 группы.
Source Pins (1, 2 и 3): используются для подачи питания на дисплей и регулировки уровня его контрастности.
Control Pins (4, 5 и 6): контакты управления. Используются для установки различных режимов работы дисплея.
Data/Command Pins (7-14): контакты для передачи данных/команд.
LED pins (15 и 16): контакты для включения/выключения фоновой подсветки дисплея (если она нужна).
Для корректной работы дисплея обязательно использование только 10 контактов из 16 перечисленных.
Подключение в CCS библиотеки для работы с ЖК дисплеем 16х2.
Мы будем использовать библиотеку, разработанную Dennis Eichmann. Скачать ее можно по следующей ссылке. Для ее подключения в Code Composer Studio выполните следующую последовательность шагов.
Шаг 1. Создание файлов и проекта.
Проект в CCS можно создать из его меню (пункт file). В диалоговом окне создания проекта (Create Project dialog box) выберите устройство (device), в качестве имени проекта введите hd44780. Под типом проекта и инструментальными средствами (toolchain) выберите в качестве выходного типа Static library и создайте проект.
Слева в панели эксплорера проекта (Project Explorer lane) создайте заголовочный файл в каталоге include и назовите его hd44780.h. затем скопируйте содержимое скачанного файла hd44780.h в этот созданный файл.
После этого создайте основной проект при помощи изменения выходного типа (output type) на исполнимый файл (executable) и создайте проект с именем CCS_LCD.
Шаг 2. Подключение путей поиска к основному проекту.
В диалоговом окне свойств проекта hd44780 и внутри опций include для компилятора MSP430, добавьте каталог include в каталог поиска файла.
После этого скомпонуйте (build) проект чтобы создать необходимые файлы компоновщика такие как .lib файлы. В результате этой операции в каталоге debug должен создаться файл hd44780.lib.
Шаг 3. Подключение путей поиска для компоновщика.
В диалоговом окне свойств проекта CCS_LCD в пути поиска файла (file search path) на вкладке компоновщика MSP430 (MSP430 Linker tab), подключите файл hd44780.lib, расположенный внутри каталога debug проекта hd44780. Каталог debug также при этом подключится к пути поиска файла.
Каталог include снова добавьте в include options компилятора MSP430 проекта CCS_LCD.
После этого библиотека будет успешно скомпилирована и добавлена в компоновщик основного проекта.
Функции для работы с ЖК дисплеем в MSP430
void hd44780_timer_isr( void ): данная функция периодически вызывается в качестве функции обработки прерывания (ISR) таймера Timer A. Данный таймер используется для выполнения таких операций с ЖК дисплеем как очистка экрана, установка положения курсора и отображение данных. Функция должна использоваться в качестве функции обработки прерывания. Она ничего не возвращает.
uint8_t hd44780_write_string ( char * ch__string, uint8_t u8__row, uint8_t u8__column, uint8_t u8__cr_lf ): записывает строку, указанную в ней в качестве первого аргумента.
char * ch__string: строка, которую необходимо записать в буфер данных (внутри функции hd44780_timer_isr). Данные будут скопированы в регистр данных и регистр команд микросхемы ЖК дисплея когда будет вызываться функция hd44780_timer_isr.
uint8_t u8__row: определяет строку дисплея, в которую будет выводиться строка данных.
uint8_t u8__column: определяет столбец дисплея, в которую будет выводиться строка данных.
uint8_t u8__cr_lf: если данный параметр равен 1, вывод будет осуществляться на следующую строку, а если 0 – то в текущую строку.
void hd44780_clear_screen( void ): очищает весь экран, ничего не возвращает.
uint8_t hd44780_output_unsigned_16bit_value(uint16_t u16__value, uint8_t u8__leading_zero_handling, uint8_t u8__row, uint8_t u8__column, uint8_t u8__cr_lf ): отображает 16-битное число целого типа без знака на необходимой позиции дисплея.
uint16_t u16__value: число целого типа, которое необходимо отобразить.
uint8_t u8__leading_zero_handling: если 0, то будут показаны ведущие нули для отображаемого числа целого типа. Если 1 – нули будут вырезаны. Если 2 – будут показаны только значимые цифры.
uint8_t u8__row: строка дисплея, в которую будет выводиться число.
uint8_t u8__column: столбец дисплея, в который будет выводиться число.
uint8_t u8__cr_lf: если данный параметр равен 1, вывод будет осуществляться на следующую строку, а если 0 – то в текущую строку.
Схема проекта
Схема подключения ЖК дисплея к MSP430 представлена на следующем рисунке.
Для питания схемы мы будем использовать адаптер на 5V.
Схема соединений проекта приведена в следующей таблице.
ЖК дисплей | MSP430 |
Vss | земля источника питания 5V |
Vdd | 5V |
V0 | к потенциометру |
RS | P2.1 |
R/W | Ground |
E | P2.0 |
D0 | P1.0 |
D1 | P1.1 |
D2 | P1.2 |
D3 | P1.3 |
D4 | P1.4 |
D5 | P1.5 |
D6 | P1.6 |
D7 | P1.7 |
A | резистор 220 Ом |
K | Ground |
Анод подсветки ЖК дисплея нельзя непосредственно подключать к источнику 5V, его следует подключать через токоограничивающий резистор, минимизирующий протекающий ток через модуль ЖК дисплея. Для сборки проекта мы использовали перфорированную плату, вы можете использовать макетную плату если хотите.
Внешний вид собранной конструкции проекта показан на следующем рисунке.
Объяснение кода программы
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Первым делом в программе мы откроем заголовочный файл hd44780.h и подключим необходимый заголовочный файл.
1 |
#include "msp430g2553.h" |
Затем остановим работу сторожевого таймера и настроим частоту работы кварцевого генератора микроконтроллера с помощью регистров DCOCTL и BCSCTL1.
1 2 3 |
WDTCTL = (WDTPW | WDTHOLD); BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; |
Далее зададим режим работы контактов порта 1 на вывод данных – с них будут передаваться данные на ЖК дисплей. Также зададим режим работы на вывод данных для контактов 0 и 1 порта 2 – они подключены к контактам RS и R/W ЖК дисплея.
1 2 |
P1DIR = 0xFF; P2DIR = (0x01 | 0x02); |
Встроенный таймер будет использоваться для периодического отображения значений на экране дисплея. Для Timer A выбирается частота работы 1 МГц с помощью SMCLK и задается непрерывный режим работы.
1 2 3 |
TA0CCR1 = 32768; TA0CCTL1 = CCIE; TA0CTL = (TASSEL_2 | MC_2 | TACLR); |
Прерывания от каналов сравнения 1 и 2 и переполнения таймера используют один и тот же вектор прерывания (TIMER0_A1_VECTOR) с различными стартовыми адресами. Канал сравнения 1 (CCR1) использует 2 в качестве адреса, который используется у нас в операторе switch. Более подробно о прерываниях в MSP430 вы можете прочитать в этой статье.
1 2 3 4 5 6 7 8 9 10 11 12 |
#pragma vector = TIMER0_A1_VECTOR __interrupt void timer_0_a1_isr( void ) { switch( TA0IV ) { case 2: { hd44780_timer_isr(); break; } } } |
После компиляции кода программы загрузите его в плату MSP430 как описано в данной статье. Если все работает так, как надо, вы должны увидеть как на ЖК дисплее начнет отображаться информация.
Если на экране ЖК дисплея ничего не видно попробуйте отрегулировать его контрастность с помощью потенциометра. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.
Исходный код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include "msp430g2553.h" // Microcontroller specific header file #include "hd44780.h" // библиотека для работы с контроллером HD44780 uint8_t value=0; void main( void ) { WDTCTL = (WDTPW | WDTHOLD); // останавливаем сторожевой таймер BCSCTL1 = CALBC1_1MHZ; // Set range to calibrated 1MHz DCOCTL = CALDCO_1MHZ; // Set DCO step and modulation for 1MHz P1DIR = 0xFF; // устанавливаем режим работы контактов с P1.0 (D0) по P1.7 (D7) на вывод данных P2DIR = (0x01 | 0x02); // устанавливаем режим работы контактов P2.0 (E) и P2.1 (RS) на вывод данных TA0CCR1 = 32768; // устанавливаем значение CCR1 для прерываний с интервалом 32.678 ms TA0CCTL1 = CCIE; // Compare interrupt enable TA0CTL = (TASSEL_2 | MC_2 | TACLR); //SMCLK, непрерывный режим __bis_SR_register( GIE ); // глобальное разрешение прерываний hd44780_clear_screen(); // очищаем экран дисплея while( 1 ) // бесконечный цикл – основная программа { hd44780_write_string( "Circuit Digest!", 1, 1, NO_CR_LF ); hd44780_output_unsigned_16bit_value( value++, 2, 2, 1, 0 ); if(value>10) value=0; } } // Directive for timer interrupt #pragma vector = TIMER0_A1_VECTOR __interrupt void timer_0_a1_isr( void ) // функция обработки прерывания от Timer 0 A1 { switch( TA0IV ) // определяем источник прерывания { case 2: // прерывание от CCR1 { hd44780_timer_isr(); // вызов функции обработки прерывания от HD44780 break; // CCR1 interrupt handling done } } } |