PROGCONT.RU

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

STM8S и LCD 1602a или hd44780 описание работы, примеры программ для обмена информацией.


 Решая проблемы индикации мы подошли к изучению LCD модуля на чипе 1602a или тот же hd44780, достоинство его в возможности подробно отображать информацию( буквы, цифры и знаки) и конечно цена, к недостаткам отнесу его интерфейс обмена информацией( параллельный) для которого требуется большее количество соединений чем последовательному а так же обязательное выдерживание пауз для обработки им информации что сильно замедляет обмен данными.
 Перед изучение прошу ознакомится с описанием и на русском описание далее я попробую объяснить по своему, начнем конечно с подключения к контроллеру я буду использовать STM8S903K3.

нет рисунка

Описание выводов LCD:
VSS и VDD-питание GND и +5V.
VO-контрастность дисплея, подключается через переменный резистор 10K для регулировки.
RS-если на этом выводе низкий уровень значит передается команда, высокий данные.
R/W-вывод используется для чтения или записи в модуль LCD, низкий уровень модуль принимает данные высокий отдает.
E-при переходе с низкого на высокий уровень на этом выводе LCD проверяет состояние RS и R/W в зависимости от их состояния выставит сам данные на D0-D7 или по спаду с них прочтет данные.
D0-D7-выводы команд и данных.
A и K-выводы светодиода подсветки, для уменьшения яркости используйте внешний резистор.

 На схеме показана передача данных по восьми линиям D0-D7 если нужно сэкономить выводы возможна передача по четырем линиям D4-D7 остальные D0-D3 можно не использовать, вывод RW используется для чтения из памяти LCD и опроса его состояния тоже можно не использовать но нужно тогда обязательно подтянуть его к земле.
 Выводы RS, R/W и D0-D7 и E являются болтающимися( не подтянут к питанию или земле), вывод E рекомендую подтянуть к питанию если этого не сделать то при старте или загрузки контроллера на этом выводе возникают помехи которые могут привести LCD к зависанию.


Таблица команд.

нет рисунка

 
Инициализация, передача и прием данных.

нет рисунка

 Из схемы выше мы видим что основное действие в инициализации это запись трижды одной команды которая определяет восьмибитную передачу данных даже если соединение четырехбитное. Для перенастройки на четырехбитную линию данных должны выполнить тужу команду только D4( DL)=0, после выполняем полную настройку отсылая команды по полубайтам.
 Отображение символов должно начинаться с установки курсора в нужную позицию путем записи в DDRAM адреса или выполнения команды возвращения курсора в начальную позицию, после передаем как данные код символа.
 Ниже адреса DDRAM и кода символов.

нет рисунканет рисунка

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

 Внимание! В функциях отправки команд, данных у меня стоят задержки Pause( 5) и Pause( 2000) значение в которых вы должны изменить в зависимости от тактирования, если частота больше то и задержка должна быть больше, что бы LCD успевал отработать команды и данные.

нет рисунка
 Контроллер для корректной отправки в LCD данных должен выполнять следующую последовательность на выводах RS, R/W, E и D0-D7:
 1.Устанавливаем на RS и R/W нужный уровень.
 2.Устанавливаем на E выводе высокий уровень.
 3.Устанавливаем на D0-D7 данные.
 4.Устанавливаем на E выводе низкий уровень.
 5.Выдерживаем время, что бы LCD успел обработать данные и вывести на экран нужные символы.
 Первый пример будет с передачей данных по восьмибитной линией, тут мы будем просто выводить PROGCONT.ru с начальной позиции а потом с конца второй строки.

