PROGCONT.RU

Вход Регистрация
О САЙТЕ ГЛАВНАЯ
 

STM32F учимся работать с цветным графическим дисплеем st7735r.


нет рисунка Продолжаем тему визуализации информации, теперь будем покорять или учится работать TFT дисплеем c диагональю 1.8 дюйма, разрешением 128x160 и драйвером на борту ST7735R SPI. Для тех кто пока выбирает дисплей для своих нужд скажу о недостатках, данные экраны требуют затрат огромного количества памяти и сложности вывода информации так как каждый знак на экране придется собирать из пикселей и для этого вам придется писать свои функции или где то брать готовые библиотеки, так что прежде чем браться за эти LCD хорошо ознакомитесь с их документацией или остановитесь на выборе экранов с готовыми знакогенераторами такие как 1602a( hd44780).
 Кто не испугался продолжаем, начнем как обычно со схемы подключения, в проекте я буду использовать контроллер STM32F103C8 и LCD без платы расширения для первого раза и удобства берите экран с ней.

нет рисунка

 Описание выводов LCD.
GND-земля.
LED- -земля подсветки.
LED+ -питание подсветки, желательно через резистор как у меня на схеме иначе будут засветка от светодиодов.
/RESET-низкий уровень осуществляет сброс экрана, высокий рабочее состояние.
AO-низкий уровень на этом выводе означает что экран должен принять команду, высокий придут данные.
SDA-канал данных SPI.
SCK-канал тактирования SPI.
VCC и IOVCC-питание экрана и его выводов.
CS-низкий уровень разрешает работу с экраном, высокий запрещает, используется для выбора нужного экрана если их больше одного.

 А теперь скачиваем документацию на st7735r и пытаемся там что то понять, для вас я опишу основные команды и порядок отправки данных думаю этого будет достаточно а если нет то вперед к самостоятельным действиям, если узнаете что то интересное то пишите в комментариях я это добавлю в статью.

 Начнем с инициализации LCD, перед тем как это сделать его нужно сбросить установив низкий уровень на выводе /RESET затем повысить до питания тем самым ввести экран в рабочее состояние, после командами выполним основную настройку.
 Далее функциями( как устроенны смотрите в примере программы) отправки команд и данных будем настраивать LCD, первое что сделаем выведем LCD из сна, он всегда в нем находится после включения или сброса.
LCD_Send_Command( 0x11);
после выполним самую главную настройку это порядок вывода изображения на экран( зависит от положения экрана), вывод цветов и порядок обновления.
LCD_Send_Command( 0x36);
и далее данные для конфигурации, эта настройка будет для положения экрана как на схеме подключения то есть горизонтально шлейф подключения находится с право, X=0 и Y=0 это верхний левый угол, вывод графики с верху в низ и с лева на право.
LCD_Send_Data( 0xB4);
тут остановимся по подробней, старшие биты 7-5 отправленных данных отвечают за порядок записи графики в видеопамять или её положение на экране, биты 4 и 2 порядок обновления графики или вывода непосредственно из видеопамяти на экран должно быть попутным с записью в видеопамять, бит 3 отвечает за порядок принятия данных цвета R-G-B или B-G-R, подробней описание смотрите в рисунках ниже.

нет рисунка

продолжаем, отправляем команду настройки битности цветности пикселя
LCD_Send_Command( 0x3A);
и данные настройки 5 бит для цвета R, 6 бит G и 5 для B
LCD_Send_Data( 0x05);
и последнее включаем отображение иначе будет просто белый экран
LCD_Send_Command( 0x29);

нет рисунка
 Инициализацию выполнили осталось изучить порядок вывода изображения, вывод начинается с определения зоны закраски, смотрим в примере ниже.
 Командой и двумя данными( длина 16 бит, старший байт равен 0) мы определяем начало и конец заполнения по X.
LCD_Send_Command(0x2A);
Определяем начало.
LCD_Send_Data(0x00);
LCD_Send_Data( 2);
Определяем конец.
LCD_Send_Data(0x00);
LCD_Send_Data( 6);
 Теперь командой и двумя данными( длина 16 бит, старший байт равен 0) мы определяем начало и конец заполнения по Y.
