diff --git a/MSOS_ESP/main/CMakeLists.txt b/MSOS_ESP/main/CMakeLists.txt index 28ab405..0a1cfe1 100644 --- a/MSOS_ESP/main/CMakeLists.txt +++ b/MSOS_ESP/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "hello_world_main.c" - PRIV_REQUIRES spi_flash - INCLUDE_DIRS "") +idf_component_register(SRCS "hello_world_main.c" "iic.c" "oled.c" + PRIV_REQUIRES spi_flash esp_driver_i2c log + INCLUDE_DIRS ".") diff --git a/MSOS_ESP/main/hello_world_main.c b/MSOS_ESP/main/hello_world_main.c index 7010f3e..34fe9b0 100644 --- a/MSOS_ESP/main/hello_world_main.c +++ b/MSOS_ESP/main/hello_world_main.c @@ -13,6 +13,9 @@ #include "esp_flash.h" #include "esp_system.h" +#include "iic.h" +#include "oled.h" + void app_main(void) { printf("Hello world!\n"); @@ -42,11 +45,11 @@ void app_main(void) printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); - for (int i = 10; i >= 0; i--) { - printf("Restarting in %d seconds...\n", i); + iic_init(); + oled_init(); + + while(1){ + vTaskDelay(1000 / portTICK_PERIOD_MS); } - printf("Restarting now.\n"); - fflush(stdout); - esp_restart(); } diff --git a/MSOS_ESP/main/iic.c b/MSOS_ESP/main/iic.c new file mode 100644 index 0000000..bc0bbb5 --- /dev/null +++ b/MSOS_ESP/main/iic.c @@ -0,0 +1,65 @@ +#include "iic.h" +#include "driver/i2c_master.h" +#include "esp_log.h" +#include + +static const char *TAG = "IIC"; + +static i2c_master_bus_handle_t s_iic_bus = NULL; +static i2c_master_dev_handle_t s_iic_dev = NULL; + +esp_err_t iic_init(void) +{ + i2c_master_bus_config_t bus_cfg = { + .i2c_port = -1, + .sda_io_num = (gpio_num_t)IIC_SDA_IO, + .scl_io_num = (gpio_num_t)IIC_SCL_IO, + .clk_source = I2C_CLK_SRC_DEFAULT, + .glitch_ignore_cnt = 7, + .trans_queue_depth = 0, + .flags.enable_internal_pullup = true, + }; + esp_err_t ret = i2c_new_master_bus(&bus_cfg, &s_iic_bus); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "IIC总线初始化失败"); + return ret; + } + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x00, + .scl_speed_hz = IIC_FREQ_HZ, + }; + ret = i2c_master_bus_add_device(s_iic_bus, &dev_cfg, &s_iic_dev); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "IIC总线初始化失败"); + return ret; + } + ESP_LOGI(TAG, "IIC IO总线初始化成功"); + return ESP_OK; +} + +esp_err_t iic_send_bytes(unsigned char addr, unsigned char *txd, unsigned int len) +{ + if (txd == NULL || len == 0 || s_iic_dev == NULL) { + return ESP_ERR_INVALID_STATE; + } + esp_err_t ret = i2c_master_device_change_address(s_iic_dev, (uint16_t)addr, IIC_TIMEOUT_MS); + if (ret != ESP_OK) { + return ret; + } + return i2c_master_transmit(s_iic_dev, (const uint8_t *)txd, (size_t)len, IIC_TIMEOUT_MS); +} + +unsigned char iic_read_byte(unsigned char addr) +{ + uint8_t byte = 0; + if (s_iic_dev == NULL) { + return 0; + } + if (i2c_master_device_change_address(s_iic_dev, (uint16_t)addr, IIC_TIMEOUT_MS) != ESP_OK) { + return 0; + } + i2c_master_receive(s_iic_dev, &byte, 1, IIC_TIMEOUT_MS); + return (unsigned char)byte; +} diff --git a/MSOS_ESP/main/iic.h b/MSOS_ESP/main/iic.h new file mode 100644 index 0000000..2c8e12d --- /dev/null +++ b/MSOS_ESP/main/iic.h @@ -0,0 +1,15 @@ +#ifndef IIC_H_ +#define IIC_H_ + +#include "esp_err.h" + +#define IIC_SDA_IO 0 +#define IIC_SCL_IO 1 +#define IIC_FREQ_HZ 100000 +#define IIC_TIMEOUT_MS 1000 + +esp_err_t iic_init(void); +esp_err_t iic_send_bytes(unsigned char addr, unsigned char *txd, unsigned int len); +unsigned char iic_read_byte(unsigned char addr); + +#endif diff --git a/MSOS_ESP/main/oled.c b/MSOS_ESP/main/oled.c new file mode 100644 index 0000000..406de7f --- /dev/null +++ b/MSOS_ESP/main/oled.c @@ -0,0 +1,77 @@ +#include "oled.h" +#include "iic.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +void oled_cmd(unsigned char IIC_Command) +{ + unsigned char buf[2] = {0x00, IIC_Command}; + iic_send_bytes(OLED_ADDRESS, buf, 2); +} + +void oled_dat(unsigned char IIC_Data) +{ + unsigned char buf[2] = {0x40, IIC_Data}; + iic_send_bytes(OLED_ADDRESS, buf, 2); +} + +void oled_set_pos(unsigned char x, unsigned char y) +{ + x += OLED_COL_OFFSET; + oled_cmd(0xb0 + 7 - y); + oled_cmd(((x & 0xf0) >> 4) | 0x10); + oled_cmd((x & 0x0f) | 0x00); +} + +void oled_init_dram(char a) +{ + for (unsigned char y = 0; y < Y_WIDTH_; y++) { + oled_set_pos(0, y); + for (unsigned char x = 0; x < X_WIDTH; x++) { + oled_dat(a); + } + } +} + +void oled_set_lum(unsigned char a) +{ + oled_cmd(0x81); + oled_cmd((unsigned char)(a * 255 / 100)); +} + +void oled_init(void) +{ + vTaskDelay(pdMS_TO_TICKS(200)); + + oled_cmd(0xAE); + oled_cmd(0xD5); + oled_cmd(0x80); + oled_cmd(0xA8); + oled_cmd(0x3F); + oled_cmd(0xD3); + oled_cmd(0x00); + oled_cmd(0x40); +#if (OLED_CONTROLLER == OLED_CTRL_SH1106) + oled_cmd(0xAD); + oled_cmd(0x8B); +#elif (OLED_CONTROLLER == OLED_CTRL_ST7315) + oled_cmd(0x8D); + oled_cmd(0x14); +#endif + oled_cmd(0x20); + oled_cmd(0x10); + oled_cmd(0xA1); + oled_cmd(0xC0); + oled_cmd(0xD9); + oled_cmd(0xf1); + oled_cmd(0xDB); + oled_cmd(0x30); + oled_cmd(0xA4); + oled_cmd(0xA6); + oled_cmd(0xAF); + + oled_cmd(0x81); + oled_cmd(0xff); + + oled_init_dram(0); +} diff --git a/MSOS_ESP/main/oled.h b/MSOS_ESP/main/oled.h new file mode 100644 index 0000000..4c07e95 --- /dev/null +++ b/MSOS_ESP/main/oled.h @@ -0,0 +1,27 @@ +#ifndef OLED_H_ +#define OLED_H_ + +#define OLED_ADDRESS 0x3C +#define X_WIDTH 128 +#define Y_WIDTH_ 8 + +#define OLED_CTRL_SH1106 0 +#define OLED_CTRL_ST7315 1 +#define OLED_CONTROLLER OLED_CTRL_SH1106 + +#if (OLED_CONTROLLER == OLED_CTRL_SH1106) + #define OLED_COL_OFFSET 2 +#elif (OLED_CONTROLLER == OLED_CTRL_ST7315) + #define OLED_COL_OFFSET 0 +#else + #error "unknown OLED_CONTROLLER" +#endif + +void oled_cmd(unsigned char IIC_Command); +void oled_dat(unsigned char IIC_Data); +void oled_set_pos(unsigned char x, unsigned char y); +void oled_init_dram(char a); +void oled_set_lum(unsigned char a); +void oled_init(void); + +#endif