#include "stm8s.h"
void pause( uint32_t p);
//Функция отсылки команды.
void send_comand( uint8_t data);
//Функция отсылки данных.
void send_data( uint8_t data);
//Массив PROGCONT.ru.
uint8_t text[11]={ 80, 82, 79, 71, 67, 79, 78, 84, 46, 114, 117};
int main( void )
{
CLK_HSIPrescalerConfig( CLK_PRESCALER_HSIDIV1);
//Настройка выводов для D0-D7.
GPIO_Init( GPIOD, GPIO_PIN_ALL, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
//Настройка выводов E, RS и R/W.
GPIO_Init( GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// E Enable Signal
GPIO_Init( GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// RS H--Data Input L--Instruction Input
GPIO_Init( GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// R/W H--Read L--Write
//Инициализация LCD три команды и три настройка.
pause( 10000);
send_comand( 48);
send_comand( 48);
send_comand( 48);
send_comand( 56);
send_comand( 1);
send_comand( 14);
while(1){
//Очищаем экран и возвращаем курсор в начальную позицию.
send_comand( 1);
//Выводим PROGCONT.ru с начальной позиции.
for( uint8_t i=0; i<11; i++){
send_data( text[i]);
pause( 100000);
}
// Меняем направление курсора и устанавливаем его в конец второй строки.
send_comand( 4);
send_comand( 207);
//Выводим PROGCONT.ru в обратном порядке.
for( uint8_t i=10; i!=255; i--){
send_data( text[i]);
pause( 100000);
}
pause( 1000000);
}
return 0;
}
void send_comand( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_data( uint8_t data){
GPIO_WriteHigh(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void pause( uint32_t p){
for( uint32_t i=0; i<p; i++){ }
}
#ifdef USE_FULL_ASSERT
void assert_failed( uint8_t* file, uint32_t line)
{
while (1){}
}
#endif

 Теперь будем работать по четырехбитной линии связи, тот же пример что и выше.

#include "stm8s.h"
void pause( uint32_t p);
//Функция отсылки команды по четырехбитной линии.
void send_comand_4bit( uint8_t data);
//Функция отсылки команды по восьмибитной линии.
void send_comand_8bit( uint8_t data);
//Функция отсылки данных по четырехбитной линии.
void send_data_4bit( uint8_t data);
//Массив PROGCONT.ru.
uint8_t text[11]={ 80, 82, 79, 71, 67, 79, 78, 84, 46, 114, 117};
int main( void )
{
CLK_HSIPrescalerConfig( CLK_PRESCALER_HSIDIV1);
//Настройка выводов для D4-D7.
GPIO_Init( GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
//Настройка выводов E, RS и R/W.
GPIO_Init( GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// E Enable Signal
GPIO_Init( GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// RS H--Data Input L--Instruction Input
GPIO_Init( GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// R/W H--Read L--Write
//Инициализация LCD три команды, одна перенастройка на 4 битную линию и 2 команды настройки.
pause( 10000);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 32);
send_comand_4bit( 40);
send_comand_4bit( 14);
while(1){
//Очищаем экран и возвращаем курсор в начальную позицию.
send_comand_4bit( 1);
//Выводим PROGCONT.ru с начальной позиции.
for( uint8_t i=0; i<11; i++){
send_data_4bit( text[i]);
pause( 100000);
}
// Меняем направление курсора и устанавливаем его в конец второй строки.
send_comand_4bit( 4);
send_comand_4bit( 207);
//Выводим PROGCONT.ru в обратном порядке.
for( uint8_t i=10; i!=255; i--){
send_data_4bit( text[i]);
pause( 100000);
}
pause( 1000000);
}
return 0;
}
void send_comand_8bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_comand_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_data_4bit( uint8_t data){
GPIO_WriteHigh(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void pause( uint32_t p){
for( uint32_t i=0; i<p; i++){ }
}
#ifdef USE_FULL_ASSERT
void assert_failed( uint8_t* file, uint32_t line)
{
while (1){}
}
#endif

 Надеюсь как выводить стандартные символы вы научились теперь будем работать с нестандартными или как решить проблему русификации. Сама суть проблемы это создание кириллицы для этого есть специальные программы с помощью которых сможете создать массив матрицы любого символа затем загрузить его в CGRAM и после вывести на экран LCD, не забываем что за раз в CGRAM можно загрузить изображения только восьми символов. Длина памяти CGRAM 64 байтов для каждого символа матрица из восьми байт, матрицы символов должны загружаться с шагом через восемь байтов, например если нам нужно загрузить матрицу для символа с кодом 2 то должны к 64( команда установки нулевого адреса CGRAM) прибавить два раза по восемь получим команду 80, для символа с кодом 3 прибавляем ещё 8 получаем команду 88.
 Ниже пример загружаем в CGRAM три символа а потом их выводим.

#include "stm8s.h"
void pause( uint32_t p);
//Функция отсылки команды по четырехбитной линии.
void send_comand_4bit( uint8_t data);
//Функция отсылки команды по восьмибитной линии.
void send_comand_8bit( uint8_t data);
//Функция отсылки данных по четырехбитной линии.
void send_data_4bit( uint8_t data);
uint8_t iy[8]={ 0x0E, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11, 0x00};//Буква Й
uint8_t ee[8]={ 0x0E, 0x11, 0x01, 0x07, 0x01, 0x11, 0x0E, 0};//Буква Э
uint8_t ey[8]={ 0x0A, 0x00, 0x1F, 0x10, 0x1E, 0x10, 0x1F,0x00};//Буква Ё
int main( void )
{
CLK_HSIPrescalerConfig( CLK_PRESCALER_HSIDIV1);
//Настройка выводов для D4-D7.
GPIO_Init( GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
//Настройка выводов E, RS и R/W.
GPIO_Init( GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// E Enable Signal
GPIO_Init( GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// RS H--Data Input L--Instruction Input
GPIO_Init( GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// R/W H--Read L--Write
//Инициализация LCD три команды, одна перенастройка на 4 битную линию и 3 команды настройки.
pause( 10000);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 32);
send_comand_4bit( 40);
send_comand_4bit( 1);
send_comand_4bit( 14);
//Устанавливаем в CGRAM нулевой адрес для записи символа в нулевую позицию.
send_comand_4bit( 64);
//Загружаем символ Й.
for( uint8_t q=0; q<8; q++){ send_data_4bit( iy[q]);}
//Смещаем адрес на 8 и загружаем символ Э.
send_comand_4bit( 72);
for( uint8_t q=0; q<8; q++){ send_data_4bit( ee[q]);}
//Еще смещаем 8 и загружаем символ Ё.
send_comand_4bit( 80);
for( uint8_t q=0; q<8; q++){ send_data_4bit( ey[q]);}
while(1){
//Очищаем экран и возвращаем курсор в начальную позицию.
send_comand_4bit( 1);
//Стандартно выводим наши символы.
pause( 100000);
send_data_4bit( 0);
pause( 100000);
send_data_4bit( 1);
pause( 100000);
send_data_4bit( 2);
pause( 100000);
pause( 1000000);
}
return 0;
}
void send_comand_8bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_comand_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_data_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIO_Write( GPIOD, data);
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void pause( uint32_t p){
for( uint32_t i=0; i<p; i++){ }
}
#ifdef USE_FULL_ASSERT
void assert_failed( uint8_t* file, uint32_t line)
{
while (1){}
}
#endif

 В этом примере реализован простой счетчик который считает повторение циклов, из него вы можете взять основу русификации , вывода чисел и использования без изменения данных на ненужных выводах( D0-D3) PORTD при передачи данных.

#include "stm8s.h"
void pause( uint32_t p);
//Функция отсылки команды по четырехбитной линии.
void send_comand_4bit( uint8_t data);
//Функция отсылки команды по восьмибитной линии.
void send_comand_8bit( uint8_t data);
//Функция отсылки данных по четырехбитной линии.
void send_data_4bit( uint8_t data);
//Функция отображения чисел.
void displ_number( uint16_t number);
uint8_t iy[8]={ 0x0E, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11, 0x00};//Буква Й
uint8_t ee[8]={ 0x0E, 0x11, 0x01, 0x07, 0x01, 0x11, 0x0E, 0};//Буква Э
uint8_t ey[8]={ 0x0A, 0x00, 0x1F, 0x10, 0x1E, 0x10, 0x1F,0x00};//Буква Ё
uint8_t ch[8]={ 0x11, 0x11, 0x11, 0x11, 0x0F, 0x01, 0x01, 0x00};//Буква Ч
uint8_t i[8]={ 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00};//Буква И
int main( void )
{
CLK_HSIPrescalerConfig( CLK_PRESCALER_HSIDIV1);
//Настройка выводов для D4-D7.
GPIO_Init( GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
//Настройка выводов E, RS и R/W.
GPIO_Init( GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// E Enable Signal
GPIO_Init( GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// RS H--Data Input L--Instruction Input
GPIO_Init( GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// R/W H--Read L--Write
//Инициализация LCD три команды, одна перенастройка на 4 битную линию и 3 команды настройки.
pause( 10000);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 32);
send_comand_4bit( 40);
send_comand_4bit( 1);
send_comand_4bit( 14);
//Устанавливаем в CGRAM нулевой адрес для записи символа в нулевой позиции.
send_comand_4bit( 64);
//Загружаем символ Й в позицию 0.
for( uint8_t q=0; q<8; q++){ send_data_4bit( iy[q]);}
//Загружаем символ Э в позицию 1.
send_comand_4bit( 72);
for( uint8_t q=0; q<8; q++){ send_data_4bit( ee[q]);}
//Загружаем символ Ё в позицию 2.
send_comand_4bit( 80);
for( uint8_t q=0; q<8; q++){ send_data_4bit( ey[q]);}
//Загружаем символ Ч в позицию 3.
send_comand_4bit( 88);
for( uint8_t q=0; q<8; q++){ send_data_4bit( ch[q]);}
//Загружаем символ И в позицию 4.
send_comand_4bit( 96);
for( uint8_t q=0; q<8; q++){ send_data_4bit( i[q]);}
while(1){
//Очищаем экран и возвращаем курсор в начальную позицию.
send_comand_4bit( 1);
//Стандартно выводим наши символы.
send_data_4bit( 67);//C
send_data_4bit( 3);//Ч
send_data_4bit( 2);//Ё
send_data_4bit( 84);//T
send_data_4bit( 3);//Ч
send_data_4bit( 4);//И
send_data_4bit( 75);//K
send_data_4bit( 58);//:
//Цикл из которого будем выводить количество его повторений
for( uint16_t count=0; count<10000; count++){
send_comand_4bit( 136);
displ_number( count);
pause( 300000);
}
}
return 0;
}
void displ_number( uint16_t number){
send_data_4bit( number/10000+48);
number= number-(number/10000*10000);
send_data_4bit( number/1000+48);
number= number-(number/1000*1000);
send_data_4bit( number/100+48);
number= number-(number/100*100);
send_data_4bit( number/10+48);
number= number-(number/10*10);
send_data_4bit( number+48);
}
void send_comand_8bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
//Стираем данные в D4-D7 для записи новых.
GPIOD->ODR &= 15;
//Записываем новые данные только в D4-D7.
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_comand_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_data_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void pause( uint32_t p){
for( uint32_t i=0; i<p; i++){ }
}
#ifdef USE_FULL_ASSERT
void assert_failed( uint8_t* file, uint32_t line)
{
while (1){}
}
#endif


нет рисунка И осталась последняя тема чтение данных из LCD, чтение из LCD контроллером информации выполняется в два этапа отсылка команды и чтение с выводов LCD D0-D7 или как у меня в примере ниже по четырехбитной линии D4-D7 нужных данных.
 В примере мы выведем на экран LCD с начальной позиции цифры 0-1-2-3-4 потом прочтем содержание флага BF, содержимое AC и выведем на экран положение курсора, так же можете применить данный пример для чтения CGRAM/DDRAM DATA READ только выставите нужные сигналы на RS и R/W.

#include "stm8s.h"
void pause( uint32_t p);
void send_comand_4bit( uint8_t data);
void send_comand_8bit( uint8_t data);
void send_data_4bit( uint8_t data);
//Функция чтения данных по четырехбитной линии.
uint8_t read_data_4bit( void);
int main( void )
{
CLK_HSIPrescalerConfig( CLK_PRESCALER_HSIDIV1);
GPIO_Init( GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// E Enable Signal
GPIO_Init( GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// RS H--Data Input L--Instruction Input
GPIO_Init( GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// R/W H--Read L--Write
pause( 10000);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 48);
send_comand_8bit( 32);
send_comand_4bit( 40);
send_comand_4bit( 1);
send_comand_4bit( 14);
while(1){
//Очищаем экран и возвращаем курсор в начальную позицию.
send_comand_4bit( 1);
//Выводим цифры 0-1-2-3-4.
pause( 100000);
send_data_4bit( 48);//0
pause( 100000);
send_data_4bit( 49);//1
pause( 100000);
send_data_4bit( 50);//2
pause( 100000);
send_data_4bit( 51);//3
pause( 100000);
send_data_4bit( 52);//4
//Проверка раскомментируйте строку ниже.
//send_data_4bit( 53);
pause( 500000);
//Читаем данные из LCD.
uint8_t qwe=read_data_4bit();
//Выводим результат преобразуя в код нужной цифры.
send_data_4bit( qwe+48);
pause( 500000);
}
return 0;
}
uint8_t read_data_4bit( void){
uint8_t number_pos=0;
//Перенастройка выводов для D4-D7 как входы.
GPIO_Init( GPIOD, GPIO_PIN_4, GPIO_MODE_IN_PU_NO_IT);// DATA
GPIO_Init( GPIOD, GPIO_PIN_5, GPIO_MODE_IN_PU_NO_IT);// DATA
GPIO_Init( GPIOD, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT);// DATA
GPIO_Init( GPIOD, GPIO_PIN_7, GPIO_MODE_IN_PU_NO_IT);// DATA
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
GPIO_WriteHigh(GPIOC, GPIO_PIN_5);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
pause( 5);
//Читаем старшие 4 бита.
number_pos=GPIO_ReadInputData( GPIOD)&240;
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
pause( 5);
//Читаем младшие 4 бита.
number_pos|=GPIO_ReadInputData( GPIOD)>>4;
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
//Перенастройка выводов для D4-D7 как выходы.
GPIO_Init( GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
GPIO_Init( GPIOD, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);// DATA
return number_pos;
}
void send_comand_8bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_comand_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void send_data_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 2000);
}
void pause( uint32_t p){
for( uint32_t i=0; i<p; i++){ }
}
#ifdef USE_FULL_ASSERT
void assert_failed( uint8_t* file, uint32_t line)
{
while (1){}
}
#endif

 Использовать функцию чтения данных можно вместо пауз в конце каждой функций просто проверяя флаг BF, для этого пример на одной из функций.

void send_comand_4bit( uint8_t data){
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
pause( 5);
GPIO_WriteHigh(GPIOC, GPIO_PIN_7);
data=data<<4;
GPIOD->ODR &= 15;
GPIOD->ODR |= data&240;
pause( 5);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
//Проверка флага BF, зацикливание пока он не сбросится.
while( read_data_4bit()&128 );
}
Статья №30 Дата:28/10/2018

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