LCD_Send_Command(0x2B);
Определяем начало.
LCD_Send_Data(0x00);
LCD_Send_Data( 1);
Определяем конец.
LCD_Send_Data(0x00);
LCD_Send_Data( 6);
Зону определили осталось отправить команду записи данных в видеопамять
LCD_Send_Command(0x2C);
затем просто заполняем зону пикселяим нужного цвета отправляя функцией LCD_Send_Data() с начало старший байт цвета после младший, именно столько раз сколько пикселей в нашей зоне тут получается 30.


 Внимание! Максимальная зона которую вы можете определить это область всего экрана или от 0-159 и 0-127(160*128 пикселей), если превысите по X или Y LCD зависнит установив белый цвет.


 Примеры программ.

 В этом примере будет минимальное количество кода для первого старта и понимание как это все работает, программа будет заполнять экран по очереди синим и красным цветом.

#include "stm32f10x.h"
//Функция отправляющая команды в LCD.
void LCD_Send_Command( uint8_t com);
//Функция отправляющая данные в LCD.
void LCD_Send_Data( uint8_t dat);

int main()
{
RCC_DeInit();
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA |RCC_APB2Periph_SPI1, ENABLE);
//Настройка выводов для SPI.
GPIO_InitTypeDef Lcd_pin_spi;
Lcd_pin_spi.GPIO_Mode =GPIO_Mode_AF_PP;
Lcd_pin_spi.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
Lcd_pin_spi.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &Lcd_pin_spi);
//Настройка выводов для управления /RESET и AO.
GPIO_InitTypeDef Lcd_pin;
Lcd_pin.GPIO_Mode =GPIO_Mode_Out_PP;
Lcd_pin.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
Lcd_pin.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &Lcd_pin);
//Настройка SPI.
SPI_InitTypeDef Lcd_Spi1;
Lcd_Spi1.SPI_Direction=SPI_Direction_1Line_Tx;
Lcd_Spi1.SPI_Mode=SPI_Mode_Master;
Lcd_Spi1.SPI_DataSize=SPI_DataSize_8b;
Lcd_Spi1.SPI_CPOL=SPI_CPOL_Low;
Lcd_Spi1.SPI_CPHA=SPI_CPHA_1Edge;
Lcd_Spi1.SPI_NSS=SPI_NSS_Soft;
Lcd_Spi1.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
Lcd_Spi1.SPI_FirstBit=SPI_FirstBit_MSB;
Lcd_Spi1.SPI_CRCPolynomial=7;
SPI_Init( SPI1, &Lcd_Spi1);
SPI_Cmd( SPI1, ENABLE);

//Сброс LCD перед инициализацией.
GPIO_ResetBits( GPIOA, GPIO_Pin_4);
for( uint16_t Pause=1000; Pause>0; Pause--);
GPIO_SetBits( GPIOA, GPIO_Pin_4);
for( uint16_t Pause=1000; Pause>0; Pause--);
//Выводит LCD из сна.
LCD_Send_Command( 0x11);
//Выбор порядка вывода изображения.
LCD_Send_Command( 0x36);
//Вывод изображения Y сверху-низ, X c лева-право зависит от положения, цвет RGB и направление обновления после включения LCD.
LCD_Send_Data( 0xB4);
//Выбор RGB пикселя.
LCD_Send_Command( 0x3A);
//Установка 16 бит RGB.
LCD_Send_Data( 0x05);
//Включаем отображение.
LCD_Send_Command( 0x29);
//Определяем границы зоны по X.
LCD_Send_Command( 0x2A);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 159);
//Определяем границы зоны по Y.
LCD_Send_Command(0x2B);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 127);
LCD_Send_Command(0x2C);

while(1){
//Заполняем зону синим цветом.
for ( uint16_t Pix=0; Pix<128*160; Pix++){
LCD_Send_Data((uint8_t)( 0x001F>>8));
LCD_Send_Data((uint8_t)( 0x001F));
}
for( uint32_t P=1000000; P>0; P--);
//Заполняем зону красным цветом.
for ( uint16_t Pix=0; Pix<128*160; Pix++){
LCD_Send_Data((uint8_t)( 0xF800>>8));
LCD_Send_Data((uint8_t)( 0xF800));
}
for( uint32_t P=1000000; P>0; P--);
}
return 0;
}

void LCD_Send_Command( uint8_t com){
//Устанавливаем AO низкий уровень.
GPIO_ResetBits( GPIOA, GPIO_Pin_6);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
while(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY));
SPI_I2S_SendData( SPI1, com);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
while(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY));
}
void LCD_Send_Data( uint8_t dat){
//Устанавливаем AO высокий уровень.
GPIO_SetBits( GPIOA, GPIO_Pin_6);
SPI_I2S_SendData( SPI1, dat);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
}


