1

Тема: LCD1602_4BIT

// Подключаем пины Arduino к пинам LCD1602
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
int int_out;
unsigned long times;

void setup() {
  Serial.begin(9600);
  // Устанавливаем пины в режим вывода
  pinMode(rs, OUTPUT);
  pinMode(en, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(d5, OUTPUT);
  pinMode(d6, OUTPUT);
  pinMode(d7, OUTPUT);

  // Инициализируем экран
  lcd_init();
}

void loop() {
  times=millis();
  for(int i1=0;i1<10000;i1++){
  lcd_command(0x80);
  lcd_print("LCD1602");
  lcd_command(0xC0);
  lcd_print(String(int_out++));
  }
   lcd_command(0x01);
   int_out=0;
   Serial.print("4-bit ");Serial.println(millis()-times);
   delay(1000);
}

void lcd_init() {
  // Инициализация экрана
  delay(100);
  lcd_command(0x03);delayMicroseconds(4500);
  lcd_command(0x03);delayMicroseconds(4500);
  lcd_command(0x03);delayMicroseconds(200);
  lcd_command(0x02);
  lcd_command(0x28);
  lcd_command(0x0C);
  lcd_command(0x01);
}

void lcd_command(byte cmd) {
  // Отправляем команду на экран
  digitalWrite(rs, LOW);delayMicroseconds(100);
  lcd_write(cmd);
}

void lcd_print(String str) {
  // Выводим строку на экран
  digitalWrite(rs, HIGH);
  for (int i = 0; i < str.length(); i++) {
    lcd_write(str[i]);
  }
}

void lcd_write(byte data) {
  // Отправляем данные на экран
  digitalWrite(d4, (data >> 4) & 0x01);
  digitalWrite(d5, (data >> 5) & 0x01);
  digitalWrite(d6, (data >> 6) & 0x01);
  digitalWrite(d7, (data >> 7) & 0x01);

  digitalWrite(en, HIGH);
  delayMicroseconds(1);
  digitalWrite(en, LOW);
  delayMicroseconds(50);
  
  digitalWrite(d4, (data >> 0) & 0x01);
  digitalWrite(d5, (data >> 1) & 0x01);
  digitalWrite(d6, (data >> 2) & 0x01);
  digitalWrite(d7, (data >> 3) & 0x01);

  digitalWrite(en, HIGH);
  delayMicroseconds(1);
  digitalWrite(en, LOW);
  delayMicroseconds(50);
}

2

Re: LCD1602_4BIT

LCD1602_8BIT

// Подключаем пины Arduino к пинам LCD1602
const int rs = 12, en = 11, d0 = 2, d1 = 3, d2 = 4, d3 = 5, d4 = 6, d5 = 7, d6 = 8, d7 = 9;
int int_out;
unsigned long times;

void setup() {
    Serial.begin(9600);
  // Устанавливаем пины в режим вывода
  pinMode(rs, OUTPUT);
  pinMode(en, OUTPUT);
  pinMode(d0, OUTPUT);
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(d5, OUTPUT);
  pinMode(d6, OUTPUT);
  pinMode(d7, OUTPUT);

  // Инициализируем экран
  lcd_init();
}

void loop() {
  times=millis();
  for(int i1=0;i1<10000;i1++){
  lcd_command(0x80);
  lcd_print("LCD1602");
  lcd_command(0xC0);
  lcd_print(String(int_out++));
  }
   lcd_command(0x01);
   int_out=0;
   Serial.print("8-bit ");Serial.println(millis()-times);
   delay(1000);
}

void lcd_init() {
  // Инициализация экрана
  delay(100);
  lcd_command(0x03);delayMicroseconds(4500);
  lcd_command(0x03);delayMicroseconds(4500);
  lcd_command(0x03);delayMicroseconds(200);
  lcd_command(0x02);
  lcd_command(0x38);
  lcd_command(0x0C);
  lcd_command(0x01);
}

void lcd_command(byte cmd) {
  // Отправляем команду на экран
  digitalWrite(rs, LOW);delayMicroseconds(100);
  lcd_write(cmd);
}

void lcd_print(String str) {
  // Выводим строку на экран
  digitalWrite(rs, HIGH);
  for (int i = 0; i < str.length(); i++) {
    lcd_write(str[i]);
  }
}

void lcd_write(byte data) {
  // Отправляем данные на экран
  digitalWrite(d7, (data >> 7) & 0x01);
  digitalWrite(d6, (data >> 6) & 0x01);
  digitalWrite(d5, (data >> 5) & 0x01);
  digitalWrite(d4, (data >> 4) & 0x01);
  digitalWrite(d3, (data >> 3) & 0x01);
  digitalWrite(d2, (data >> 2) & 0x01);
  digitalWrite(d1, (data >> 1) & 0x01);
  digitalWrite(d0, (data >> 0) & 0x01);

  digitalWrite(en, HIGH);
  delayMicroseconds(1);
  digitalWrite(en, LOW);
  delayMicroseconds(50);
}

3

Re: LCD1602_4BIT

http://forum.rcl-radio.ru/uploads/images/2023/04/51032f0325bbe61476a1af1bc32dc52e.gif

4

Re: LCD1602_4BIT

http://forum.rcl-radio.ru/uploads/images/2023/04/2fb6df590a962da72d0fa94ff7765085.gif

5

Re: LCD1602_4BIT

Когда не хватает ног для подключения экрана
http://forum.rcl-radio.ru/uploads/images/2024/09/4db0728b1b512024e6d81875cb1bb980.jpg

#define REG_PORT PORTB // PORT
#define REG_DDR DDRB // DDR
#define ST_CP PB1 // пин для st_sp - 12 нога регистра
#define SH_CP PB2 // пин для sh_cp - 11 нога регистра
#define DS PB0 // пин для ds - 14 нога регистра
// Команды для управления портами LCD
/* RS */
#define RS1 registr(0x01, 1)
#define RS0 registr(0x01, 0)

/* E */
#define E1 registr(0x02, 1)
#define E0 registr(0x02, 0)

/* D4 */
#define D41 registr(0x04, 1)
#define D40 registr(0x04, 0)

/* D5 */
#define D51 registr(0x08, 1)
#define D50 registr(0x08, 0)

/* D6 */
#define D61 registr(0x10, 1)
#define D60 registr(0x10, 0)

/* D7 */
#define D71 registr(0x20, 1)
#define D70 registr(0x20, 0)


// Функция установки курсора в указанную точку
#define lcd_gotoxy(x, y) write_to_lcd(0x80|((x)+((y)*0x40)), 0)

volatile static unsigned char tempdata = 0; // буферная переменная.

void setup() {
lcd_init(); // Инициализация дисплея  
lcd_gotoxy(0, 0); // курсор на 5 позиции 0 строки
    lcd_puts((char*)"  HELLO"); // вывод текста.
    lcd_gotoxy(5, 0); // курсор на 5 позиции 0 строки
    lcd_gotoxy(0, 1);
    lcd_puts((char*)" WORLD");
    delay(10000);
    write_to_lcd(0x01, 0); // Очищаем дисплей
   
}

void loop() {
  // put your main code here, to run repeatedly:

}
// Функция передачи данных в регистр
void registr(unsigned char data, unsigned char WriteOrErase)
{
  if(WriteOrErase == 1)
  tempdata = (tempdata|data);
  else
  tempdata &= ~(data);
  REG_PORT &= ~(1 << ST_CP); // ST_CP 0

  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x80)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x40)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x20)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x10)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x08)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x04)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x02)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x01)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT |= (1 << ST_CP); // ST_CP 1
}

