- Войдите или зарегистрируйтесь, чтобы оставлять комментарии
STM32F4VE LCD ili9341 16bit Keil
Всем привет!
В этой статье хочу рассказать о выводе информации на LCD ili9341 в режиме 16bit. Ранее в статье ссылка мною был уже представлен этот LCD и его присоединение к плате STM32F4VE , а также в другой статье - ссылка выводил информацию - STM32F4VE LCD ili9341 16bit CubeMx_Keil . Программа создавалась с помощью генератора начального кода CubeMx. В этой статье мы выведем информацию на LCD ili9341 с помощью Keil Vision и библиотек. Создадим проект, сгенерируем файл с помощью System Clock Configuration. Подключим библиотеки в выведем информацию на экран. Программу будем создавать в Keil µVision® версии v5.29.0.0.
Что мы получим в результате
1. Вывод информации на LCD ili9341 16 bit
2. Возможно регулировать подсветку LCD ili9341 !!
И так приступим..
Запускаем Keil и создаем проект с микроконтроллером STM32F407Vx
В появившемся окне выбираем путь для проекта и название
Нажимаем Сохранить и выходит окно выбора микроконтроллера.
Выбираем STM32F407VETx и OK и попадаем в следующее окно.
Выбираем в нем следующие пункты
Нажимаем OK и выходим в основное окно которое получает следующий вид
И далее два пути:
1. Для тех, кто пока сам не может с нуля собрать проект - статья Первый проект на STM32F407VE Keil до пункта где добавляется в файл main управление светодиодами потом пункт 2.
2. Взять мой пустой проект и наполнить его содержимым. Это быстрее. Ссылка.
Я не буду плодить одинаковые статьи и исправлю (дополню) проект по ссылке выше.
Итак скачиваем, распаковываем в папку, открываем проект в Keil.
Переходим к файлу main.c. Убираем все, что идет после while (1) . Файл main.c получает вид
#include "main.h"
//*******************************************************
int main(void)
{
SysTick_Config(SystemCoreClock / 1000);
// Настраиваем порты
GPIO_init();
// Настраиваем кнопки установленные на плате
button_ini();
//
// Настраиваем связь
USART2_Configuration();
//
while (1)
{
}
}
***********************************************************************
Проверяем все ли нормально - собираем проект
Ошибок быть не должно.
Далее необходимо настроить частоту работы микроконтроллера STM32F407 и его основной периферии.
Для этого ищем архив с файлами файл от фирмы ST под названием en.stsw-stm32091.zip его можно найти в интернете можно скачать у меня - ссылка. Распаковываем его в папку. В папке будут присутствовать файлы
Запускаем файл STM32F4xx_Clock_Configuration_V1.1.0.xls. Для открытия файла должен быть установлен пакет программ - Microsoft Office.
Запускаем файл.
При первом запуске выйдет оно
Включаем содержимое.
И получаем следующее окно
Идея использовать Excel на мой взгляд очень не плохая. Конечно, Excel, он не у всех установлен. И скорее всего этот файл поддерживаться не будет в связи с CubeMx. Но на сегодня файл есть и он работает. И я этим воспользуюсь..
Устанавливаем в нем следующую конфигурацию - ставим все по max !!!
по схеме ниже
И в результате полный вид картинки
Маленький CubeMx такой получается ....
Когда нужная картинка с конфигурацией создана нажимаем
И результатом будет создание файла в той же папке где лежит файл STM32F4xx_Clock_Configuration_V1.1.0.xls
Закрываем Keil !!!
Переходим в папку проекта !!!
У меня это
D:\Keil_pj\Work\407\RTE\Device\STM32F407VETx
Созданный файл копируем в папку STM32F407VETx заменяя тот который там лежит.
Заменяем его на созданный. Если файл по каким-то причинам не получился берем мой ссылка. Файл в архиве. Скачиваем распаковываем и копируем с заменой файл из папки см.выше.
Далее ..
В папке проекта создаем папку Lib для удобства
Заходим в нее и создаем в ней папку с названием ILI9341
Скачиваем папку с библиотекой - ссылка. В архиве файлы
colors.h
font8.c
....
fonts.h
ili9341.c
ili9341.h
image.h
registers.h
Открываем архив и все файлы из архива копируем в ранее созданную ILI9341
Запускаем Keil. И проверяем сначала
Файл самый нижний два раза тыкаем мышкой - когда он откроется - мы увидим следующее
Это заголовок где видно дату создания и где в какой программе он создан и конечно все необходимые нам настройки.
Далее ..
Устанавливаем как на фото ниже
Переходим
В этом окне необходимо!!!
1. Поправить пути к указанным библиотекам - в том случае когда вы скачали МОЙ проект с моими указанными путями для файлов!!!!!
2. Добавить путь к папке ILI9341
Исправляем и добавляем.. в итоге будет вид
Нажимаем OK два раза и выходим в основное окно и добавить наши библиотеки
Для этого
И создаем новую группу
Переименовываем ее
Два раза тыкаем мышкой на созданной папке и откроется окно добавления файлов.
Переходим в окне в папку Lib -> ILI9341 - выделяем в ней мышкой все файлы и жмем Add.
Все файлы пропишутся у нас в проекте
Дальше начинаем наполнять файлы проекта содержимым
Начнем с файла port_ini.c - добавим в него следующие строки сразу после 170 строчки
void LCD_CtrlLinesConfig()
{
// Настраиваем порт D
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7
| GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_13 | GPIO_Pin_1
| GPIO_Pin_0 | GPIO_Pin_15 | GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Конфигурируем D как альтернативную функцию - FSMC */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
/* // Настраиваем порт E */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13
| GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_7 | GPIO_Pin_8
| GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Конфигурируем E как альтернативную функцию - FSMC */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FSMC); //
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FSMC); //
return;
}
/* Конфигурируем FSMC */
void LCD_FSMCConfig()
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructureRead;
FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructureWrite;
/* Enable FSMC Clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
/* Define Read timing parameters */
FSMC_NORSRAMTimingInitStructureRead.FSMC_AddressSetupTime = 2;
FSMC_NORSRAMTimingInitStructureRead.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructureRead.FSMC_DataSetupTime = 5;
FSMC_NORSRAMTimingInitStructureRead.FSMC_BusTurnAroundDuration = 0;
FSMC_NORSRAMTimingInitStructureRead.FSMC_CLKDivision = 0;
FSMC_NORSRAMTimingInitStructureRead.FSMC_DataLatency = 0;
FSMC_NORSRAMTimingInitStructureRead.FSMC_AccessMode = FSMC_AccessMode_B;
/* Define Write Timing parameters */
FSMC_NORSRAMTimingInitStructureWrite.FSMC_AddressSetupTime = 3;
FSMC_NORSRAMTimingInitStructureWrite.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructureWrite.FSMC_DataSetupTime = 6;
FSMC_NORSRAMTimingInitStructureWrite.FSMC_BusTurnAroundDuration = 0;
FSMC_NORSRAMTimingInitStructureWrite.FSMC_CLKDivision = 1;
FSMC_NORSRAMTimingInitStructureWrite.FSMC_DataLatency = 0;
FSMC_NORSRAMTimingInitStructureWrite.FSMC_AccessMode = FSMC_AccessMode_A;
/* Define protocol type */
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; //Bank1
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; //No mux
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; //SRAM type
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; //16 bits wide
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; //No Burst
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; // No wait
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; //Don'tcare
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; //No wrap mode
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; //Don't care
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; //Don't care
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; //Allow distinct Read/Write parameters
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; //Don't care
// Set read timing structure
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct =
&FSMC_NORSRAMTimingInitStructureRead;
// Set write timing structure
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct =
&FSMC_NORSRAMTimingInitStructureWrite;
// Initialize FSMC for read and write
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
// Enable FSMC
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
return;
}
void LCD_Configuration(void)
{
// Настраиваем порты для работы с индикатором
LCD_CtrlLinesConfig();
// Настраиваем FSMC
LCD_FSMCConfig();
}
// Для того чтобы была возможность управлять уровнем яркости от 0-max до 100 - min
// Настроим Таймер3 канал 4 и используем PWM
void LCD_SetBackLight(unsigned short level)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uint16_t CCR1_Val = level;
uint16_t PrescalerValue;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
// Конфигурируем ПОРТ В1 на выход и настраиваем PWM
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3);
PrescalerValue = (uint16_t)((SystemCoreClock) / 100000) - 1;
TIM_TimeBaseStructure.TIM_Period = 100;
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low ;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
/* TIM1 enable counter */
TIM_Cmd(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM3, ENABLE);
}
Далее ....
Дополним его - выделю те строчки которые дополнил.
port_ini.h
void GPIO_init(void);
void LCD_Configuration(void);
void LCD_SetBackLight(unsigned short level);
void button_ini(void);
void delay_ms(uint32_t ms);
void delay_us(uint32_t us);
void USART2_Configuration(void);
Перейдем в main.c
Дополним его - выделю те строчки которые дополнил.
#include "main.h"
#include <stdio.h>
#include <string.h>
#include "ili9341.h"
char str1[60];
char str2[60];
USART2_Configuration();
//
LCD_Configuration();
//
lcdInit();
//
lcdSetOrientation(LCD_ORIENTATION_LANDSCAPE);
lcdFillRGB(COLOR_WHITE);
LCD_SetBackLight(50); //Включаем подсветку на нужную яркость. 0 -max 100- min
// Пишем текст сверху экрана
lcdSetTextFont(&Font24);
lcdSetTextColor(COLOR_BLACK, COLOR_WHITE);
lcdSetCursor(40, 5); // xy
lcdPrintf("www.stm32res.ru");
lcdSetTextColor(COLOR_BLUE , COLOR_WHITE);
lcdSetCursor(80, 65);
lcdPrintf("STM32F4VE");
lcdSetTextColor(COLOR_MAROON , COLOR_WHITE);
lcdSetCursor(20, 100);
lcdPrintf("LCD ili9341 16bit");
lcdSetTextColor(COLOR_RED , COLOR_WHITE);
lcdSetCursor(110, 140);
lcdPrintf("No Hal");
while (1)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_7); //Подаем «0» на PA
delay_ms(450);
GPIO_SetBits(GPIOA, GPIO_Pin_7); //Подаем «1» на PA
delay_ms(450);
}
}
Отлично почти закончили!! Осталось добавить только стандартные библиотеки которые не использовались ранее!!
Для этого
В открывшемся окне
В группу User1 справа добавляем Add Files следующие файлы - это стандартные библиотеки для работы с
FSMC и TIM Добавляем файлы с расширением .с и .h которые находятся соответственно в папках src и inc
Выбрали нажали Add
Выбрали нажали Add
Перешли в папку inc
Выбрали нажали Add
Жмем два раза Ok и выходим в основное окно Keil
Собираем проект
Если все сделано правильно то Error быть не должно !!!
Настраиваем программатор !!!
Я использую ULINK - у меня настройки остаются от проекта.
Прошиваем микроконтроллер!!
В результате на экране появиться изображение. Т.к у нас установлено ~ 50% свечения - экран будет затемненный!!!!
Ура !! Все получилось!!!
Если есть вопросы или необходим исходник проекта из статьи - пишите по адресу stm32@stm32res.ru или Website feedback