esp开发与应用(1602液晶显示屏)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

模块当中,有的是比较简单的,比如说蜂鸣器,尤其是有源蜂鸣器。大家可以把它想象成是一个gpio输出的喇叭,通电就有声音,没通电就没有声音。整个模块也就三个pin,一个是电源,一个是地,还有一个就是gpio控制开关。所以蜂鸣器不复杂。但相比较而言,还有一些模块,会稍微复杂一点,比如说1602液晶屏幕。过去的1602屏幕占用的pin比较多,但是后来出了一个PCF8574芯片,这就方便多了。相当于这是一个i2c接口的芯片,我们只要对PCF8574进行控制,就可以让PCF8574控制屏幕,最终让1602屏幕显示文字和符号了。

1、找到esp32的i2c口

在esp32上面,默认第一个i2c口就是gpio22和gpio21,前者是scl,后者是sda。

2、找到电源部分

这里需要注意的部分,就是输入电压。一般esp32上面有两个电压,一个是5v,一个是3.3v。5v就是直接usb传进来的电压,3.3v也是5v转的电压。但对于1602模块呢,它需要5v的电压,所以这部分还是要找到5v的电压入口。

3、连接好esp32模块和1602模块

连接的时候采用的是母对母的杜邦线,这部分不复杂,但是要细心一点。

4、编写代码

编写代码这部分,如之前所说,还是用ai来写比较好。我们需要告诉ai的是,当前使用的i2c是第一个,gpio用的是22和21,1602的驱动芯片就是PCF8574,然后希望它编写一个简单的输出小程序。这样不出意外的话,ai就可以帮助我们生成代码。有条件的,可以vs code上直接购买ai插件生成代码。如果不行,用deepseek生成后,拷贝粘贴过来,也是可以的。

复制代码
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c.h"

// I2C configuration
#define I2C_MASTER_SCL_IO    22          // SCL pin
#define I2C_MASTER_SDA_IO    21          // SDA pin
#define I2C_MASTER_NUM       I2C_NUM_0   // I2C port number
#define I2C_MASTER_FREQ_HZ   100000      // I2C frequency

// PCF8574 I2C address (common: 0x27 or 0x3F)
#define PCF8574_ADDR         0x27

// PCF8574 pin definitions (connected to 1602 LCD)
#define LCD_RS               0x01        // P0
#define LCD_RW               0x02        // P1
#define LCD_EN               0x04        // P2
#define LCD_BACKLIGHT        0x08        // P3
#define LCD_D4               0x10        // P4
#define LCD_D5               0x20        // P5
#define LCD_D6               0x40        // P6
#define LCD_D7               0x80        // P7

// LCD commands
#define LCD_CLEAR            0x01
#define LCD_HOME             0x02
#define LCD_ENTRY_MODE       0x04
#define LCD_DISPLAY_CTRL     0x08
#define LCD_CURSOR_SHIFT     0x10
#define LCD_FUNCTION_SET     0x20
#define LCD_CGRAM_ADDR       0x40
#define LCD_DDRAM_ADDR       0x80

// I2C write byte to PCF8574
static esp_err_t i2c_write_byte(uint8_t data)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (PCF8574_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, data, true);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

// Send LCD command
void lcd_send_cmd(uint8_t cmd)
{
    uint8_t high_nibble = (cmd & 0xF0) | LCD_BACKLIGHT;  // High nibble + backlight
    uint8_t low_nibble = ((cmd << 4) & 0xF0) | LCD_BACKLIGHT;  // Low nibble + backlight
    
    // Send high nibble
    i2c_write_byte(high_nibble);
    i2c_write_byte(high_nibble | LCD_EN);  // EN=1
    vTaskDelay(1 / portTICK_PERIOD_MS);
    i2c_write_byte(high_nibble & ~LCD_EN);  // EN=0
    
    // Send low nibble
    i2c_write_byte(low_nibble);
    i2c_write_byte(low_nibble | LCD_EN);  // EN=1
    vTaskDelay(1 / portTICK_PERIOD_MS);
    i2c_write_byte(low_nibble & ~LCD_EN);  // EN=0
}

// Send LCD data
void lcd_send_data(uint8_t data)
{
    uint8_t high_nibble = (data & 0xF0) | LCD_RS | LCD_BACKLIGHT;  // RS=1
    uint8_t low_nibble = ((data << 4) & 0xF0) | LCD_RS | LCD_BACKLIGHT;
    
    // Send high nibble
    i2c_write_byte(high_nibble);
    i2c_write_byte(high_nibble | LCD_EN);
    vTaskDelay(1 / portTICK_PERIOD_MS);
    i2c_write_byte(high_nibble & ~LCD_EN);
    
    // Send low nibble
    i2c_write_byte(low_nibble);
    i2c_write_byte(low_nibble | LCD_EN);
    vTaskDelay(1 / portTICK_PERIOD_MS);
    i2c_write_byte(low_nibble & ~LCD_EN);
}

