Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы
Непрочитано 09.06.2020, 15:38  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Сообщений: 4,418
Сказал спасибо: 395
Сказали Спасибо 2,205 раз(а) в 1,306 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: библиотека для LCD hd44780

А вообще - полезно хоть "по диагонали" проглядывать доки. Дисплей 1602 - это в 2020 году уже такая избитая тема, что...
Открываете докум на HD44780, смотрите таблицу символов, открываете ANSI-кодировку и просто сопоставляете каждый код символа из ANSI коду этого же символа из таблицы дисплея. Там простой табличный пересчет, поскольку в дисплее часть символов является общей для латиницы и кириллицы.

PS.
Warning 'lcd_rus' defined but not used [-Wunused-function] : lcd_rus определено, но не используется.
Учебник по языку Си - в помощь!! Глава "Функции".
Реклама:

Последний раз редактировалось NewWriter; 09.06.2020 в 16:39.
NewWriter вне форума  
Непрочитано 10.06.2020, 01:51  
gogaze
Частый гость
 
Регистрация: 26.04.2017
Сообщений: 17
Сказал спасибо: 4
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
gogaze на пути к лучшему
По умолчанию Re: библиотека для LCD hd44780

Сообщение от anatol378 Посмотреть сообщение
8-битные кодировки: ASCII, КОИ-8R и CP1251
Это знакомо, с этим разобрался.
gogaze вне форума  
Непрочитано 10.06.2020, 02:26  
gogaze
Частый гость
 
Регистрация: 26.04.2017
Сообщений: 17
Сказал спасибо: 4
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
gogaze на пути к лучшему
По умолчанию Re: библиотека для LCD hd44780

NewWriter,
Наверное Вы не совсем правильно меня поняли. В библиотеке, которую я прикрепил в архиве, встроена и отлично работает функция перекодировки ср1251 в таблицу знакогенератора русско-английского LCD1602.
В связи с затянувшимся режимом самоликвидации, решил попытать свои силы и выделить эту функцию в отдельный модуль, чтобы его можно было добавлять и использовать с другими библиотеками.
Ссылка на топик автора http://we.easyelectronics.ru/lcd_gfx...#comment122672
Вывод я для себя уже сделал - рано пока!

Последний раз редактировалось gogaze; 10.06.2020 в 03:20.
gogaze вне форума  
Непрочитано 10.06.2020, 07:17  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Сообщений: 4,418
Сказал спасибо: 395
Сказали Спасибо 2,205 раз(а) в 1,306 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: библиотека для LCD hd44780

Тогда нужно просто прочитать, как вызываются функции. Учебник Си (авторы Ритчи, Керниган) - в помощь. Или онлайн справочник http://www.c-cpp.ru/books
NewWriter вне форума  
Эти 2 пользователя(ей) сказали Спасибо NewWriter за это сообщение:
baiderin (29.06.2020), gogaze (11.06.2020)
Непрочитано 29.06.2020, 07:24  
Insector
Частый гость
 
Регистрация: 24.11.2006
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Insector на пути к лучшему
По умолчанию Re: библиотека для LCD hd44780

char_display.h
Нажмите, чтобы открыть спойлер

Код:
#ifndef CHAR_DISPLAY_H

#define CHAR_DISPLAY_H

#include "char_display.h"

#include "main_def_func.h"

//==================================================  ======================
#define LCD             0
#define VFD             1

// Тип дисплея. ЖКИ LCD или вакуумно-люминесцентный VFD.
#define TYPE_DISPLAY    VFD // LCD // 
//==================================================  ======================

//==================================================  ======================
// LCD Data Port
#define DATA_PORT       PORTC
#define DATA_PIN        PINC
#define DATA_DDR        DDRC

// LCD Control Port
#define CMD_PORT        PORTC
#define CMD_PIN         PINC
#define CMD_DDR         DDRC

// Строб.
#define EN_PORT         PORTC
#define EN_DDR          DDRC

#define EN              2

// Команда\данные.
#define RS_PORT         PORTC
#define RS_DDR          DDRC

#define RS              3
//==================================================  ======================

