Продолжаем осваивать STM32F4. В дальнейшем, нам понадобится как то общаться с микроконтроллером, один из наиболее простых способов — вывод информации на символьный ЖК дисплей и управление кнопками. Вот этим мы и займемся сегодня.
Инфа не первой свежести, ранее был урок3 — «подключение дисплея к AVR микроконтроллеру», а также статья «Как пишутся библиотеки», где подробнейшим образом рассматривалась инициализация и передача символов. В общем, рекомендую хотя бы поверхностно ознакомиться с данными статьями. Мы же кратко пробежимся по верхам.
Сразу оговоримся, речь идет о HD44780 совместимых дисплеях, если ваш дисплей другой — читайте даташит 🙂 Ножки дисплея можно условно разделить на 3 группы: питание, управление, данные. Важно! названия ножек дисплея могут отличаться, но общая суть не меняется, поэтому не поленитесь заглянуть в даташит.
С питанием все просто GND-земля, V0-контраст, Vcc-5В. Проблемы могут только с контрастом, обычно напряжение находится в диапазоне 0-5В, поэтому ставят внешний построечный резистор, позволяющий регулировать напряжение. Ножки относящиеся к управлению: RS — выбор типа сообщения (команды/данные), RW — чтение/запись, E — синхронизация (отправка данных на дисплей). Ножки данных D0-D7, когда они задействованы все, то дисплей находится в 8-битном режиме, т.е. за один раз мы можем отправить 1 байт, иначе говоря символ. Если задействованы только ножки D4-D7, то отправка байта данных займет уже две команды, такой режим называется 4 битным.
Хитростей с подключением к плате Discovery нет, подсоединяем напрямую к каким угодно ножкам, только для контраста придется внешний резистор подцепить. С библиотекой пришлось немного повозиться, ибо все скачанные почему то не работали. В репозитории кокса была некая рабочая бета версия, но в ней проблема с тем, что все ножки должны быть на одном порту и косяк с задержками. В общем я ее чуток ковырнул на свой лад. Теперь ножки управления можно повесить на один порт, а данных на другой. Можете допилить/переделывать библиотеку, сделать все ножки индивидуально настраиваемыми, все это только приветствуется.
Настройки портов производятся в hd44780.h Настройки порта
/////should be defined by user ///// #define PORT_SIG GPIOA //настраиваем порт ножек управления #define PORT_SIG_RCC RCC_AHB1Periph_GPIOA //в данном случае используется портА ножки 1 и 3, RW достаточно подцепить на землю GND #define RS GPIO_Pin_1 #define RW GPIO_Pin_2 #define EN GPIO_Pin_3 #define PORT_DATA GPIOE //настраиваем порт ножек управления #define PORT_DATA_RCC RCC_AHB1Periph_GPIOE //в данном случае используется портЕ ножки 11-14 #define DB4 GPIO_Pin_14 #define DB5 GPIO_Pin_13 #define DB6 GPIO_Pin_11 #define DB7 GPIO_Pin_12 /////////////////////////////////// |
Прототипы используемых функций можно посмотреть в том же hd44780.h. Для примера выведем строчку hello.
#include <stm32f4xx_gpio.h> #include <stm32f4xx_rcc.h> int main(void) { lcd_init(); lcd_out("hello"); while(1){} } |
Теперь перейдем к кнопке. Товарищ steep_zero любезно поделился своими исследованиями на этот счет, за что отдельное спасибо, поэтому я решил поддержать стремления и скопипастил код 🙂 Физически кнопка прицеплена к портуA ноге 0. Нажатие регистрируется наличием логической единицы.
Обычно в авр кнопка подтянута к плюсу питания, для защиты от помех. В stm32 можно подтягивать к земле, поэтому можно извращаться как угодно. Сама программа: при загрузке выводим приветствие, после нажатия кнопки — текст button.
#include <stm32f4xx_gpio.h> #include <stm32f4xx_rcc.h> int main(void) { GPIO_InitTypeDef PORT_SETUP; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Включить тактирование PORTA PORT_SETUP.GPIO_Pin = GPIO_Pin_0;//задаем номер вывода, если кнопка подключена, например к 6 порту, то пишем GPIO_Pin_6 PORT_SETUP.GPIO_Mode = GPIO_Mode_IN;//порт будет работать как цифровой вход PORT_SETUP.GPIO_PuPd = GPIO_PuPd_DOWN;//включаем подтяжку к «земле» GPIO_Init( GPIOA , &PORT_SETUP); //записать настройки lcd_init(); //инициализация дисплея lcd_out("hello"); //приветствуем while(1) { if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1) //проверка нажатия { lcd_set_xy(0,0); //перемещаемся в координату 0,0 lcd_out("button"); //выводим текст } } } |
Хочется отметить, что с момента приобретения платы STM32F4Discovery, появилось много сайтов, видеоуроков и документации. Поэтому чаще возникает мысль, что выбрано правильное направление.
Проект кокоса
Пытался переделать этот код под Stm32f3discovery, но компилятор упорно ругается на «RCC_AHB1Periph_GPIOA», утверждая, что она не определена (undifined). С чем это могло бы быть связано? В соответствующих библиотеках нашел такую же конструкцию, как для f4, но в случае с f4 она принимает ее нормально.. (Пробовал сменить на AHB2, так как все GPIO_port сидели в этом случае на ней, но безрезультатно)
Попробуйте поменять на RCC_AHBPeriph_GPIOA
Спасибо! Ругаться перестал. Правда теперь вылезла куча предупреждений и одна итоговая ошибка: collect2.exe:error: Id returned 1 exit status, Никогда ранее не сталкивался с подобным. Можете подсказать куда копать?
Ошибка оказалась простой: мудила-редефайнил одно и тоже в переделанной и в непеределанной библиотеках (Старые не удалил!)
А зачем вообще определять RW выход через ножку A2, когда его все равно цепляем на землю? Кстати контраст через резистор цеплять именно к земле? Использование резистора номиналом в 910 Ом может спровоцировать большой ток,который пробьет диод у отладочного USB порта?
На экран не выводит,хотя он точно такой же. при этом на мк была старая прошивка (мельница светодиодная, аля второй урок для 3 платки). После прошивки новым кодом для вывода. остались гореть три светодиода. можно ли считать, что мк завис?
Сокол, RW можно не определять, про usb порт не понял. если вы от него питать собрались, то контраст ток не жрет, жрет подсветка.
Марс, скорее всего в либе нужно еще что то править именно под ваш мк
Ложная тревога. В общем разобрался — важно не только переписывать библиотеку под другой МК, а еще подключать к правильным ножкам я задействовал ножки PA13-PA15, которые заняты JTAG-ом, соответственно они не работают как порты вывода без ремапа. Вот уж на stm нужна двойная внимательность
да есть такие грабли. особенно здорово когда случайно swd отключаешь
Подскажите пожалуйста, а как вывести на экран переменную, а не заранее заданный текст. Например мы получаем значение температуры от ds18b20, помещаем их в переменную, а как вывести переменную на экран — фантазии не хватает.
преобразовывайте данные через sprintf http://avr-start.ru/?p=796
Спасибо за оперативный ответ)
sprintf это хорошо, но для чисел с плавающей точкой он много кушает памяти. Даже я бы сказал чрезмерно много. Если выводить только температуру, то лучше написать простенькую функцию для перевода числа в текст. С учетом того что датчик выдает температуру умноженную на 10, то загнать значение в массив труда не составит. Всего-то нужен массив на 6 элементов. Знак, два числа целого, точка, десятая часть(причем 0 или 5) и нулевой символ. Или все же я не прав?
Подскажите пожалуйста, как преобразовать и вывести на дисплей с помощью вашей библиотеки переменную в формате uint8_t. Пытаюсь считать показания с датчика LIS302, а выводит иероглифы
почитайте http://avr-start.ru/?p=4557 библиотека тут не при чем
Подскажите пожалуйста! У меня плата STM32F429I-DISCO на STM32F429ZIT6U Ваш пример в CooCox нормально создал без ошибок HEX , зашил, подсоединил дисплей 1602 с тем же контроллером 44780 — не выводит даже стартовое сообщение. Подскажите в чем может быть проблема? Я верно понял что пример универсальный для данного типа дисплеев!?
пример универсальный, только периферию надо настраивать правильно — тактирование, порты, задержки.