нет рисунка Тут выведем на экран уже готовое изображение из массива цветов который я получил с помощью программы ConvertBMP, для первого раза качаем файл img.h ( заставка для видео) в котором находится шестнадцатибитный массив img[] рисунка, не забываем распаковать и поместить в папку где находится код программы данного примера. С помощью выше упомянутой программы можете создать свой массив любого рисунка и заменив img.h файл вывести на экран дисплея, уточняю что для хранения изображения в контроллере потребуется потратить 40 Кб его памяти.

#include "stm32f10x.h"
#include "img.h"
void LCD_Send_Command( uint8_t com);
void LCD_Send_Data( uint8_t dat);

int main()
{
RCC_DeInit();
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA |RCC_APB2Periph_SPI1, ENABLE);
GPIO_InitTypeDef Lcd_pin_spi;
Lcd_pin_spi.GPIO_Mode =GPIO_Mode_AF_PP;
Lcd_pin_spi.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
Lcd_pin_spi.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &Lcd_pin_spi);
GPIO_InitTypeDef Lcd_pin;
Lcd_pin.GPIO_Mode =GPIO_Mode_Out_PP;
Lcd_pin.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
Lcd_pin.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &Lcd_pin);
SPI_InitTypeDef Lcd_Spi1;
Lcd_Spi1.SPI_Direction=SPI_Direction_1Line_Tx;
Lcd_Spi1.SPI_Mode=SPI_Mode_Master;
Lcd_Spi1.SPI_DataSize=SPI_DataSize_8b;
Lcd_Spi1.SPI_CPOL=SPI_CPOL_Low;
Lcd_Spi1.SPI_CPHA=SPI_CPHA_1Edge;
Lcd_Spi1.SPI_NSS=SPI_NSS_Soft;
Lcd_Spi1.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
Lcd_Spi1.SPI_FirstBit=SPI_FirstBit_MSB;
Lcd_Spi1.SPI_CRCPolynomial=7;
SPI_Init( SPI1, &Lcd_Spi1);
SPI_Cmd( SPI1, ENABLE);

GPIO_ResetBits( GPIOA, GPIO_Pin_4);
for( uint16_t Pause=1000; Pause>0; Pause--);
GPIO_SetBits( GPIOA, GPIO_Pin_4);
for( uint16_t Pause=1000; Pause>0; Pause--);
LCD_Send_Command( 0x11);
LCD_Send_Command( 0x36);
LCD_Send_Data( 0xB4);
LCD_Send_Command( 0x3A);
LCD_Send_Data( 0x05);
LCD_Send_Command( 0x29);
LCD_Send_Command( 0x2A);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 159);
LCD_Send_Command(0x2B);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 0);
LCD_Send_Data( 127);
LCD_Send_Command(0x2C);
//Выводим из массива изображение.
for( uint16_t pic=0; pic<160*128; pic++){
LCD_Send_Data((uint8_t)( img[pic]>>8));
LCD_Send_Data((uint8_t)( img[pic]));
}

while(1){

}
return 0;
}

void LCD_Send_Command( uint8_t com){
GPIO_ResetBits( GPIOA, GPIO_Pin_6);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
while(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY));
SPI_I2S_SendData( SPI1, com);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
while(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY));
}
void LCD_Send_Data( uint8_t dat){
GPIO_SetBits( GPIOA, GPIO_Pin_6);
SPI_I2S_SendData( SPI1, dat);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
}


 В этом примере решим проблему вывода текста, для самого текста нам понабиться библиотека с растровыми изображениями символов( букв и знаков) тут я буду использовать свою которую создал с помощью программы TheDotFactory, скачиваем мою библиотеку letters_medium.h для примера, распаковываем и кладем в папку с проектом.

 Описание функций примера.

void LCD_Write_Text ( uint8_t position_X, uint8_t position_Y, uint8_t letter[], uint8_t letter_count, uint16_t color_Letter, uint16_t color_Background )-функция получает массив символов и выводит их в нужном месте экрана, которая должна получить следующие параметры:
position_X-начало текста по X( печатает с лева на право).
position_Y-начало текста по Y( печатает с верху в низ).
letter[]-массив с кодами символов.
letter_count-количество символов для отображения, не должно превышать длину массива символов.
color_Letter-цвет символа.
color_Background-цвет за символом.

