描述
<p>(啊啊啊!来不及啦,时间不够啦,赶紧做完温湿度交上)</p>
<h3 style="line-height:1.8">* 1、项目功能介绍</h3>
<hr>
<p style="line-height:1.8">实现SHT桌面温湿度计功能</p>
<p style="line-height:1.8">esp32无线发送/接收数据</p>
<p style="line-height:1.8">使用LCD作为显示屏</p>
<p style="line-height:1.8">mpu6050作为交互</p>
<p style="line-height:1.8">可选按键作为交互</p>
<p style="line-height:1.8">(后续我有时间的话会学一下LVGL、SD卡,将此项目开发成小电视)</p>
<p style="line-height:1.8">(远程传感器控制中心,有时间的话实现。暂时想的是esp32做远程传感器模块)</p>
<h3 style="line-height:1.8">*2、项目属性</h3>
<hr>
<p style="line-height:1.8">原创</p>
<p style="line-height:1.8"> </p>
<h3 style="line-height:1.8">* 3、开源协议</h3>
<hr>
<p style="line-height:1.8">Public Domain</p>
<h3 style="line-height:1.8">*4、硬件部分</h3>
<hr>
<p style="line-height:1.8">主控板:</p>
<p style="line-height:1.8"><span style="color:#000000">主控部分:esp32模组</span></p>
<p style="line-height:1.8"><span style="color:#000000"> 主控部分使用esp32,这样我可以直接使用wifi功能无线发送/接收数据。虽然我之前并没有学习过如何使用esp32,但是咱就是不怕困难,这次就边学边做。</span></p>
<p style="line-height:1.8"><span style="color:#000000">显示部分:2.8寸LCD显示屏(插接)</span></p>
<p style="line-height:1.8"><span style="color:#000000"> </span></p>
<p style="line-height:1.8"><span style="color:#000000">交互:MPU6050、按键(可选)</span></p>
<p style="line-height:1.8"><span style="color:#000000"> 可以不焊接连接按键板的fpc座子,使用mpu6050作为交互。也可以使用fpc连线连接到其他设计好的板子拓展功能。</span></p>
<p style="line-height:1.8"><span style="color:#000000">电源:聚合物锂电池;tp4056充电。</span></p>
<p style="line-height:1.8"><span style="color:#000000"> 想着是想画一块和lcd差不多大小的板子,但画出来发现空了一块,干脆把供电换成锂电池,并且加上充放电模块。</span></p>
<p style="line-height:1.8"><span style="color:#000000">按键板:fpc接线,随手一画</span></p>
<p style="line-height:1.8"><span style="color:#000000"> 按照随手画的面板的鼓包按键的位置布局了一下按键,最后设计外壳的时候可能会做一个带按键的。</span></p>
<p style="line-height:1.8"><span style="color:#000000">面板:随手一画(可能有点丑)</span></p>
<p style="line-height:1.8"><span style="color:#000000">远程传感器板(没时间了,先不做了):</span></p>
<p style="line-height:1.8"><span style="color:#000000"> 使用esp32芯片+陶瓷天线+传感器制作远程传感器模块,这样就可以在家里各个角落捕获一些信息,然后在主控板的lcd上显示。当前想到的一些场景是温度传感器模块安装在易起火的地方作火灾报警;燃气传感器安装在燃气灶检测燃气泄漏。</span></p>
<p style="line-height:1.8"> </p>
<h3 style="line-height:1.8">*5、软件部分</h3>
<hr>
<p style="line-height:1.8">由于sht40被我烧掉,淘宝商家发错货等各种原因,加上我开始工作时间不够,这次就只做了测温湿度和显示。(先交上作业,后面再慢慢完善功能吧)</p>
<p style="line-height:1.8">正文:首先,我第一次使用esp32,而且没有使用Arduino编程而是使用esp-idf库。程序写的不好,还请各位大佬多指教</p>
<p style="line-height:1.8">一、 i2c:这一部分网上基本没有最新版esp-idf库的资料,我是跟着官方文档写的程序</p>
<p style="line-height:1.8"><a href="https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32/get-started/index.html" target="_blank">文档:快速入门 - ESP32 - — ESP-IDF 编程指南 v5.3 文档 (espressif.com)</a></p>
<p style="line-height:1.8">这里我不知道怎么弄代码好,就直接粘贴了,有时间研究一下markdown看看</p>
<p style="line-height:1.8">1. i2c初始化:因为我用到了mpu6050和sht40两种i2c设备,所以i2c总线初始化和设备初始化分开写了</p>
<div>
<div>
<div>
<div><span style="color:#2dc26b">i2c_master_bus_handle_t i2c_handle; //i2c总线的句柄后面可能会用到,所以我直接定义成了全局变量<br>i2c_master_dev_handle_t sht40_handle;//sht40句柄同理</span></div>
<div><span style="color:#2dc26b">void i2c_init()</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> i2c_master_bus_config_ti2c_cfg=</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> .clk_source = I2C_CLK_SRC_DEFAULT,</span></div>
<div><span style="color:#2dc26b"> .i2c_port = I2C_NUM_0,</span></div>
<div><span style="color:#2dc26b"> .scl_io_num = GPIO_NUM_36,</span></div>
<div><span style="color:#2dc26b"> .sda_io_num = GPIO_NUM_37,</span></div>
<div><span style="color:#2dc26b"> .flags.enable_internal_pullup = true,</span></div>
<div><span style="color:#2dc26b"> .glitch_ignore_cnt = 7,</span></div>
<div><span style="color:#2dc26b"> };</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_cfg, &i2c_handle));</span></div>
<div><span style="color:#2dc26b">}</span></div>
</div>
</div>
</div>
<p style="line-height:1.8">2. i2c设备穷举:初始化以后可以穷举一下看看i2c设备(sht40)连接是否正常</p>
<div>
<div><span style="color:#2dc26b">void i2c_probe()</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> printf("i2c device list:\r\n");</span></div>
<div><span style="color:#2dc26b"> for (uint16_t i = 0; i <= 0x77; i++)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> if (i2c_master_probe(i2c_handle, i, 100) == ESP_OK)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> printf("%d ", i);</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> printf("\r\n");</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000">正常的话会有68输出,68转16进制0x44刚好是sht40的地址</span></div>
<div><span style="color:#000000">3. sht40初始化:实际上就是创建并注册i2c设备句柄</span></div>
<div>
<div><span style="color:#2dc26b">void sht40_init()</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> i2c_device_config_t sht40_cfg = {</span></div>
<div><span style="color:#2dc26b"> .dev_addr_length = I2C_ADDR_BIT_LEN_7,</span></div>
<div><span style="color:#2dc26b"> .device_address = 0x44,</span></div>
<div><span style="color:#2dc26b"> .scl_speed_hz = 100000,</span></div>
<div><span style="color:#2dc26b"> };</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c_handle, &sht40_cfg, &sht40_handle));</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000">4. 读温湿度:初始化完i2c以后就可以愉快的读取温湿度啦</span></div>
<div><span style="color:#2dc26b">//sht40有三种测温命令,这里command_measure就是传入测温命令,常用的应该是0xfd吧</span></div>
<div>
<div><span style="color:#2dc26b">void sht40_read_temp(uint8_t command_measure, float *data)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> uint8_t buf[6];</span></div>
<div><span style="color:#2dc26b"> uint16_t t_data, rh_data;</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(i2c_master_transmit(sht40_handle, &command_measure, 1, 100));</span></div>
<div><span style="color:#2dc26b"> vTaskDelay(10/portTICK_PERIOD_MS);</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(i2c_master_receive(sht40_handle, buf, 6, 100));</span></div>
<div><span style="color:#2dc26b"> t_data = ((uint16_t)buf[0] << 8) + buf[1];</span></div>
<div><span style="color:#2dc26b"> rh_data = ((uint16_t)buf[3] << 8) + buf[4];</span></div>
<div><span style="color:#2dc26b"> data[0] = ((float)t_data / 65535) * 175 - 45;</span></div>
<div><span style="color:#2dc26b"> data[1] = ((float)rh_data / 65535) * 125 - 6;</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000">二、lcd:这部分挺复杂的,有一些代码我是从官方示例中抄下来的</span></div>
<div><span style="color:#000000">1. 全局变量</span></div>
<div>
<div><span style="color:#2dc26b">spi_device_handle_t lcd_handle;//同理,我把spi总线句柄设置成了全局变量</span></div>
<div><span style="color:#2dc26b">uint16_t LCD_height = 240;</span></div>
<div><span style="color:#2dc26b">uint16_t LCD_width = 320;</span></div>
<div><span style="color:#2dc26b">//下面抄的官方示例(显示方向有改动)</span></div>
<div><span style="color:#2dc26b">DRAM_ATTR static const lcd_init_cmd_t st_init_cmds[] = {</span></div>
<div><span style="color:#2dc26b"> /* Memory Data Access Control, MX=MV=1, MY=ML=MH=0, RGB=0 */</span></div>
<div><span style="color:#2dc26b"> {0x36, {0xa8}, 1},</span></div>
<div><span style="color:#2dc26b"> /* Interface Pixel Format, 16bits/pixel for RGB/MCU interface */</span></div>
<div><span style="color:#2dc26b"> {0x3A, {0x55}, 1},</span></div>
<div><span style="color:#2dc26b"> /* Porch Setting */</span></div>
<div><span style="color:#2dc26b"> {0xB2, {0x0c, 0x0c, 0x00, 0x33, 0x33}, 5},</span></div>
<div><span style="color:#2dc26b"> /* Gate Control, Vgh=13.65V, Vgl=-10.43V */</span></div>
<div><span style="color:#2dc26b"> {0xB7, {0x45}, 1},</span></div>
<div><span style="color:#2dc26b"> /* VCOM Setting, VCOM=1.175V */</span></div>
<div><span style="color:#2dc26b"> {0xBB, {0x2B}, 1},</span></div>
<div><span style="color:#2dc26b"> /* LCM Control, XOR: BGR, MX, MH */</span></div>
<div><span style="color:#2dc26b"> {0xC0, {0x2C}, 1},</span></div>
<div><span style="color:#2dc26b"> /* VDV and VRH Command Enable, enable=1 */</span></div>
<div><span style="color:#2dc26b"> {0xC2, {0x01, 0xff}, 2},</span></div>
<div><span style="color:#2dc26b"> /* VRH Set, Vap=4.4+... */</span></div>
<div><span style="color:#2dc26b"> {0xC3, {0x11}, 1},</span></div>
<div><span style="color:#2dc26b"> /* VDV Set, VDV=0 */</span></div>
<div><span style="color:#2dc26b"> {0xC4, {0x20}, 1},</span></div>
<div><span style="color:#2dc26b"> /* Frame Rate Control, 60Hz, inversion=0 */</span></div>
<div><span style="color:#2dc26b"> {0xC6, {0x0f}, 1},</span></div>
<div><span style="color:#2dc26b"> /* Power Control 1, AVDD=6.8V, AVCL=-4.8V, VDDS=2.3V */</span></div>
<div><span style="color:#2dc26b"> {0xD0, {0xA4, 0xA1}, 1},</span></div>
<div><span style="color:#2dc26b"> /* Positive Voltage Gamma Control */</span></div>
<div><span style="color:#2dc26b"> {0xE0, {0xD0, 0x00, 0x05, 0x0E, 0x15, 0x0D, 0x37, 0x43, 0x47, 0x09, 0x15, 0x12, 0x16, 0x19}, 14},</span></div>
<div><span style="color:#2dc26b"> /* Negative Voltage Gamma Control */</span></div>
<div><span style="color:#2dc26b"> {0xE1, {0xD0, 0x00, 0x05, 0x0D, 0x0C, 0x06, 0x2D, 0x44, 0x40, 0x0E, 0x1C, 0x18, 0x16, 0x19}, 14},</span></div>
<div><span style="color:#2dc26b"> /* Sleep Out */</span></div>
<div><span style="color:#2dc26b"> {0x11, {0}, 0x80},</span></div>
<div><span style="color:#2dc26b"> /* Display On */</span></div>
<div><span style="color:#2dc26b"> {0x29, {0}, 0x80},</span></div>
<div><span style="color:#2dc26b"> {0, {0}, 0xff}</span></div>
<div><span style="color:#2dc26b">};</span></div>
</div>
<div><span style="color:#000000">2. 初始化:这里只有lcd挂载到了spi总线上,sd卡单独挂载到了其他spi总线,所以lcd初始化和spi初始化我写到了一块</span></div>
<div><span style="color:#2dc26b"><span style="color:#2dc26b"><span style="color:#2dc26b">//这里我理解的是发送前会调用这个函数</span></span></span>
<div>
<div><span style="color:#2dc26b">void lcd_pre_callback(spi_transaction_t *t)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> int dc = (int)t->user;</span></div>
<div><span style="color:#2dc26b"> gpio_set_level(LCD_DC_IO_NUM, dc);</span></div>
<div><span style="color:#2dc26b">}</span></div>
</div>
<div>
<div><span style="color:#2dc26b">void lcd_init()</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> /*spi初始化 */</span></div>
<div><span style="color:#2dc26b"> //spi总线配置结构体</span></div>
<div><span style="color:#2dc26b"> spi_bus_config_t spi_cfg = {</span></div>
<div><span style="color:#2dc26b"> .sclk_io_num = GPIO_NUM_12,</span></div>
<div><span style="color:#2dc26b"> .mosi_io_num = GPIO_NUM_11,</span></div>
<div><span style="color:#2dc26b"> .flags = SPICOMMON_BUSFLAG_MASTER,</span></div>
<div><span style="color:#2dc26b"> .miso_io_num = -1,</span></div>
<div><span style="color:#2dc26b"> .quadhd_io_num = -1,</span></div>
<div><span style="color:#2dc26b"> .quadwp_io_num = -1,</span></div>
<div><span style="color:#2dc26b"> };</span></div>
<div><span style="color:#2dc26b"> //lcd设备配置结构体</span></div>
<div><span style="color:#2dc26b"> spi_device_interface_config_t lcd_cfg = {</span></div>
<div><span style="color:#2dc26b"> .mode = 0,</span></div>
<div><span style="color:#2dc26b"> .clock_speed_hz = 10000000,</span></div>
<div><span style="color:#2dc26b"> .queue_size = 8,</span></div>
<div><span style="color:#2dc26b"> .spics_io_num = GPIO_NUM_10,</span></div>
<div><span style="color:#2dc26b"> .pre_cb = lcd_pre_callback,</span></div>
<div><span style="color:#2dc26b"> };</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &spi_cfg, SPI_DMA_CH_AUTO));</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(spi_bus_add_device(SPI2_HOST, &lcd_cfg, &lcd_handle));</span></div>
<div><span style="color:#2dc26b"> //rst dc bl 引脚初始化</span></div>
<div><span style="color:#2dc26b"> gpio_config_t lcd_io_cfg = {</span></div>
<div><span style="color:#2dc26b"> .mode = GPIO_MODE_OUTPUT,</span></div>
<div><span style="color:#2dc26b"> .pull_up_en = GPIO_PULLUP_ENABLE,</span></div>
<div><span style="color:#2dc26b"> .pin_bit_mask = (1ull << LCD_DC_IO_NUM) | (1ull << LCD_BL_IO_NUM) | (1ull << LCD_RST_IO_NUM),</span></div>
<div><span style="color:#2dc26b"> };</span></div>
<div><span style="color:#2dc26b"> gpio_config(&lcd_io_cfg);</span></div>
<div><span style="color:#2dc26b"> //硬件复位</span></div>
<div><span style="color:#2dc26b"> gpio_set_level(LCD_RST_IO_NUM, 0);</span></div>
<div><span style="color:#2dc26b"> vTaskDelay(100 / portTICK_PERIOD_MS);</span></div>
<div><span style="color:#2dc26b"> gpio_set_level(LCD_RST_IO_NUM, 1);</span></div>
<div><span style="color:#2dc26b"> vTaskDelay(100 / portTICK_PERIOD_MS);</span></div>
<div><span style="color:#2dc26b"> //初始化</span></div>
<div><span style="color:#2dc26b"> int cmd = 0;</span></div>
<div><span style="color:#2dc26b"> while (st_init_cmds[cmd].databytes != 0xff) {</span></div>
<div><span style="color:#2dc26b"> lcd_cmd(st_init_cmds[cmd].cmd, false);</span></div>
<div><span style="color:#2dc26b"> lcd_data(st_init_cmds[cmd].data, st_init_cmds[cmd].databytes & 0x1F);</span></div>
<div><span style="color:#2dc26b"> if (st_init_cmds[cmd].databytes & 0x80) {</span></div>
<div><span style="color:#2dc26b"> vTaskDelay(100 / portTICK_PERIOD_MS);</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> cmd++;</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<br>
<div><span style="color:#2dc26b"> ///Enable backlight</span></div>
<div><span style="color:#2dc26b"> </span><span style="color:#2dc26b"> gpio_set_level(LCD_BL_IO_NUM, 1);</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div> 3. 发送命令和数据的函数:抄的官方示例
<div>
<div><span style="color:#2dc26b">void lcd_cmd(const uint8_t cmd, bool keep_cs_active)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> esp_err_t ret;</span></div>
<div><span style="color:#2dc26b"> spi_transaction_t t;</span></div>
<div><span style="color:#2dc26b"> memset(&t, 0, sizeof(t)); //Zero out the transaction</span></div>
<div><span style="color:#2dc26b"> t.length = 8; //Command is 8 bits</span></div>
<div><span style="color:#2dc26b"> t.tx_buffer = &cmd; //The data is the cmd itself</span></div>
<div><span style="color:#2dc26b"> t.user = LCD_CMD_MODE; //D/C needs to be set to 0</span></div>
<div><span style="color:#2dc26b"> if (keep_cs_active) {</span></div>
<div><span style="color:#2dc26b"> t.flags = SPI_TRANS_CS_KEEP_ACTIVE; //Keep CS active after data transfer</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> ret = spi_device_polling_transmit(lcd_handle, &t); //Transmit!</span></div>
<div><span style="color:#2dc26b"> assert(ret == ESP_OK); //Should have had no issues.</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#2dc26b">void lcd_data(const uint8_t *data, int len)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> spi_transaction_t t;</span></div>
<div><span style="color:#2dc26b"> if (len == 0) {</span></div>
<div><span style="color:#2dc26b"> return; //no need to send anything</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> memset(&t, 0, sizeof(t)); //Zero out the transaction</span></div>
<div><span style="color:#2dc26b"> t.length = len * 8; //Len is in bytes, transaction length is in bits.</span></div>
<div><span style="color:#2dc26b"> t.tx_buffer = data; //Data</span></div>
<div><span style="color:#2dc26b"> t.user = LCD_DATA_MODE; //D/C needs to be set to 1</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(spi_device_polling_transmit(lcd_handle, &t));</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000">4. 设置显示区域:借鉴了官方示例,没有使用lcd_cmd和lcd_data函数,那样太慢了</span></div>
<div>
<div><span style="color:#2dc26b">void lcd_set_window(uint16_t startX, uint16_t endX, uint16_t startY, uint16_t endY)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> spi_transaction_t trans[4];</span></div>
<div><span style="color:#2dc26b"> for (uint8_t i = 0; i < 4; i++)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> memset(&trans[i], 0, sizeof(spi_transaction_t));</span></div>
<div><span style="color:#2dc26b"> if ((i & 1) == 0)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> trans[i].length = 8;</span></div>
<div><span style="color:#2dc26b"> trans[i].user = LCD_CMD_MODE;</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> else</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> trans[i].length = 8 * 4;</span></div>
<div><span style="color:#2dc26b"> trans[i].user = LCD_DATA_MODE;</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> trans[i].flags = SPI_TRANS_USE_TXDATA;</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> trans[0].tx_data[0] = 0x2a;</span></div>
<div><span style="color:#2dc26b"> trans[1].tx_data[0] = startX >> 8;</span></div>
<div><span style="color:#2dc26b"> trans[1].tx_data[1] = startX& 0xff;</span></div>
<div><span style="color:#2dc26b"> trans[1].tx_data[2] = endX >> 8;</span></div>
<div><span style="color:#2dc26b"> trans[1].tx_data[3] = endX & 0xff;</span></div>
<div><span style="color:#2dc26b"> trans[2].tx_data[0] = 0x2b;</span></div>
<div><span style="color:#2dc26b"> trans[3].tx_data[0] = startY >> 8;</span></div>
<div><span style="color:#2dc26b"> trans[3].tx_data[1] = startY & 0xff;</span></div>
<div><span style="color:#2dc26b"> trans[3].tx_data[2] = endY >> 8;</span></div>
<div><span style="color:#2dc26b"> trans[3].tx_data[3] = endY& 0xff;</span></div>
<div><span style="color:#2dc26b"> for (uint8_t i = 0; i < 4; i++)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> ESP_ERROR_CHECK(spi_device_queue_trans(lcd_handle, &trans[i], portMAX_DELAY));</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000">5. 画点,没什么好说的:</span></div>
<div>
<div><span style="color:#2dc26b">void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> uint8_t buf[2];</span></div>
<div><span style="color:#2dc26b"> buf[0] = color >> 8;</span></div>
<div><span style="color:#2dc26b"> buf[1] = color;</span></div>
<div><span style="color:#2dc26b"> lcd_set_window(x, x, y, y);</span></div>
<div><span style="color:#2dc26b"> lcd_cmd(0x2c, false);</span></div>
<div><span style="color:#2dc26b"> lcd_data(buf, 2);</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000">6. 清屏:扫描线的方式填充,使用画点函数太慢</span></div>
<div>
<div><span style="color:#2dc26b">void lcd_clear(uint16_t color)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> uint8_t *buf;</span></div>
<div><span style="color:#2dc26b"> buf = heap_caps_malloc(320 * sizeof(uint16_t), MALLOC_CAP_DMA);</span></div>
<div><span style="color:#2dc26b"> memset(buf, color, 320 * sizeof(uint16_t));</span></div>
<br>
<div><span style="color:#2dc26b"> lcd_set_window(0, LCD_width-1, 0, LCD_height-1);</span></div>
<div><span style="color:#2dc26b"> lcd_cmd(0x2c, false);</span></div>
<div><span style="color:#2dc26b"> for (uint16_t i = 0; i < LCD_height; i++)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> lcd_data(buf, 320 * 2);</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> heap_caps_free(buf);</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div>7. 显示字符:<span style="color:#000000">ascii16是字模,这是从我很久以前用stm32写lcd的时候写的函数,字模忘记怎么取得了。。。。。这部分挺好改的。</span></div>
<div>
<div><span style="color:#2dc26b">void LCD_ShowChar(uint16_t x, uint16_t y, uint8_t ch, uint8_t size,</span></div>
<div><span style="color:#2dc26b"> uint16_t color, uint16_t bg_color, uint8_t mode)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> uint8_t temp;</span></div>
<div><span style="color:#2dc26b"> uint16_t y0 = y, x0 = x;</span></div>
<div><span style="color:#2dc26b"> uint8_t idx = 0;</span></div>
<div><span style="color:#2dc26b"> for (uint8_t i = 0; i < size/2; i++)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> for (uint8_t t = 0; t < size/8; t++)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> switch (size)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> case 16:</span></div>
<div><span style="color:#2dc26b"> temp = ascii16[ch-32][idx];</span></div>
<div><span style="color:#2dc26b"> break;</span></div>
<div><span style="color:#2dc26b"> case 24:</span></div>
<div><span style="color:#2dc26b"> temp = ascii24[ch-32][idx];</span></div>
<div><span style="color:#2dc26b"> break;</span></div>
<div><span style="color:#2dc26b"> case 32:</span></div>
<div><span style="color:#2dc26b"> temp = ascii32[ch-32][idx];</span></div>
<div><span style="color:#2dc26b"> break;</span></div>
<div><span style="color:#2dc26b"> default:</span></div>
<div><span style="color:#2dc26b"> break;</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> idx++;</span></div>
<div><span style="color:#2dc26b"> for (uint8_t j = 0; j < 8; j++)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> if (temp & 0x80)</span></div>
<div><span style="color:#2dc26b"> lcd_draw_point(x0, y0, color);</span></div>
<div><span style="color:#2dc26b"> else</span></div>
<div><span style="color:#2dc26b"> if (mode == 1)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> lcd_draw_point(x0, y0, bg_color);</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> </span></div>
<div><span style="color:#2dc26b"> y0++;</span></div>
<div><span style="color:#2dc26b"> temp <<= 1;</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b"> y0 = y;</span></div>
<div><span style="color:#2dc26b"> x0++;</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000">8. 显示字符串:循环调用显示字符函数就完了</span></div>
<div>
<div><span style="color:#2dc26b">void LCD_ShowString(uint16_t x, uint16_t y, char *str, uint8_t size,</span></div>
<div><span style="color:#2dc26b"> uint16_t color, uint16_t bg_color, uint8_t mode)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> uint8_t idx = 0;</span></div>
<div><span style="color:#2dc26b"> while (str[idx] != '\0')</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> LCD_ShowChar(x, y, str[idx], size, color, bg_color, mode);</span></div>
<div><span style="color:#2dc26b"> x+=size/2;</span></div>
<div><span style="color:#2dc26b"> idx++;</span></div>
<div><span style="color:#2dc26b"> } </span></div>
<div><span style="color:#2dc26b">}</span></div>
<div> </div>
<div>三、主函数</div>
<div>
<div>
<div><span style="color:#2dc26b">void app_main(void)</span></div>
<div><span style="color:#2dc26b">{</span></div>
<div><span style="color:#2dc26b"> i2c_init();</span></div>
<div><span style="color:#2dc26b"> sht40_init();</span></div>
<div><span style="color:#2dc26b"> lcd_init();</span></div>
<div><span style="color:#2dc26b"> float t_rh[2];</span></div>
<div><span style="color:#2dc26b"> char t_rh_str[22];</span></div>
<div><span style="color:#2dc26b"> vTaskDelay(100/portTICK_PERIOD_MS);</span></div>
<div><span style="color:#2dc26b"> lcd_clear(LCD_COLOR_BLACK);</span></div>
<div><span style="color:#2dc26b"> vTaskDelay(100/portTICK_PERIOD_MS);</span></div>
<div><span style="color:#2dc26b"> while (1)</span></div>
<div><span style="color:#2dc26b"> {</span></div>
<div><span style="color:#2dc26b"> sht40_read_temp(0xfd, t_rh);</span></div>
<div><span style="color:#2dc26b"> printf("temp:%.2f RH:%.2f\r\n", t_rh[0], t_rh[1]);</span></div>
<div><span style="color:#2dc26b"> sprintf(t_rh_str, "T: %.2foC, RH: %.2f%c", t_rh[0], t_rh[1], '%');</span></div>
<div><span style="color:#2dc26b"> LCD_ShowString(0, 0, t_rh_str, 32, LCD_COLOR_RED, LCD_COLOR_BLACK, 1);</span></div>
<div><span style="color:#2dc26b"> vTaskDelay(100);</span></div>
<div><span style="color:#2dc26b"> }</span></div>
<div><span style="color:#2dc26b">}</span></div>
<div><span style="color:#000000"> 只显示温湿度的话这些函数就够了,但很明显,这就是垃圾程序。我先写成这样完成作业再说吧,以后我会慢慢完善的。而且这次硬件设计上完全可以做成小电视的,后续我会再学一下esp32的联网怎么搞和lvgl尝试把小电视整出来。还有就是完成工程源码先不放出来了,写的太烂了,做完整理完再上传吧。</span></div>
<div><span style="color:#000000"> (打工真的没时间啊!!!)</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h3 style="line-height:1.8">*7、大赛LOGO验证</h3>
<hr>
<p style="line-height:1.8"><img src="//image.lceda.cn/oshwhub/be7010a15afc4c7ba80cb43ba8fd104e.png" alt="" width="709" height="567"></p>
<p style="line-height:1.8"> </p>
<h3 style="line-height:1.8">* 8、演示您的项目并录制成视频上传</h3>
<hr>
<p style="line-height:1.8"> </p>
<p style="line-height:1.8"> </p>
<p style="line-height:1.8"> </p>
评论(0)