//==================================================  ======================
#define Line1           0x80 // Адрес первой строки.
#define Line2           0xC0 // Адрес второй строки.
#define Line3           0x94 // Адрес третьей строки.
#define Line4           0xD4 // Адрес четвертой строки.
//==================================================  ======================

//==================================================  ======================
#define DRV_LCD_TIME    1
//==================================================  ======================

//==================================================  ======================
#if (TYPE_DISPLAY==VFD)
extern u08 bright; // Значение яркости VFD.
// 3 - 25%
// 2 - 75%
// 1 - 50%
// 0 - 100%
#endif
//==================================================  ======================

//==================================================  ======================
#define QUANT_USERS_CHARS 4

#define ARROW_RIGHT 2
#define ARROW_LEFT 3
//==================================================  ======================

//==================================================  ======================
void lcd_io_in (void);
void lcd_send_nibble (u08 lcd_data);
void lcd_send_byte (u08 lcd_data);
void lcd_send_com_nibble (u08 lcd_data);
void lcd_send_com (u08 lcd_data);
void lcd_send_data (u08 lcd_data);
//==================================================  ======================

//==================================================  ======================
bool char_dsp_init (void);
//==================================================  ======================

//==================================================  ======================
void def_users_chars (u08 __flash *ptr);
//==================================================  ======================

//==================================================  ======================
#define POSITION_MAX_X    20   // Количество символов в строке.
#define POSITION_MAX_Y    4    // Количество строк дисплея.

extern char dsp_buf [];

#define LineBuf1          dsp_buf
#define LineBuf2          dsp_buf+POSITION_MAX_X
#define LineBuf3          dsp_buf+(POSITION_MAX_X*2)
#define LineBuf4          dsp_buf+(POSITION_MAX_X*3)
//==================================================  ======================

//==================================================  ======================
#ifdef __PROJECT_MODE_WORK__
#define DSP_INIT_TIME 40
#endif

#ifdef __PROJECT_MODE_DEBUG__
#define DSP_INIT_TIME 1
#endif
//==================================================  ======================

//==================================================  ======================
extern void clr_dsp_buf (void);

extern void init_dsp_buf (void);
//==================================================  ======================

//==================================================  ======================
#define Clr_String(y, x, n) _clr_string(((y)-1)*POSITION_MAX_X+((x)-1), (n))
void _clr_string (u08 x, u08 n);
//==================================================  ======================

//==================================================  ======================
extern u08 __flash string_azbuka [];

void test_out_text (void);
//==================================================  ======================

//==================================================  ======================
enum
{
   DRV_CHAR_DSP_INIT_1 = 0,
   DRV_CHAR_DSP_INIT_2,
   DRV_CHAR_DSP_SEND_ADDR,
   DRV_CHAR_DSP_SEND_CHAR,
};
//------------------------------------------------------------------------
void drv_char_dsp (void);

void drv_char_dsp_init_1 (void);
void drv_char_dsp_init_2 (void);
void drv_char_dsp_send_addr (void);
void drv_char_dsp_send_char (void);
//------------------------------------------------------------------------
u08 get_char_dsp_state (void);
//==================================================  ======================

#endif


char_display.c
Нажмите, чтобы открыть спойлер

Код:
//==================================================  ======================
#include "char_display.h"
//==================================================  ======================

//==================================================  ======================
// Алгоритм работы модуля дисплея:
// Есть буфер дисплея. Размер буфера равен кол-во символов*кол-во строк.
// Обновление дисплея осуществляется посимвольно, раз в 1 мс. Полное
// обновление дисплея происходит за
// кол-во символов*кол-во строк + кол-во строк (адреса строк).
// Если дисплей 20х4, то полное обновление происходит за 20*4+4=84 мс.
//==================================================  ======================

//==================================================  ======================
static u08 _drv_char_dsp;

static u08 position_x;
static u08 position_y;

u08 __flash lines [4] = {0x80, 0xC0, 0x94, 0xD4};

   static soft_timer ST_DRV_CHAR_DSP;
//==================================================  ======================

//==================================================  ======================
#if (TYPE_DISPLAY == LCD)