uint8_t LCD_Write_Letter ( uint8_t position_X, uint8_t position_Y, uint8_t letter, uint16_t Color_Letter, uint16_t Color_Background )-для вывода одного символа функция, параметры те же что у функции выше только в место массива текста получает код символа letter и возвращает его ширину.

void LCD_Square_Zone( uint8_t start_X, uint8_t stop_X, uint8_t start_Y, uint8_t stop_Y)-определяет зону для заполнения где:
start_X-начало по X.
stop_X-конец по X.
start_Y-старт по Y.
stop_Y-конец по Y.

void LCD_Draw_Square( uint8_t start_X, uint8_t stop_X, uint8_t start_Y, uint8_t stop_Y, uint16_t Color)-рисует квадрат и заполняет его цветом параметр Color, остальные параметры аналогичны функции выше.

uint8_t* Digit_Array( uint16_t number, uint8_t digit[])-функция принимает число number которое будет преобразовано в массив цифр, digit[] массив в котором вернутся данные.

В коде программы будут применяться две команды это LCD_Send_Command( 0x21); включить инверсию экрана и LCD_Send_Command( 0x20); выключить, применяю для мигания.

нет рисунка
 Коды символов не соответствуют ASCII для своего текста их можно узнать в файле letters_medium.h, открываем его и видим в первом массиве ширину символов и их порядок в библиотеке, с лева в комментарии сам символ и его код.

#include "stm32f10x.h"
#include "letters_medium.h"
//Цвета RGB формат 5 бит красный, 6 бит зеленый, 5 бит синий итого 16 бит.
#define WHITE 0xFFFF
#define BLACK 0x0
#define YELLOW 0xFFE0
#define GREEN 0x0400
#define LIGHT_GREEN 0x9772
#define RED 0xF800
#define BLUE 0x001F
void Pause( uint32_t paus){ for( uint32_t p=0; paus>p; p++);}
void LCD_Initialization( void);
void LCD_Square_Zone( uint8_t start_X, uint8_t stop_X, uint8_t start_Y, uint8_t stop_Y);
void LCD_Draw_Square( uint8_t start_X, uint8_t stop_X, uint8_t start_Y, uint8_t stop_Y, uint16_t Color);
uint8_t LCD_Write_Letter ( uint8_t position_X, uint8_t position_Y, uint8_t letter, uint16_t Color_Letter, uint16_t Color_Background );
void LCD_Write_Text ( uint8_t position_X, uint8_t position_Y, uint8_t letter[], uint8_t letter_count, uint16_t color_Letter, uint16_t color_Background );
uint8_t* Digit_Array( uint16_t number, uint8_t digit[]);
void LCD_Send_Command( uint8_t com);
void LCD_Send_Data( uint8_t dat);
//Массив для отображения счетчика.
uint8_t array_digit[5];

int main()
{
//Настраиваем тактирование шины данных и контроллера на 48 MHz .
RCC_DeInit();
FLASH_SetLatency(FLASH_Latency_1);//Пропускаем два такта, для Flash.
FLASH_PrefetchBufferCmd( FLASH_PrefetchBuffer_Enable);// Доступен предварительный буфер.
RCC_PLLConfig( RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);
RCC_PLLCmd( ENABLE);
RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK);
//Включаем тактирование SPI и его выводов.
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA |RCC_APB2Periph_SPI1, ENABLE);
//Настройка выводов.
GPIO_InitTypeDef Lcd_pin_spi;
Lcd_pin_spi.GPIO_Mode =GPIO_Mode_AF_PP;
Lcd_pin_spi.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
Lcd_pin_spi.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &Lcd_pin_spi);
GPIO_InitTypeDef Lcd_pin;
Lcd_pin.GPIO_Mode =GPIO_Mode_Out_PP;
Lcd_pin.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
Lcd_pin.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &Lcd_pin);
//Настройка SPI.
SPI_InitTypeDef Lcd_Spi1;
Lcd_Spi1.SPI_Direction=SPI_Direction_1Line_Tx;
Lcd_Spi1.SPI_Mode=SPI_Mode_Master;
Lcd_Spi1.SPI_DataSize=SPI_DataSize_8b;
Lcd_Spi1.SPI_CPOL=SPI_CPOL_Low;
Lcd_Spi1.SPI_CPHA=SPI_CPHA_1Edge;
Lcd_Spi1.SPI_NSS=SPI_NSS_Soft;
Lcd_Spi1.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
Lcd_Spi1.SPI_FirstBit=SPI_FirstBit_MSB;
Lcd_Spi1.SPI_CRCPolynomial=7;
SPI_Init( SPI1, &Lcd_Spi1);
SPI_Cmd( SPI1, ENABLE);
//Инициализация LCD
LCD_Initialization();
uint8_t ProgC[]={ 47, 81, 78, 70, 34, 78, 77, 83, 13, 81, 84};//ProgCont.ru.
uint8_t Text[]={ 113, 132, 137, 144, 145, 160, 156, 145, 141};//Текст это не СЛОЖНО.
uint8_t Ne[]={ 140, 132};//не.
uint8_t Slojno[]={ 112, 106, 109, 101, 108, 109, 0, 0, 0};//СЛОЖНО.
uint8_t Count[]={ 112, 150, 159, 145, 150, 135, 137, 25};//Счётчик:.
uint8_t Scale[]={ 27, 119, 105, 95, 106, 95, 29};//<ШКАЛА>.

