图片
Lcd db1,2引脚修改为esp32的d2.,d4脚,原d16,d17脚用于串口通信,到目前为止,pc机可以作为esp32的上位机了。因为它已经可以通过串口接收数据了。
特别注意,idf的串口接收函数是不带阻塞的,程序是通过判断接收字节数为0来阻塞的。
Esp32是双核的,可以开双线程,用一个线程适时监控串口,用另一个线程完成显示和其他动作。或者用串口中断监听串口。完善学习中。
图片
#include <stdio.h>
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_rom_sys.h"
#include "driver/uart.h"
#define UART_NUM UART_NUM_2
#define TXD_PIN 17
#define RXD_PIN 16
#define BUF_SIZE 1024
#define DATA0_GPIO 2
#define DATA1_GPIO 4
#define DATA2_GPIO 18
#define DATA3_GPIO 19
#define DATA4_GPIO 23
#define DATA5_GPIO 25
#define DATA6_GPIO 26
#define DATA7_GPIO 27
#define RS_GPIO 21 // 数据/命令选择引脚
#define RST_GPIO 15 // 复位引脚
#define EN_GPIO 22 // 使能引脚
#define RW 13
void init_uart() { //esp32 串口
const uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM, &uart_config);
uart_set_pin(UART_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);
}
void pd(){ //判断lcd 忙
gpio_set_level(RW, 1);
gpio_set_level(RS_GPIO, 0);
while(gpio_get_level(27)!=0){
esp_rom_delay_us(10);
}
}
void lcd_write_command(uint8_t cmd) {
pd();
gpio_set_level(RS_GPIO, 0); // 设置为命令模式
gpio_set_level(RW, 0);
gpio_set_level(EN_GPIO, 0);
esp_rom_delay_us(50);
gpio_set_level(EN_GPIO, 1);
gpio_set_level(DATA0_GPIO, cmd & 0x01);
gpio_set_level(DATA1_GPIO, (cmd >> 1) & 0x01);
gpio_set_level(DATA2_GPIO, (cmd >> 2) & 0x01);
gpio_set_level(DATA3_GPIO, (cmd >> 3) & 0x01);
gpio_set_level(DATA4_GPIO, (cmd >> 4) & 0x01);
gpio_set_level(DATA5_GPIO, (cmd >> 5) & 0x01);
gpio_set_level(DATA6_GPIO, (cmd >> 6) & 0x01);
gpio_set_level(DATA7_GPIO, (cmd >> 7) & 0x01);
esp_rom_delay_us(500);
gpio_set_level(EN_GPIO, 0); // 使能低电
esp_rom_delay_us(50);
gpio_set_level(RS_GPIO, 1);
gpio_set_level(RW, 1);
esp_rom_delay_us(20);
}
void lcd_init() {
// 初始化引脚
gpio_set_direction(DATA0_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(DATA1_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(DATA2_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(DATA3_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(DATA4_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(DATA5_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(DATA6_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(DATA7_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(RS_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(RST_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction(EN_GPIO, GPIO_MODE_OUTPUT);
// 复位 LCD
gpio_set_level(RST_GPIO, 0);
esp_rom_delay_us(500);
gpio_set_level(RST_GPIO, 1);
}
void lcd_write_data(uint8_t data) {
pd();
gpio_set_level(RS_GPIO, 1); // 设置为数据模式
gpio_set_level(RW, 0);
gpio_set_level(EN_GPIO, 0); // 使能低电平
esp_rom_delay_us(50);
gpio_set_level(EN_GPIO, 1);
gpio_set_level(DATA0_GPIO, data & 0x01);
gpio_set_level(DATA1_GPIO, (data >> 1) & 0x01);
gpio_set_level(DATA2_GPIO, (data >> 2) & 0x01);
gpio_set_level(DATA3_GPIO, (data >> 3) & 0x01);
gpio_set_level(DATA4_GPIO, (data >> 4) & 0x01);
gpio_set_level(DATA5_GPIO, (data >> 5) & 0x01);
gpio_set_level(DATA6_GPIO, (data >> 6) & 0x01);
gpio_set_level(DATA7_GPIO, (data >> 7) & 0x01);
esp_rom_delay_us(500);
gpio_set_level(EN_GPIO, 0); // 使能低电平
esp_rom_delay_us(50);
gpio_set_level(RS_GPIO, 0);
gpio_set_level(RW, 1);
esp_rom_delay_us(20);
}
// 应用主函数
void app_main() {
init_uart();
lcd_init();
// 初始化 LCD 控制器(根据 LCD 模型设置命令)
lcd_write_command(0x30); // 8-bit模式,
lcd_write_command(0x30); // 8-bit模式,
lcd_write_command(0x0c); // 开启显示,不显示光标
lcd_write_command(0x01);
lcd_write_command(0x06);
lcd_write_command(0x80);
//------------------------------------------------------
uint8_t dt[64];
int length =64;
int len=0;
while (1) {
len=uart_read_bytes(UART_NUM, &dt,length, 1); //从pc串口接收
// uart_write_bytes(UART_NUM, &i,1); //向pc 串口发送
if(len>0){ //串口接收到数据
lcd_write_command(0x01); //lcd清屏
lcd_write_command(0x06); //lcd 显示归0
for(int a=0;a<len;a++){
lcd_write_data(dt[a]);
}
}
vTaskDelay(200/ portTICK_PERIOD_MS);
}
}