u08 __flash table_rus_chars [64] =
{
  0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4,
  0xa5,0xa6,0x4b,0xa7,0x4d,0x48,0x4f,0xa8,
  0x50,0x43,0x54,0xa9,0xaa,0x58,0xe1,0xab,
  0xac,0xe2,0xad,0xae,0x62,0xaf,0xb0,0xb1,
  0x61,0xb2,0xb3,0xb4,0xe3,0x65,0xb6,0xb7,
  0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0x6f,0xbe,
  0x70,0x63,0xbf,0x79,0xe4,0x78,0xe5,0xc0,
  0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
};

u08 __flash string_azbuka [] = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОП  РСТУФХЦЧШЩЪЫЬЭЮЯ";

//------------------------------------------------------------------------

#elif (TYPE_DISPLAY == VFD)

u08 __flash table_users_chars [8 * QUANT_USERS_CHARS]  = // Таблица пользовательских символов.
{
0x00, 0x04, 0x0E, 0x15, 0x15, 0x0E, 0x04, 0x04, // Ф
0x00, 0x10, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x1E, // Ь
0x00, 0x08, 0x0C, 0x1E, 0x1F, 0x1E, 0x0C, 0x08,
0x00, 0x02, 0x06, 0x0F, 0x1F, 0x0F, 0x06, 0x02,
};
//------------------------------------------------------------------------

//------------------------------------------------------------------------
u08 __flash table_rus_chars [32] = // Таблица кириллицы. VFD поддерживает только
// заглавные русские буквы. И не все. Ф и Ь в таблице пользовательских символов.
{
//АБВГДЕЖЗ
0x41, 0x80, 0x42, 0x92, 0x81, 0x45, 0x82, 0x83,
//ИЙКЛМНОП
0x84, 0x85, 0x4B, 0x86, 0x4D, 0x48, 0x4F, 0x87,
//РСТУФХЦЧ
0x50, 0x43, 0x54, 0x88, 0x00, 0x58, 0x89, 0x8A,
//ШЩЪЫЬЭЮЯ
0x8B, 0x8C, 0x8D, 0x8E, 0x01, 0x8F, 0xAC, 0xAD,
};

#endif
//==================================================  ======================