// Initialize LCD
void lcd_init(void)
{
    vTaskDelay(50 / portTICK_PERIOD_MS);
    
    // 4-bit mode initialization sequence
    lcd_send_cmd(0x33);
    vTaskDelay(5 / portTICK_PERIOD_MS);
    lcd_send_cmd(0x32);
    vTaskDelay(5 / portTICK_PERIOD_MS);
    
    // Function set: 4-bit, 2-line, 5x8
    lcd_send_cmd(LCD_FUNCTION_SET | 0x08 | 0x00);
    vTaskDelay(5 / portTICK_PERIOD_MS);
    
    // Display control: display on, cursor off
    lcd_send_cmd(LCD_DISPLAY_CTRL | 0x04);
    vTaskDelay(5 / portTICK_PERIOD_MS);
    
    // Clear display
    lcd_send_cmd(LCD_CLEAR);
    vTaskDelay(20 / portTICK_PERIOD_MS);
    
    // Entry mode: cursor move right
    lcd_send_cmd(LCD_ENTRY_MODE | 0x02);
    vTaskDelay(5 / portTICK_PERIOD_MS);
}

// Set cursor position
void lcd_set_cursor(uint8_t row, uint8_t col)
{
    uint8_t addr = (row == 0) ? 0x00 : 0x40;
    lcd_send_cmd(LCD_DDRAM_ADDR | (addr + col));
}

// Print string to LCD
void lcd_print(const char *str)
{
    while (*str)
    {
        lcd_send_data(*str++);
    }
}

// Initialize I2C
void i2c_init(void)
{
    i2c_config_t conf =
    {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
    };
    i2c_param_config(I2C_MASTER_NUM, &conf);
    i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);
}

void app_main(void)
{
    printf("1602 LCD I2C Driver (PCF8574)\n");
    printf("SCL: GPIO%d, SDA: GPIO%d\n", I2C_MASTER_SCL_IO, I2C_MASTER_SDA_IO);
    printf("PCF8574 Address: 0x%02X\n", PCF8574_ADDR);
    
    // Initialize I2C
    i2c_init();
    
    // Initialize LCD
    lcd_init();
    
    // Display Hello, World!
    lcd_set_cursor(0, 0);
    lcd_print("Hello,");
    lcd_set_cursor(1, 0);
    lcd_print("Fei ning ning!");
    
    printf("LCD display complete!\n");
    
    while (1)
    {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

5、编译查看代码

代码输出后,首先编译一下。不能编译的代码价值不大。其次就是简单看一下流程,有没有i2c初始化、PCF8574初始化、发命令、发数据、显示数据这些动作。如果没有问题的话,就可以烧入显示了。不出意外,就可以看到屏幕的显示了。

6、调整电位器

实际显示的时候,字体的显示效果不一定好,即字体和背景的对比度可能不是很好。好在模块上面有一个明显的电位器。说是电位器,其实就是一个可调电阻,找一个十字起,微调一下即可。

相关推荐
嵌入式小站10 小时前
STM32 临界区是什么:为什么有时候要用 __disable_irq() 保护变量
chrome·stm32·嵌入式硬件
leo_jk10 小时前
STM32单片机 空闲中断
stm32·单片机·嵌入式硬件
weyyhdke10 小时前
2026电源与MCU控制设计实战:用Gemini3.5镜像站免费优化开关电源环路与电机FOC算法硬核教程
单片机·嵌入式硬件·算法
星夜夏空9910 小时前
STM32单片机学习(22) —— I2C通信协议
stm32·单片机·学习
拾知_H11 小时前
STM32/串口控制LED亮灭
stm32·单片机·嵌入式硬件·串口
szxinmai主板定制专家11 小时前
基于ZYNQ MPSOC ARM+FPGA的超高清实时图像采集与压缩系统设计
linux·运维·服务器·arm开发·人工智能·嵌入式硬件·fpga开发
iCxhust11 小时前
个人计算机的起点,INTEL 8088
c语言·单片机·嵌入式硬件·微机原理·8088单板机
国科安芯11 小时前
国科安芯AS32A601芯片及ANSIC-EVB601开发平台获OneWo-zepLinux全面适配支持
网络·单片机·嵌入式硬件·risc-v·安全性测试
ACP广源盛1392462567311 小时前
OpenAI 推出的 GPT-5.5 大模型,倒逼接口芯片升级迭代@ACP#IX8024应用迭代
网络·人工智能·嵌入式硬件·电脑·音视频