while(1){
//Перекрашиваем экран в синий цвет и выводим Progcont.ru снизу вверх.
LCD_Draw_Square( 0, 159, 0, 127, BLUE);
for(uint8_t i=104; i>0; i-=1){
LCD_Write_Text ( 22, i, ProgC, 11, WHITE, BLUE );
Pause( 500000);
LCD_Draw_Square( 0, 159, i+22, i+22, BLUE);
}
Pause( 20000000);
//Выводим счетчик.
LCD_Draw_Square( 0, 159, 0, 127, BLACK);
LCD_Write_Text ( 4, 28, Count, 8, WHITE, BLACK );
LCD_Write_Text ( 30, 58, Scale, 7, WHITE, BLACK );
LCD_Draw_Square( 32, 132, 85, 100, LIGHT_GREEN);
for( uint16_t d=100; d!=65535; d--){
LCD_Write_Text ( 96, 28, Digit_Array( d, array_digit), 5, BLACK, WHITE );
LCD_Draw_Square( 32, 132-d, 85, 100, RED);
Pause( 800000);
}
Pause( 20000000);
//Выводим Текст это не СЛОЖНО!!! и мигаем экраном.
LCD_Draw_Square( 0, 159, 0, 127, YELLOW);
LCD_Write_Text ( 25, 23, Text, 9, BLUE, YELLOW );
LCD_Write_Text ( 70, 46, Ne, 2, BLUE, YELLOW );
LCD_Write_Text ( 27, 69, Slojno, 9, BLUE, YELLOW );
Pause( 20000000);
for( uint8_t r=10; r>0; r--){
LCD_Send_Command( 0x21);
Pause( 2000000);
LCD_Send_Command( 0x20);
Pause( 2000000);
}
}
return 0;
}