//==================================================  ======================
void lcd_io_in (void)
{
   DATA_DDR = DATA_DDR & 0x0F;
   DATA_PORT = DATA_PORT & 0x0F;
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_nibble (u08 lcd_data)
{
   set_bit (CMD_PORT, EN);
   DATA_PORT = (DATA_PORT & 0x0F) | (lcd_data & 0xF0);
   asm("rjmp ($/2+1)*2"); // Такой своеобразный ассемблер в IAR/
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   clr_bit (CMD_PORT, EN);
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_byte (u08 lcd_data)
{
   DATA_DDR = (DATA_DDR | 0xF0);
   lcd_send_nibble (lcd_data);
   lcd_send_nibble (lcd_data ‹‹ 4);
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_com_nibble (u08 lcd_data)
{
   clr_bit (CMD_PORT, RS);
   DATA_DDR = (DATA_DDR | 0xF0);
   lcd_send_nibble (lcd_data);
   lcd_io_in ();
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_com (u08 lcd_data)

{
   clr_bit (CMD_PORT, RS);
   lcd_send_byte (lcd_data);
   lcd_io_in ();
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_data (u08 lcd_data)
{
   set_bit (CMD_PORT,RS);

#if (TYPE_DISPLAY == LCD)
      if (lcd_data == 0xA8)
      {
         lcd_data = 0xA2; //буква 'Ё' 
      }
      else if (lcd_data ==0xB8)
      {
         lcd_data = 0xB5; //буква 'ё'
      }
#endif

   if (lcd_data ›= 0xC0)
   {
      lcd_data = table_rus_chars [lcd_data - 0xC0];
   }

   lcd_send_byte (lcd_data);
   lcd_io_in ();
}
//==================================================  ======================

//==================================================  ======================
 // Инициализация дисплея.

bool char_dsp_init (void)
{
   static u08 _char_dsp_init;

#if (TYPE_DISPLAY == LCD)
   static u08 cnt;
#endif

   switch (_char_dsp_init)
   {
      case 0:
         set_soft_timer (ST_DRV_CHAR_DSP, DSP_INIT_TIME, 0); // Задержка. Повтора нет.
         _char_dsp_init = 1;
         return false;

      case 1:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
            set_bit (EN_DDR, EN);
            set_bit (RS_DDR, RS);

#if (TYPE_DISPLAY == LCD)
            cnt = 0;

            set_soft_timer (ST_DRV_CHAR_DSP, 0, 5); // Немедленное исполнение, последующая задержка 5 мс.
            _char_dsp_init = 2;

#elif (TYPE_DISPLAY == VFD)

            // Так как VFD работает быстро, задержки не нужны.
            for (u08 i = 3; i › 0; i--)
            {
               lcd_send_com_nibble (0x30); // Установка 8-разрядного интерфейса.
            }

            lcd_send_com_nibble (0x20); // Установка 4-разрядного интерфейса.
            lcd_send_com (0x28 | 3); // 4-разрядный интерфейс. Двухстрочный режим. Яркость 25 %

            //   lcd_send_com(0x01); // Команда очистки дисплея.
            //   wait_5_ms ();

            lcd_send_com (0x06); // Инкремент счетчика адреса.
            lcd_send_com (0x0C); // Включение дисплея.

            def_users_chars (table_users_chars);

            return true;
#endif
         }
         return false;

#if (TYPE_DISPLAY == LCD)
      case 2:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
            if (cnt ‹ 3)
            {
               lcd_send_com_nibble (0x30); // Установка 8-разрядного интерфейса.
               cnt++;
               return false;
            }

            if (cnt == 3)
            {
               lcd_send_com_nibble (0x20); // Установка 4-разрядного интерфейса.
               delay_us (50);

               lcd_send_com (0x28); // 4-разрядный интерфейс. Двухстрочный режим.
               delay_us (50);

               lcd_send_com(0x01); // Команда очистки дисплея.
               cnt++;
               return false;
            }

            if (cnt == 4)
            {
               lcd_send_com (0x06); // Инкремент счетчика адреса.
               delay_us (50);

               lcd_send_com (0x0C); // Включение дисплея.
               delay_us (50);
               return true;
            }
         }
         return false;
#endif
   }

   return false;
}
//==================================================  ======================

//==================================================  ======================
void def_users_chars (u08 __flash *ptr)
{
   lcd_send_com (1‹‹6);

   u08 a;
   u08 b;

   for (a = QUANT_USERS_CHARS; a › 0; a--)
   {
      for (b = 8; b › 0; b--)
      {
         lcd_send_data (*ptr);
         ptr++;

#if (TYPE_DISPLAY == LCD)
         delay_us (50);
#endif

      }
   }
}
//==================================================  ======================

//==================================================  ======================
// Очистка буфера дисплея.

char dsp_buf [POSITION_MAX_X * POSITION_MAX_Y];

void clr_dsp_buf (void)
{
   u08 i;

   for (i = 0; i ‹ POSITION_MAX_X * POSITION_MAX_Y; i++)
      dsp_buf [i] = 0x20;

   init_dsp_buf (); // Переинициализация модуля дисплея.
}
//==================================================  ======================

//==================================================  ======================
// Переинициализация модуля дисплея.
// Так как модуль ЖКИ работает с обновлением, то при выводе новой информации
// переинициализация модуля дисплея, чтобы обновление началось заново.

void init_dsp_buf (void)
{
   _drv_char_dsp = DRV_CHAR_DSP_INIT_2;
}
//==================================================  ======================

//==================================================  ======================
// Очистка определенного участка буфера дисплея. Формат:
// Номер строки, номер знакоместа, кол-во очищаемых знакомест.

void _clr_string (u08 x, u08 n)
{
   while (n--) dsp_buf [x++] = ' ';

//   init_dsp_buf (); // Переинициализация модуля дисплея.
}
//==================================================  ======================

//==================================================  ======================
//void test_out_text (void)
//{
/*
// Тестовый вывод текста в буфер.
// Вариант 1 вывода текста.
u08 i = 0;
u08 j = 0;

while (string_azbuka [j])
{
   dsp_buf [i++] = string_azbuka [j++];
}

clr_dsp_buf ();
*/
//------------------------------------------------------------------------
// Вариант 2 вывода текста.
// Примечание: в параметрах функции Print_Buf количество символов не должно
// превышать кол-ва символов на строку. Но в данном случае точно известно,
// что позиция первого символа начинается с нулевого адреса буфера дисплея
// и кол-во символов не превышает 20*4.

//Print_Buf (1, 1, "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОП  РСТУФХЦЧШЩЪЫЬЭЮЯ");

//      Print_Buf (1, 1, "абвгдеёжзийклмнопрст");
//      Print_Buf (1, 2, "уфхцчшщъыьэюяАБВГДЕЁ");
//      Print_Buf (1, 3, "ЖЗИЙКЛМНОПРСТУФХЦЧШЩ");
//      Print_Buf (1, 4, "ЪЫЬЭЮЯ");
//}
//==================================================  ======================

//==================================================  ======================
void drv_char_dsp (void)
{
   u08 data;

   switch (_drv_char_dsp)
   {
      case DRV_CHAR_DSP_INIT_1:
         if (char_dsp_init ())
         {
            clr_dsp_buf ();
            Set_Event (EV_ID_CHAR_DSP_RUN, USER_EVENT);

            _drv_char_dsp = DRV_CHAR_DSP_INIT_2;
         }
         break;

      case DRV_CHAR_DSP_INIT_2:
         position_x = 0;
         position_y = 0;

         set_soft_timer (ST_DRV_CHAR_DSP, 0, 1); // Немедленное исполнение. Повтор.

         _drv_char_dsp = DRV_CHAR_DSP_SEND_ADDR;
         break;

      case DRV_CHAR_DSP_SEND_ADDR:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
            lcd_send_com (lines [position_y]);
            _drv_char_dsp = DRV_CHAR_DSP_SEND_CHAR;
         }
         break;

      case DRV_CHAR_DSP_SEND_CHAR:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
         #if (TYPE_DISPLAY == LCD)
            data = dsp_buf [(position_y * POSITION_MAX_X) + position_x];

            if (data ›= 0xC0)
            {
               data = table_rus_chars [data - 0xC0];
            }

            lcd_send_data (data);
            position_x++;

            if (position_x ›= POSITION_MAX_X)
            {
               position_x = 0;

               position_y++;
               if (position_y ›= POSITION_MAX_Y)
               {
                  position_y = 0;
               }

               _drv_char_dsp = DRV_CHAR_DSP_SEND_ADDR;
            }

         #elif (TYPE_DISPLAY == VFD)
            while (position_x ‹ POSITION_MAX_X)
            {
               data = dsp_buf [(position_y * POSITION_MAX_X) + position_x];

               if (data ›= 0xC0)
               {
                  data = table_rus_chars [data - 0xC0];
               }

               lcd_send_data (data);
               position_x++;
            }

            position_x = 0;

            position_y++;
            if (position_y ›= POSITION_MAX_Y)
            {
               position_y = 0;

               char_dsp_init (); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            }

            _drv_char_dsp = DRV_CHAR_DSP_SEND_ADDR;

         #endif
         }
         break;
   }
}
//==================================================  ======================

//==================================================  ======================
u08 get_char_dsp_state (void)
{
   return _drv_char_dsp;
}
//==================================================  ======================
Insector вне форума  
Сказали "Спасибо" Insector
DmitryM67 (03.07.2020)
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ускорить компьютер 7Fantomas7 Ремонт оргтехники 111 08.08.2018 05:27
PIC16F876a+Nokia 5110 LCD+PICKit2 AndGrig PIC 31 02.11.2016 09:18
Библиотека для LCD 16x2(HD44780) для STM32F4xx Vittok007 ARM 4 07.06.2015 19:23
Компас 3D V10+ algenkel Proteus, KiCAD и другие ECAD 14 29.09.2009 13:09
LCD на контроллере HD44780 yga Микроконтроллеры, АЦП, память и т.д 8 03.12.2007 16:50


Часовой пояс GMT +4, время: 13:51.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot