Мир не стоит на месте, если еще несколько лет назад микроконтроллеры AVR и PIC были основными семействами, как среди радиолюбителей, так и среди разработчиков, то в настоящее время по всем параметрам набирают популярность микроконтроллеры с архитектурой ядра ARM. Чтобы, так сказать, не отставать от прогресса наконец-то взял в руки микроконтроллер STM32, купленный уже достаточно давно. А точнее говоря не микроконтроллер, а минимальную отладочную плату на основе микроконтроллера STM32F103C8T6.
В процессе, как и я, многие могут столкнуться с ситуациями, когда к проекту необходимо подключить какое-то устройство (соответственно библиотеку), чтобы это устройство работало в паре с микроконтроллером, но у вас сам микроконтроллер не той марки, на которых чаще всего пишутся примеры. При подключении подобных библиотек тупо ничего не работает, а компилятор выдает массу ошибок.
В данной статье я предложу модифицированную библиотеку для работы с дисплеями на базе микроконтроллера HD44780, которая позволит работать с размерами до 4 строк по 20 символов. Кроме этого попробуем разобраться, почему же библиотека, написанная, например, для STM32F407 (как наиболее популярный по той причине, что Discovery построена как раз на базе этого микроконтроллера) не будет работать с некоторыми другими микроконтроллерами и наоборот.
Итак, подключаем дисплей к микроконтроллеру, а также необходимую обвязку:
Минусом такого ЖК дисплея является то, что он питается от 5 вольт, в то время как сам микроконтроллер от 3,3 вольт. Поэтому необходимо использовать два уровня напряжения – 5 вольт и 3,3 вольта – стабилизаторы VR1 и VR2. Если питать схему от USB порта компьютера, то стабилизатор VR1 не нужен. А вообще можно использовать ЖК дисплеи с рабочим напряжением в 3,3 вольта, что позволит питать всю схему только от одного напряжения. Экранчик можно использовать любых размеров – 0802, 1602, 2004 (вроде бОльших не встречал). Кроме этого он должен быть на базе HD44780, в противном случае библиотека вряд ли будет работать. Подключение дисплея к микроконтроллеру происходит по четырех битной системе. Выводы дисплея можно разделить на три группы – питание, управление (RS, RW, EN), данные (D0 – D7). По питанию подсветку дисплея необходимо подключать через резистор R1, ограничивающий ток. Его необходимо подбирать таким образом, чтобы подсветка была достаточной яркости, но ток не выходил за пределы номинального. Переменный резистор R2 регулирует контрастность дисплея. Для экономии можно подобрать просто два обычных резистора и использовать вместо переменного, который фактически играет роль делителя напряжения для вывода Vo дисплея. Относительно микроконтроллера на схеме присутствует самый минимум - конденсаторы, подтяжки, кварцевый резонатор. Это то, что задействовано на минимальной отладочной плате для микроконтроллера STM32F103C8T6, которая будет использоваться для работы с ЖК дисплеем.
Для тестирования собираем схему, в моем случае используется минимальная отладочная плата (схема отражает задействованные узлы):
В качестве среды программирование используется Keil. Данная библиотека является модернизацией кода для AVR микроконтроллеров под работу с микроконтроллерами STM32. Библиотека состоит из двух частей - первая часть необходима непосредственно для работы с дисплеями на основе микроконтроллера HD44780, вторая часть библиотеки необходима для вывода переменных на дисплей. Чтобы начать работу, необходимо создать проект, подключить необходимые стандартные библиотеки для выбранного микроконтроллера STM32 и создать файл, в котором будет прописываться вся наша программа, ну и соответственно подключить к проекту файлы библиотеки. Для удобства можно отводить отдельные папки для библиотек, которые подключаются к проекту. Чтобы начать работы с библиотекой необходимо прописать инклуды:
#include "LCD/HD44780.h" // библиотека для ЖК экрана #include "LCD/bcd.h" // библиотека для вывода переменных на ЖК экран
Если вы используете микроконтроллер STM32F10x, то библиотека заработает сразу после вызова функций, прописанных в ней:
void lcd_init(void); // инициализация void lcd_send(u8 byte, dat_or_comm dc); // отправить дисплею информацию или команду void lcd_set_state(lcd_state state, cursor_state cur_state, cursor_mode cur_mode); void lcd_clear(void); // очистить дисплей void lcd_out(char * txt); // вывод строки void lcd_set_xy(uint8_t x, uint8_t y); // позиционирование курсора void lcd_set_user_char(u8 char_num, u8 * char_data); // загрузить пользовательский символ void lcd_delay(void);
А также дополнение к основной библиотеке для вывода переменных на экран:
void BCD_1Lcd(unsigned char value); // значение числа от 0 до 9 void BCD_2Lcd(unsigned char value); // значение числа от 0 до 99 void BCD_3Lcd(unsigned char value); // значение числа от 0 до 255 void BCD_3IntLcd(unsigned int value); // значение числа от 0 до 999 void BCD_4IntLcd(unsigned int value); // значение числа от 0 до 9999
Чтобы изменить выводы микроконтроллера, к которым подключается дисплей, необходимо в заголовочном файле библиотеки HD44780.h прописать необходимую информацию:
// пины управления и данных можно посадить на разные порты // внимательно выбирать выводы (если выводы заняты, например JTAG-ом, то они работать не будут) #define PORT_SIG GPIOB #define PORT_SIG_RCC RCC_APB2Periph_GPIOB #define RS GPIO_Pin_5 #define RW GPIO_Pin_6 #define EN GPIO_Pin_7 #define PORT_DATA GPIOB #define PORT_DATA_RCC RCC_APB2Periph_GPIOB #define DB4 GPIO_Pin_8 #define DB5 GPIO_Pin_9 #define DB6 GPIO_Pin_10 #define DB7 GPIO_Pin_11
Здесь (STM32, ARM) работа с портами ввода-вывода достаточно отличается от других микроконтроллеров (AVR, PIC), что и является фактическим различием между библиотеками для разных МК. БОльшая сложность обусловлена бОльшим функционалом. Таким образом даже у STM32 разные линейки микроконтроллеров могут отличаться инициализацией портов ввода-вывода (различие не в глобальном смысле, а в той информации, которая прописывается для настройки работы, различие не только в названиях портов, но и в шинах тактирования этих портов). Таким образом, чтобы библиотека заработала с другими микроконтроллерами STM32, необходимо заменить инициализацию портов (соответственно и самого ЖК дисплея, так как это все прописывается именно там), а также используемые стандартные библиотеки для соответствующих моделей микроконтроллеров. В этом
#include "hd44780.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x.h" GPIO_InitTypeDef port; GPIO_InitTypeDef port1;
... RCC_APB2PeriphClockCmd(PORT_DATA_RCC, ENABLE); port.GPIO_Pin = DB4 | DB5 | DB6 | DB7; port.GPIO_Mode = GPIO_Mode_Out_PP; port.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(PORT_DATA, &port); RCC_APB2PeriphClockCmd(PORT_SIG_RCC, ENABLE); port1.GPIO_Pin = RS | RW | EN; port1.GPIO_Mode = GPIO_Mode_Out_PP; port1.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(PORT_SIG, &port1); ...
Главное отличие между разными микроконтроллерами STM32 в этом плане, наверно, заключается в том, что выводы могут тактироваться от разных шин, что является необходимым требованием для их работы. поэтому в соответствии с документацией (либо в соответствии с подключаемыми библиотеками) необходимо задавать не только номер вывода, порт и режим работы, но и шину тактирования, что является частой ошибкой при работе с подобными микроконтроллерами и причиной того, что что-то не работает.
Здесь инициализация происходит двумя пачками для пинов передачи информации в четырехбитном режиме DB4, DB5, DB6, DB7 и пинов управления RS, RW, EN. Для большего удобства подключения дисплея к микроконтроллеру инициализацию выводов можно разделить таким образом, чтобы каждый отдельный вывод дисплея можно было подключать на любой вывод микроконтроллера, проинициализировав каждый вывод отдельно.
Таким образом, в используемом микроконтроллере STM32F103C8T6 порты ввода-вывода тактируются по шине APB2:
А, например, при использовании микроконтроллера STM32F407 порты ввода-вывода тактируются по шине AHB1:
Как видно из скриншотов, данное условие по выбору шины тактирования относится не только к портам ввода-вывода, но и ко всем остальным периферийным устройствам (SPI, UART, USB и так далее).
Подробный пример работы с библиотекой можно найти в исходном коде, приложенном ниже (вывод строки, символа, пользовательского символа, а также переменной).
На этом все, надеюсь статья будет полезна начинающим и желающим разобраться с работой микроконтроллеров STM32. Все это затевалось в главной роли для того, чтобы некоторые проекты на AVR микроконтроллерах перевести на STM32 и модернизировать их, развивать далее.
К статье прилагается исходный код в Keil и небольшое видео, показывающее, что данные на экран выводятся корректно и изменение переменной на экране происходит без проблем.
Список радиоэлементов
Обозначение | Тип | Номинал | Количество | Примечание | Магазин | Мой блокнот |
---|---|---|---|---|---|---|
IC1 | МК STM32 | STM32F103C8 | 1 | Поиск в магазине Отрон | ||
VR1 | Линейный регулятор | L7805AB | 1 | Поиск в магазине Отрон | ||
VR2 | Линейный регулятор | AMS1117-3.3 | 1 | Поиск в магазине Отрон | ||
HG1 | LCD-дисплей | 2004a | 1 | HD44780 | Поиск в магазине Отрон | |
Z1 | Кварцевый резонатор | 8 МГц | 1 | Поиск в магазине Отрон | ||
R2 | Переменный резистор | 10 кОм | 1 | Поиск в магазине Отрон | ||
R1 | Резистор | 22 Ом | 1 | Поиск в магазине Отрон | ||
R3, R5 | Резистор | 10 кОм | 2 | Поиск в магазине Отрон | ||
R4 | Резистор | 100 Ом | 1 | Поиск в магазине Отрон | ||
R6 | Резистор | 390 Ом | 1 | Поиск в магазине Отрон | ||
C1 | Электролитический конденсатор | 470 мкФ | 1 | Поиск в магазине Отрон | ||
C2, C4 | Конденсатор | 22 пФ | 2 | Поиск в магазине Отрон | ||
C3, C5-C7, C9-C11 | Конденсатор | 100 нФ | 7 | Поиск в магазине Отрон | ||
C8 | Электролитический конденсатор | 220 мкФ | 1 | Поиск в магазине Отрон | ||
C12 | Электролитический конденсатор | 10 мкФ | 1 | Поиск в магазине Отрон | ||
S1 | Тактовая кнопка | TC-A109 | 1 | Поиск в магазине Отрон | ||
HL1 | Светодиод | Зеленый | 1 | Поиск в магазине Отрон | ||
Скачать список элементов (PDF)
Прикрепленные файлы:
- 4.rar (992 Кб)
Комментарии (17) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация
На счет библиотеки - крайне советую делать ее асинхронной. Т.е. буферизировать команды и вешать latch на прерывания таймера.
Для своих целей мне пришлось писать такую библиотеку с нуля, т.к. висеть по 5 мс пока сольются данные не вариант.
[Автор]
[Автор]
[Автор]
[Автор]
[Автор]
Т.е. нужно переделать библиотеку "stm32f10x.h" в "stm32f1xx_hal.h" и т.д.
А готового проекта под HAL не собираетесь делать?
[Автор]
Мысли переделки были, не успеваю.
[Автор]
[Автор]