// Функция передачи данных или команды в LCD
void write_to_lcd(char p, unsigned char rs)
{
  if(rs == 1) RS1;
  else RS0;
  
  E1;

  if(p&0x10) D41; else D40;
  if(p&0x20) D51; else D50;
  if(p&0x40) D61; else D60;
  if(p&0x80) D71; else D70;
  E0;
  delay(2);
  
  E1;
  
  if(p&0x01) D41; else D40;
  if(p&0x02) D51; else D50;
  if(p&0x04) D61; else D60;
  if(p&0x08) D71; else D70;
  E0;

  delay(2);
}

// Функция инициализации LCD
void lcd_init(void)
{
  REG_DDR|=(1<<DS) | (1<<ST_CP) | (1<<SH_CP);
  write_to_lcd(0x02, 0); // Курсор в верхней левой позиции
  write_to_lcd(0x28, 0); // Шина 4 бит, LCD - 2 строки
  write_to_lcd(0x0C, 0); // Разрешаем вывод изображения, курсор не виден
  write_to_lcd(0x01, 0); // Очищаем дисплей
}

// Функция вывода строки
void lcd_puts(char *str)
{
  unsigned char i = 0;

  while(str[i])
  write_to_lcd(str[i++], 1);
}

// Функция вывода переменной
void lcd_num_to_str(unsigned int value, unsigned char nDigit)
{
  switch(nDigit)
  {
    case 4: write_to_lcd((value/1000)+'0', 1);
    case 3: write_to_lcd(((value/100)%10)+'0', 1);
    case 2: write_to_lcd(((value/10)%10)+'0', 1);
    case 1: write_to_lcd((value%10)+'0', 1);
  }
}

фото для lcd1601
http://forum.rcl-radio.ru/uploads/images/2024/09/d5feea52d042cdbba46dc20afd41f925.jpg

6

Re: LCD1602_4BIT

В качестве примера attiny45_bmp180.

#include <TinyWireM.h>
#include <tinyBMP085.h>
tinyBMP085 bmp;
//SDA pin 5 PB0
//SCL pin 7 PB2 
#define REG_PORT PORTB // PORT
#define REG_DDR DDRB // DDR
#define ST_CP PB1 // пин для st_sp - 12 нога регистра
#define SH_CP PB4 // пин для sh_cp - 11 нога регистра
#define DS PB3 // пин для ds - 14 нога регистра
// Команды для управления портами LCD
/* RS */
#define RS1 registr(0x01, 1)
#define RS0 registr(0x01, 0)

/* E */
#define E1 registr(0x02, 1)
#define E0 registr(0x02, 0)

/* D4 */
#define D41 registr(0x04, 1)
#define D40 registr(0x04, 0)

/* D5 */
#define D51 registr(0x08, 1)
#define D50 registr(0x08, 0)

/* D6 */
#define D61 registr(0x10, 1)
#define D60 registr(0x10, 0)

/* D7 */
#define D71 registr(0x20, 1)
#define D70 registr(0x20, 0)


// Функция установки курсора в указанную точку
#define lcd_gotoxy(x, y) write_to_lcd(0x80|((x)+((y)*0x40)), 0)

volatile static unsigned char tempdata = 0; // буферная переменная.

void setup() {
bmp.begin();  
lcd_init(); // Инициализация дисплея  
lcd_gotoxy(0, 0); // курсор на 5 позиции 0 строки
    lcd_puts((char*)"  HELLO"); // вывод текста.
    lcd_gotoxy(5, 0); // курсор на 5 позиции 0 строки
    lcd_gotoxy(0, 1);
    lcd_puts((char*)" WORLD");
    delay(1000);
    write_to_lcd(0x01, 0); // Очищаем дисплей
   
}

void loop() {
   int pres = bmp.readPressure()/100; //kилопаскалях
   int p = (pres/0.133322);// мм ртутного столба
   int temp = bmp.readTemperature10C();
    lcd_gotoxy(0, 0); // курсор на 5 позиции 0 строки
    lcd_puts((char*)"P="); // вывод текста.
    write_to_lcd((p/1000)+'0', 1);
    write_to_lcd(((p/100)%10)+'0', 1);
    write_to_lcd(((p/10)%10)+'0', 1);
   
    lcd_puts((char*)"mm ");
    lcd_gotoxy(0, 1);
    lcd_puts((char*)"T=");
    write_to_lcd(((temp/100)%10)+'0', 1);
    write_to_lcd(((temp/10)%10)+'0', 1);
    lcd_puts((char*)".");
    write_to_lcd((temp%10)+'0', 1);
    lcd_puts((char*)"C");
    delay(1000);
}
// Функция передачи данных в регистр
void registr(unsigned char data, unsigned char WriteOrErase)
{
  if(WriteOrErase == 1)
  tempdata = (tempdata|data);
  else
  tempdata &= ~(data);
  REG_PORT &= ~(1 << ST_CP); // ST_CP 0

  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x80)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x40)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x20)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x10)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x08)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x04)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x02)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT &= ~(1 << SH_CP); // SH_CP 0
  if(tempdata & 0x01)REG_PORT |= (1 << DS);
  else REG_PORT &= ~(1 << DS);
  REG_PORT |= (1 << SH_CP); // SH_CP 1
  REG_PORT |= (1 << ST_CP); // ST_CP 1
}

// Функция передачи данных или команды в LCD
void write_to_lcd(char p, unsigned char rs)
{
  if(rs == 1) RS1;
  else RS0;
  
  E1;

  if(p&0x10) D41; else D40;
  if(p&0x20) D51; else D50;
  if(p&0x40) D61; else D60;
  if(p&0x80) D71; else D70;
  E0;
  delay(2);
  
  E1;
  
  if(p&0x01) D41; else D40;
  if(p&0x02) D51; else D50;
  if(p&0x04) D61; else D60;
  if(p&0x08) D71; else D70;
  E0;

  delay(2);
}

// Функция инициализации LCD
void lcd_init(void)
{
  REG_DDR|=(1<<DS) | (1<<ST_CP) | (1<<SH_CP);
  write_to_lcd(0x02, 0); // Курсор в верхней левой позиции
  write_to_lcd(0x28, 0); // Шина 4 бит, LCD - 2 строки
  write_to_lcd(0x0C, 0); // Разрешаем вывод изображения, курсор не виден
  write_to_lcd(0x01, 0); // Очищаем дисплей
}

// Функция вывода строки
void lcd_puts(char *str)
{
  unsigned char i = 0;

  while(str[i])
  write_to_lcd(str[i++], 1);
}

// Функция вывода переменной
void lcd_num_to_str(unsigned int value, unsigned char nDigit)
{
  switch(nDigit)
  {
    case 4: write_to_lcd((value/1000)+'0', 1);
    case 3: write_to_lcd(((value/100)%10)+'0', 1);
    case 2: write_to_lcd(((value/10)%10)+'0', 1);
    case 1: write_to_lcd((value%10)+'0', 1);
  }
}

http://forum.rcl-radio.ru/uploads/images/2024/09/72b6361d903d4b8cd1396ed7010dc533.jpg