//Функция готовит массив символов чисел.
uint8_t* Digit_Array( uint16_t number, uint8_t digit[]){
digit[0]= number/10000+15;
number= number-(number/10000*10000);
digit[1]= number/1000+15;
number= number-(number/1000*1000);
digit[2]= number/100+15;
number= number-(number/100*100);
digit[3]= number/10+15;
number= number-(number/10*10);
digit[4]= number+15;
return digit;
}
/*Функция выводит текст, position_X начало по X, position_Y начало по Y, letter[] массив символов, letter_count количество символов в массиве, color_Letter цвет символа, color_Background цвет экрана за символом.*/
void LCD_Write_Text ( uint8_t position_X, uint8_t position_Y, uint8_t letter[], uint8_t letter_count, uint16_t color_Letter, uint16_t color_Background ){
uint8_t count_position=position_X;
for( uint8_t i=0; letter_count>i; i++){
count_position+=LCD_Write_Letter ( count_position, position_Y, letter[i], color_Letter, color_Background );
}
}
/*Функция выводит символы, position_X начало по X, position_Y начало по Y, letter код символа, Color_Letter цвет символа, Color_Background цвет экрана за символом.*/
uint8_t LCD_Write_Letter ( uint8_t position_X, uint8_t position_Y, uint8_t letter, uint16_t Color_Letter, uint16_t Color_Background ){
uint8_t column_lett=(Letter_Medium_Count[letter][0]- 1)/8+1;
LCD_Square_Zone( position_X, position_X+1, position_Y, position_Y+21);
LCD_Send_Command(0x2C);
for( uint8_t e=0; 2*22>e; e++){
LCD_Send_Data(( uint8_t)( Color_Background>>8));
LCD_Send_Data(( uint8_t)( Color_Background));
}
LCD_Square_Zone( position_X+2, position_X+Letter_Medium_Count[letter][0]+1, position_Y, position_Y+21);
LCD_Send_Command(0x2C);
uint8_t count_shift=0;
for( uint8_t q=0; 22* column_lett>q; q++){
for( uint8_t w=0; 8>w; w++){
if( Letter_Medium_Count[ letter][0]>count_shift){
if( Letters_Medium[ Letter_Medium_Count[letter][1]+q]<<w&128){
LCD_Send_Data(( uint8_t)( Color_Letter>>8));
LCD_Send_Data(( uint8_t)( Color_Letter));
}else{
LCD_Send_Data(( uint8_t)( Color_Background>>8));
LCD_Send_Data(( uint8_t)( Color_Background));
}
count_shift++;
}else{ w=8; count_shift=0;}
}
}
LCD_Square_Zone( position_X+Letter_Medium_Count[ letter][0]+2, position_X+Letter_Medium_Count[ letter][0]+3, position_Y, position_Y+21);
LCD_Send_Command(0x2C);
for( uint8_t e=0; 2*22>e; e++){
LCD_Send_Data(( uint8_t)( Color_Background>>8));
LCD_Send_Data(( uint8_t)( Color_Background));
}
return Letter_Medium_Count[ letter][0]+2;}
//Функция рисует прямоугольник.
void LCD_Draw_Square( uint8_t start_X, uint8_t stop_X, uint8_t start_Y, uint8_t stop_Y, uint16_t Color)
{
uint8_t y;
uint8_t x;
LCD_Square_Zone(start_X, stop_X, start_Y, stop_Y);
LCD_Send_Command(0x2C);
for ( y=start_Y; stop_Y>=y; y++){
for ( x=start_X; stop_X>=x; x++)
{
LCD_Send_Data((uint8_t)(Color>>8));
LCD_Send_Data((uint8_t)(Color));
}}
}
//Инициализация LCD.
void LCD_Initialization( void){
//Сброс LCD перед инициализацией.
GPIO_ResetBits( GPIOA, GPIO_Pin_4);
Pause( 1000);
GPIO_SetBits( GPIOA, GPIO_Pin_4);
Pause( 1000);
//Выводит LCD из сна.
LCD_Send_Command( 0x11);
//Выбор порядка вывода изображения.
LCD_Send_Command( 0x36);
//Вывод изображения Y сверху-низ, X слева-право зависит от положения, цвет RGB и направление обновления после включения LCD.
LCD_Send_Data( 0xB4);
//Выбор RGB цветности пикселя.
LCD_Send_Command( 0x3A);
//Установка 16 бит RGB.
LCD_Send_Data( 0x05);
//Включаем отображение.
LCD_Send_Command( 0x29);
}
//Функция определение области экрана для заполнения.
void LCD_Square_Zone( uint8_t start_X, uint8_t stop_X, uint8_t start_Y, uint8_t stop_Y){
//Установка пределов по X.
LCD_Send_Command(0x2A);
LCD_Send_Data(0x00);
LCD_Send_Data(start_X);
LCD_Send_Data(0x00);
LCD_Send_Data(stop_X);
//Установка пределов по Y.
LCD_Send_Command(0x2B);
LCD_Send_Data(0x00);
LCD_Send_Data(start_Y);
LCD_Send_Data(0x00);
LCD_Send_Data(stop_Y);
}
//Отправка команд.
void LCD_Send_Command( uint8_t com){
GPIO_ResetBits( GPIOA, GPIO_Pin_6);//Устанавливаем AO низкий уровень.
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
while(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY));
SPI_I2S_SendData( SPI1, com);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
while(SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY));
}
//Отправка данных.
void LCD_Send_Data( uint8_t dat){
GPIO_SetBits( GPIOA, GPIO_Pin_6);//Устанавливаем AO высокий уровень.
SPI_I2S_SendData( SPI1, dat);
while(!SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ));
}
Статья №35 Дата:25/12/2018

Комментарии.