鸿蒙开发板Hi3861_驱动0.95_oled显示屏ssd1306_code-2.0-CANARY_双显示屏效果

2.0支持windows编译与上传,不需要ubuntu编译

环境搭建需要有耐心:

https://www.cnblogs.com/txwtech/p/15041927.html

首先学会点亮LED的实验

https://www.cnblogs.com/txwtech/p/15139405.html

//驱动oled源代码

源码下载:

https://gitee.com/hihopeorg/harmonyos-ssd1306

下载的源代码有三个文件夹,examples,libm_portm,ssd1306,拷贝到如下目录

F:\code-2.0-canary\applications\sample\wifi-iot\app

参考链接:

https://harmonyos.51cto.com/posts/2126#comment

oled SDA接gpio13

oled SCL接gpio14

VCC --3V3

GND--GND

打开vscode,源码是1.0的,参考如下方法修改:

https://blog.csdn.net/YangHxuan/article/details/119116051

需要修改的几个关键文件:

F:\code-2.0-canary\device\hisilicon\hispark_pegasus\sdk_liteos\build\config

找到usr_config.mk修改

添加:

CONFIG_I2C_SUPPORT=y

ssd1306_demo.c,这个是根据1.0修改为2.0版本的

/** Copyright (c) 2020, HiHope Community.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions are met:** 1. Redistributions of source code must retain the above copyright notice, this*    list of conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright notice,*    this list of conditions and the following disclaimer in the documentation*    and/or other materials provided with the distribution.** 3. Neither the name of the copyright holder nor the names of its*    contributors may be used to endorse or promote products derived from*    this software without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include <ctype.h>
#include <stdio.h>
#include <unistd.h>#include "ohos_init.h"
#include "cmsis_os2.h"
//#include "wifiiot_gpio.h"
#include "hi_io.h"
//#include "wifiiot_gpio_ex.h"
//#include "wifiiot_pwm.h"
#include "hi_pwm.h"
#include "wifiiot_adc.h"
#include "hi_adc.h"
//#include "wifiiot_i2c.h"
#include "hi_i2c.h"
//#include "wifiiot_errno.h"
#include "hi_errno.h"
//#include "wifiiot_watchdog.h"
#include "hi_watchdog.h"#include "ssd1306.h"
#include "ssd1306_tests.h"#define OLED_I2C_BAUDRATE 400*1000const unsigned char headSize[] = { 64, 64 };
const unsigned char headData[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00,
0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00,
0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x00, 0x00, 0xFF, 0x83, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE3, 0xF0, 0x18, 0x00,
0x00, 0x00, 0x01, 0xFF, 0xE3, 0xE0, 0x10, 0x00, 0x00, 0x00, 0x61, 0xFE, 0x03, 0xE1, 0xF8, 0x00,
0x00, 0xC1, 0xF1, 0xF8, 0x97, 0xE0, 0x18, 0x00, 0x00, 0x00, 0xB9, 0xFF, 0xFF, 0xF8, 0x88, 0x00,
0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFD, 0xF8, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFE, 0x78, 0x00,
0x00, 0x00, 0xCD, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x40, 0xDF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
0x00, 0x40, 0xDF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x40, 0x7F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
0x00, 0xA0, 0x7F, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x01, 0x20, 0x3F, 0xFF, 0xFC, 0x47, 0xF8, 0x00,
0x02, 0x10, 0x1F, 0xFF, 0xFF, 0x87, 0xF0, 0x00, 0x0C, 0x18, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x08, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0D, 0x07, 0xFF, 0xFC, 0x07, 0xF0, 0x00,
0x00, 0x05, 0x07, 0xFF, 0xC0, 0x01, 0xF0, 0x00, 0x00, 0x05, 0x07, 0xFF, 0xDF, 0xE1, 0xE0, 0x00,
0x02, 0x06, 0x07, 0xFF, 0xFF, 0x09, 0xE0, 0x00, 0x00, 0x02, 0x07, 0xFF, 0xFE, 0x1F, 0xC0, 0x00,
0x00, 0x02, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x60, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
0x00, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x32, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0xF0, 0x00, 0x00,
0x00, 0x07, 0xFF, 0xFF, 0xFE, 0xF0, 0x00, 0x01, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x07,
0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0xE0, 0x3F, 0x00, 0x23, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF,
};/*** 汉字字模在线: https://www.23bei.com/tool-223.html* 数据排列:从左到右从上到下* 取模方式:横向8位左高位
**/
void TestDrawChinese1(void)
{const uint32_t W = 16, H = 16;uint8_t fonts[][32] = {{/*-- ID:0,字符:"你",ASCII编码:C4E3,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*///0x11,0x00,0x11,0x00,0x11,0x00,0x23,0xFC,0x22,0x04,0x64,0x08,0xA8,0x40,0x20,0x40,//0x21,0x50,0x21,0x48,0x22,0x4C,0x24,0x44,0x20,0x40,0x20,0x40,0x21,0x40,0x20,0x80,/*-- ID:0,字符:"阿",ASCII编码:B0A2,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x04,0x7F,0xFE,0x44,0x08,0x48,0x08,0x48,0x28,0x51,0xF8,0x49,0x28,0x49,0x28,
0x45,0x28,0x45,0x28,0x45,0x28,0x69,0xE8,0x51,0x28,0x40,0x08,0x40,0x28,0x40,0x10,},{/*-- ID:1,字符:"好",ASCII编码:BAC3,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*///0x10,0x00,0x11,0xFC,0x10,0x04,0x10,0x08,0xFC,0x10,0x24,0x20,0x24,0x24,0x27,0xFE,//0x24,0x20,0x44,0x20,0x28,0x20,0x10,0x20,0x28,0x20,0x44,0x20,0x84,0xA0,0x00,0x40,/*-- ID:1,字符:"武",ASCII编码:CEE4,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x40,0x02,0x50,0x3F,0x48,0x00,0x48,0x00,0x40,0xFF,0xFE,0x04,0x40,0x04,0x40,
0x27,0x40,0x24,0x40,0x24,0x20,0x24,0x20,0x27,0xA0,0xF8,0x12,0x40,0x0A,0x00,0x06,},{/*-- ID:2,字符:"鸿",ASCII编码:BAE8,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*///0x40,0x20,0x30,0x48,0x10,0xFC,0x02,0x88,0x9F,0xA8,0x64,0x88,0x24,0xA8,0x04,0x90,//0x14,0x84,0x14,0xFE,0xE7,0x04,0x3C,0x24,0x29,0xF4,0x20,0x04,0x20,0x14,0x20,0x08,/*-- ID:2,字符:"科",ASCII编码:BFC6,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x04,0x10,0x0E,0x10,0xF8,0x90,0x08,0x50,0x08,0x10,0xFE,0x90,0x08,0x50,0x1C,0x14,
0x1A,0x1E,0x29,0xF0,0x28,0x10,0x48,0x10,0x88,0x10,0x08,0x10,0x08,0x10,0x08,0x10,},{/*-- ID:3,字符:"蒙",ASCII编码:C3C9,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*///0x04,0x48,0x7F,0xFC,0x04,0x40,0x7F,0xFE,0x40,0x02,0x8F,0xE4,0x00,0x00,0x7F,0xFC,// 0x06,0x10,0x3B,0x30,0x05,0xC0,0x1A,0xA0,0x64,0x90,0x18,0x8E,0x62,0x84,0x01,0x00/*-- ID:3,字符:"技",ASCII编码:BCBC,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x10,0x40,0x10,0x40,0x10,0x48,0x13,0xFC,0xFC,0x40,0x10,0x40,0x10,0x40,0x13,0xF8,
0x1A,0x08,0x31,0x10,0xD1,0x10,0x10,0xA0,0x10,0x40,0x10,0xB0,0x51,0x0E,0x26,0x04,},{/*-- ID:4,字符:"t",ASCII编码:A3F4,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x07,0xE0,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x90,0x01,0x90,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,},{/*-- ID:5,字符:"x",ASCII编码:A3F8,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x0C,0x30,
0x03,0x60,0x01,0xC0,0x03,0x60,0x0C,0x30,0x3E,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,},{/*-- ID:6,字符:"w",ASCII编码:A3F7,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0xEE,0x18,0xC4,
0x08,0xCC,0x0D,0x68,0x05,0x28,0x06,0x30,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x00,},
{/*-- ID:4,字符:"t",ASCII编码:A3F4,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x07,0xE0,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x90,0x01,0x90,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,
},{/*-- ID:7,字符:"e",ASCII编码:A3E5,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x0C,0x30,
0x0C,0x30,0x0F,0xF0,0x0C,0x00,0x0C,0x30,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,
},{/*-- ID:8,字符:"c",ASCII编码:A3E3,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x0C,0x30,
0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x30,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,
},
{/*-- ID:9,字符:"h",ASCII编码:A3E8,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节*/
0x00,0x00,0x00,0x00,0x0E,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0xE0,0x07,0x30,
0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x30,0x0E,0x78,0x00,0x00,0x00,0x00,0x00,0x00,}};ssd1306_Fill(Black);for (size_t i = 0; i < sizeof(fonts)/sizeof(fonts[0]); i++) {ssd1306_DrawRegion(i * W, 0, W, H, fonts[i], sizeof(fonts[0]), W);}ssd1306_SetCursor(64, 0);ssd1306_DrawRegion(64, 0, headSize[0], headSize[1], headData, sizeof(headData), headSize[0]);ssd1306_UpdateScreen();
}void TestDrawChinese2(void)
{const uint32_t W = 12, H = 12, S = 16;uint8_t fonts[][24] = {{/*-- ID:0,字符:"你",ASCII编码:C4E3,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/0x12,0x00,0x12,0x00,0x27,0xF0,0x24,0x20,0x69,0x40,0xA1,0x00,0x25,0x40,0x25,0x20,0x29,0x10,0x31,0x10,0x25,0x00,0x22,0x00,},{/*-- ID:1,字符:"好",ASCII编码:BAC3,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/0x20,0x00,0x27,0xE0,0x20,0x40,0xF8,0x80,0x48,0x80,0x48,0xA0,0x57,0xF0,0x50,0x80,0x30,0x80,0x28,0x80,0x4A,0x80,0x81,0x00,},{/*-- ID:2,字符:"鸿",ASCII编码:BAE8,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/0x00,0x40,0x80,0x80,0x5D,0xE0,0x09,0x20,0xC9,0xA0,0x09,0x60,0x29,0x00,0xCD,0xF0,0x58,0x10,0x43,0xD0,0x40,0x10,0x40,0x60,},{/*-- ID:3,字符:"蒙",ASCII编码:C3C9,对应字:宽x高=12x12,画布:宽W=16 高H=12,共24字节*/0x09,0x00,0x7F,0xE0,0x09,0x00,0x7F,0xF0,0x80,0x10,0x7F,0xE0,0x0C,0x40,0x32,0x80,0xC7,0x00,0x0A,0x80,0x32,0x70,0xC6,0x20}};ssd1306_Fill(Black);for (size_t i = 0; i < sizeof(fonts)/sizeof(fonts[0]); i++) {ssd1306_DrawRegion(i * H, 0, W, H, fonts[i], sizeof(fonts[0]), S);}ssd1306_SetCursor(64, 0);ssd1306_DrawRegion(64, 0, headSize[0], headSize[1], headData, sizeof(headData), headSize[0]);ssd1306_SetCursor(0, 64 - 8);ssd1306_DrawString("txwtech.com", Font_6x8, White);ssd1306_SetCursor(0, 64 - 8*2);ssd1306_DrawString("@xtang10", Font_6x8, White);ssd1306_UpdateScreen();
}void TestShowChars(FontDef font, uint8_t w, uint8_t h)
{ssd1306_Fill(Black);uint8_t x = 0, y = 0;for (uint8_t c = 1; c < 128; c++) {if (isprint(c)) {ssd1306_SetCursor(x, y);ssd1306_DrawChar((char) c, font, White);x += w;if (x >= SSD1306_WIDTH) {x = 0;y += h;}}}ssd1306_UpdateScreen();
}void Ssd1306TestTask(void* arg)
{(void) arg;// GpioInit();hi_gpio_init();// IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);// IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);// I2cInit(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);hi_io_set_func(HI_I2C_IDX_0, OLED_I2C_BAUDRATE);// WatchDogDisable();hi_watchdog_disable();usleep(20*1000);ssd1306_Init();ssd1306_Fill(Black);ssd1306_SetCursor(0, 0);ssd1306_DrawString("Hello HarmonyOS!", Font_7x10, White);uint32_t start = HAL_GetTick();ssd1306_UpdateScreen();uint32_t end = HAL_GetTick();printf("ssd1306_UpdateScreen time cost: %d ms.\r\n", end - start);while (1) {TestDrawChinese1();osDelay(500);TestDrawChinese2();osDelay(500);// TestShowChars(Font_6x8, 6, 8);// osDelay(500);//  TestShowChars(Font_7x10, 7, 10);//  osDelay(500);ssd1306_TestAll();}
}void Ssd1306TestDemo(void)
{osThreadAttr_t attr;attr.name = "Ssd1306Task";attr.attr_bits = 0U;attr.cb_mem = NULL;attr.cb_size = 0U;attr.stack_mem = NULL;attr.stack_size = 10240;attr.priority = osPriorityNormal;if (osThreadNew(Ssd1306TestTask, NULL, &attr) == NULL) {printf("[Ssd1306TestDemo] Falied to create Ssd1306TestTask!\n");}
}
APP_FEATURE_INIT(Ssd1306TestDemo);

examples文件夹的build.gn

# Copyright (c) 2020, HiHope Community.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.static_library("oled_test") {sources = ["ssd1306_demo.c","ssd1306_tests.c",]include_dirs = ["../ssd1306","//utils/native/lite/include","//kernel/liteos_m/components/cmsis/2.0","//base/iot_hardware/interfaces/kits/wifiiot_lite","//applications/sample/wifi-iot/app/ssd1306",]
}

ssd1306文件夹的build.gn

# Copyright (c) 2020, HiHope Community.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.static_library("oled_ssd1306") {sources = ["ssd1306.c","ssd1306_fonts.c",]include_dirs = ["//utils/native/lite/include","//kernel/liteos_m/components/cmsis/2.0","//base/iot_hardware/interfaces/kits/wifiiot_lite",]
}

ssd1306文件夹的ssd1306.c

#include "ssd1306.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>  // For memcpy#include <stdio.h>
#include <unistd.h>
#include "cmsis_os2.h"
//#include "wifiiot_i2c.h"
//#include "wifiiot_errno.h"
#include "hi_errno.h" //code-2.0-canary,新添加的。txwtech
#include "hi_i2c.h"   //code-2.0-canary,新添加的。txwtech#if defined(SSD1306_USE_I2C)
//#define SSD1306_I2C_IDX WIFI_IOT_I2C_IDX_0
#define SSD1306_I2C_IDX HI_I2C_IDX_0  //code-2.0-canary,新添加的。txwtech#define SSD1306_CTRL_CMD 0x00
#define SSD1306_CTRL_DATA 0x40
#define SSD1306_MASK_CONT (0x1<<7)void ssd1306_Reset(void) {/* for I2C - do nothing */
}void HAL_Delay(uint32_t ms)
{uint32_t msPerTick = 1000 / osKernelGetTickFreq(); // 10msif (ms >= msPerTick) {osDelay(ms / msPerTick);}uint32_t restMs = ms % msPerTick;if (restMs > 0) {usleep(restMs * 1000);}
}uint32_t HAL_GetTick(void)
{uint32_t msPerTick = 1000 / osKernelGetTickFreq(); // 10msuint32_t tickMs = osKernelGetTickCount() * msPerTick;uint32_t csPerMs = osKernelGetSysTimerFreq() / 1000; // 160K cycle/msuint32_t csPerTick = csPerMs * msPerTick; // 1600K cycles/tickuint32_t restMs = osKernelGetSysTimerCount() % csPerTick / csPerMs;return tickMs + restMs;
}static uint32_t ssd1306_SendData(uint8_t* data, size_t size)
{// WifiIotI2cIdx id = SSD1306_I2C_IDX;hi_i2c_idx id = SSD1306_I2C_IDX;// WifiIotI2cData i2cData = {0};hi_i2c_data i2cData = {0};//  i2cData.sendBuf = data;// i2cData.sendLen = size;i2cData.send_buf = data;i2cData.send_len = size;// return I2cWrite(id, SSD1306_I2C_ADDR, &i2cData);return hi_i2c_write(id, SSD1306_I2C_ADDR, &i2cData);
}static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte)
{uint8_t buffer[] = {regAddr, byte};return ssd1306_SendData(buffer, sizeof(buffer));
}// Send a byte to the command register
void ssd1306_WriteCommand(uint8_t byte) {ssd1306_WiteByte(SSD1306_CTRL_CMD, byte);
}// Send data
void ssd1306_WriteData(uint8_t* buffer, size_t buff_size) {uint8_t data[SSD1306_WIDTH * 2] = {0};for (size_t i = 0; i < buff_size; i++) {data[i*2] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT;data[i*2+1] = buffer[i];}data[(buff_size - 1) * 2] = SSD1306_CTRL_DATA;ssd1306_SendData(data, sizeof(data));
}#elif defined(SSD1306_USE_SPI)void ssd1306_Reset(void) {// CS = High (not selected)HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET);// Reset the OLEDHAL_GPIO_WritePin(SSD1306_Reset_Port, SSD1306_Reset_Pin, GPIO_PIN_RESET);HAL_Delay(10);HAL_GPIO_WritePin(SSD1306_Reset_Port, SSD1306_Reset_Pin, GPIO_PIN_SET);HAL_Delay(10);
}// Send a byte to the command register
void ssd1306_WriteCommand(uint8_t byte) {HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_RESET); // select OLEDHAL_GPIO_WritePin(SSD1306_DC_Port, SSD1306_DC_Pin, GPIO_PIN_RESET); // commandHAL_SPI_Transmit(&SSD1306_SPI_PORT, (uint8_t *) &byte, 1, HAL_MAX_DELAY);HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET); // un-select OLED
}// Send data
void ssd1306_WriteData(uint8_t* buffer, size_t buff_size) {HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_RESET); // select OLEDHAL_GPIO_WritePin(SSD1306_DC_Port, SSD1306_DC_Pin, GPIO_PIN_SET); // dataHAL_SPI_Transmit(&SSD1306_SPI_PORT, buffer, buff_size, HAL_MAX_DELAY);HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET); // un-select OLED
}#else
#error "You should define SSD1306_USE_SPI or SSD1306_USE_I2C macro"
#endif// Screenbuffer
static uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE];// Screen object
static SSD1306_t SSD1306;/* Fills the Screenbuffer with values from a given buffer of a fixed length */
SSD1306_Error_t ssd1306_FillBuffer(uint8_t* buf, uint32_t len) {SSD1306_Error_t ret = SSD1306_ERR;if (len <= SSD1306_BUFFER_SIZE) {memcpy(SSD1306_Buffer,buf,len);ret = SSD1306_OK;}return ret;
}// Initialize the oled screen
void ssd1306_Init(void) {// Reset OLEDssd1306_Reset();// Wait for the screen to bootHAL_Delay(100);// Init OLEDssd1306_SetDisplayOn(0); //display offssd1306_WriteCommand(0x20); //Set Memory Addressing Modessd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode;// 10b,Page Addressing Mode (RESET); 11b,Invalidssd1306_WriteCommand(0xB0); //Set Page Start Address for Page Addressing Mode,0-7#ifdef SSD1306_MIRROR_VERTssd1306_WriteCommand(0xC0); // Mirror vertically
#elsessd1306_WriteCommand(0xC8); //Set COM Output Scan Direction
#endifssd1306_WriteCommand(0x00); //---set low column addressssd1306_WriteCommand(0x10); //---set high column addressssd1306_WriteCommand(0x40); //--set start line address - CHECKssd1306_SetContrast(0xFF);#ifdef SSD1306_MIRROR_HORIZssd1306_WriteCommand(0xA0); // Mirror horizontally
#elsessd1306_WriteCommand(0xA1); //--set segment re-map 0 to 127 - CHECK
#endif#ifdef SSD1306_INVERSE_COLORssd1306_WriteCommand(0xA7); //--set inverse color
#elsessd1306_WriteCommand(0xA6); //--set normal color
#endif// Set multiplex ratio.
#if (SSD1306_HEIGHT == 128)// Found in the Luma Python lib for SH1106.ssd1306_WriteCommand(0xFF);
#elsessd1306_WriteCommand(0xA8); //--set multiplex ratio(1 to 64) - CHECK
#endif#if (SSD1306_HEIGHT == 32)ssd1306_WriteCommand(0x1F); //
#elif (SSD1306_HEIGHT == 64)ssd1306_WriteCommand(0x3F); //
#elif (SSD1306_HEIGHT == 128)ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too.
#else
#error "Only 32, 64, or 128 lines of height are supported!"
#endifssd1306_WriteCommand(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentssd1306_WriteCommand(0xD3); //-set display offset - CHECKssd1306_WriteCommand(0x00); //-not offsetssd1306_WriteCommand(0xD5); //--set display clock divide ratio/oscillator frequencyssd1306_WriteCommand(0xF0); //--set divide ratiossd1306_WriteCommand(0xD9); //--set pre-charge periodssd1306_WriteCommand(0x11); // 0x22 by defaultssd1306_WriteCommand(0xDA); //--set com pins hardware configuration - CHECK
#if (SSD1306_HEIGHT == 32)ssd1306_WriteCommand(0x02);
#elif (SSD1306_HEIGHT == 64)ssd1306_WriteCommand(0x12);
#elif (SSD1306_HEIGHT == 128)ssd1306_WriteCommand(0x12);
#else
#error "Only 32, 64, or 128 lines of height are supported!"
#endifssd1306_WriteCommand(0xDB); //--set vcomhssd1306_WriteCommand(0x30); //0x20,0.77xVcc, 0x30,0.83xVccssd1306_WriteCommand(0x8D); //--set DC-DC enablessd1306_WriteCommand(0x14); //ssd1306_SetDisplayOn(1); //--turn on SSD1306 panel// Clear screenssd1306_Fill(Black);// Flush buffer to screenssd1306_UpdateScreen();// Set default values for screen objectSSD1306.CurrentX = 0;SSD1306.CurrentY = 0;SSD1306.Initialized = 1;
}// Fill the whole screen with the given color
void ssd1306_Fill(SSD1306_COLOR color) {/* Set memory */uint32_t i;for(i = 0; i < sizeof(SSD1306_Buffer); i++) {SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF;}
}// Write the screenbuffer with changed to the screen
void ssd1306_UpdateScreen(void) {// Write data to each page of RAM. Number of pages// depends on the screen height:////  * 32px   ==  4 pages//  * 64px   ==  8 pages//  * 128px  ==  16 pagesuint8_t cmd[] = {0X21,   // 设置列起始和结束地址0X00,   // 列起始地址 00X7F,   // 列终止地址 1270X22,   // 设置页起始和结束地址0X00,   // 页起始地址 00X07,   // 页终止地址 7};uint32_t count = 0;uint8_t data[sizeof(cmd)*2 + SSD1306_BUFFER_SIZE + 1] = {};// copy cmdfor (uint32_t i = 0; i < sizeof(cmd)/sizeof(cmd[0]); i++) {data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT;data[count++] = cmd[i];}// copy frame datadata[count++] = SSD1306_CTRL_DATA;memcpy(&data[count], SSD1306_Buffer, sizeof(SSD1306_Buffer));count += sizeof(SSD1306_Buffer);// send to i2c busuint32_t retval = ssd1306_SendData(data, count);// if (retval != WIFI_IOT_SUCCESS) {code-2.0-canary,新添加的。txwtechif (retval != HI_ERR_SUCCESS) {printf("ssd1306_UpdateScreen send frame data filed: %d!\r\n", retval);}
}//    Draw one pixel in the screenbuffer
//    X => X Coordinate
//    Y => Y Coordinate
//    color => Pixel color
void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) {if(x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) {// Don't write outside the bufferreturn;}// Check if pixel should be invertedif(SSD1306.Inverted) {color = (SSD1306_COLOR)!color;}// Draw in the right colorif(color == White) {SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8);} else {SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8));}
}// Draw 1 char to the screen buffer
// ch       => char om weg te schrijven
// Font     => Font waarmee we gaan schrijven
// color    => Black or White
char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) {uint32_t i, b, j;// Check if character is validif (ch < 32 || ch > 126)return 0;// Check remaining space on current lineif (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) ||SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)){// Not enough space on current linereturn 0;}// Use the font to writefor(i = 0; i < Font.FontHeight; i++) {b = Font.data[(ch - 32) * Font.FontHeight + i];for(j = 0; j < Font.FontWidth; j++) {if((b << j) & 0x8000)  {ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR) color);} else {ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color);}}}// The current space is now takenSSD1306.CurrentX += Font.FontWidth;// Return written char for validationreturn ch;
}// Write full string to screenbuffer
char ssd1306_DrawString(char* str, FontDef Font, SSD1306_COLOR color) {// Write until null-bytewhile (*str) {if (ssd1306_DrawChar(*str, Font, color) != *str) {// Char could not be writtenreturn *str;}// Next charstr++;}// Everything okreturn *str;
}// Position the cursor
void ssd1306_SetCursor(uint8_t x, uint8_t y) {SSD1306.CurrentX = x;SSD1306.CurrentY = y;
}// Draw line by Bresenhem's algorithm
void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) {int32_t deltaX = abs(x2 - x1);int32_t deltaY = abs(y2 - y1);int32_t signX = ((x1 < x2) ? 1 : -1);int32_t signY = ((y1 < y2) ? 1 : -1);int32_t error = deltaX - deltaY;int32_t error2;ssd1306_DrawPixel(x2, y2, color);while((x1 != x2) || (y1 != y2)){ssd1306_DrawPixel(x1, y1, color);error2 = error * 2;if(error2 > -deltaY){error -= deltaY;x1 += signX;}else{/*nothing to do*/}if(error2 < deltaX){error += deltaX;y1 += signY;}else{/*nothing to do*/}}return;
}
//Draw polyline
void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color) {uint16_t i;if(par_vertex != 0){for(i = 1; i < par_size; i++){ssd1306_DrawLine(par_vertex[i - 1].x, par_vertex[i - 1].y, par_vertex[i].x, par_vertex[i].y, color);}}else{/*nothing to do*/}return;
}
/*Convert Degrees to Radians*/
static float ssd1306_DegToRad(float par_deg) {return par_deg * 3.14 / 180.0;
}
/*Normalize degree to [0;360]*/
static uint16_t ssd1306_NormalizeTo0_360(uint16_t par_deg) {uint16_t loc_angle;if(par_deg <= 360){loc_angle = par_deg;}else{loc_angle = par_deg % 360;loc_angle = ((par_deg != 0)?par_deg:360);}return loc_angle;
}
/*DrawArc. Draw angle is beginning from 4 quart of trigonometric circle (3pi/2)* start_angle in degree* sweep in degree*/
void ssd1306_DrawArc(uint8_t x, uint8_t y, uint8_t radius, uint16_t start_angle, uint16_t sweep, SSD1306_COLOR color) {#define CIRCLE_APPROXIMATION_SEGMENTS 36float approx_degree;uint32_t approx_segments;uint8_t xp1,xp2;uint8_t yp1,yp2;uint32_t count = 0;uint32_t loc_sweep = 0;float rad;loc_sweep = ssd1306_NormalizeTo0_360(sweep);count = (ssd1306_NormalizeTo0_360(start_angle) * CIRCLE_APPROXIMATION_SEGMENTS) / 360;approx_segments = (loc_sweep * CIRCLE_APPROXIMATION_SEGMENTS) / 360;approx_degree = loc_sweep / (float)approx_segments;while(count < approx_segments){rad = ssd1306_DegToRad(count*approx_degree);xp1 = x + (int8_t)(sin(rad)*radius);yp1 = y + (int8_t)(cos(rad)*radius);count++;if(count != approx_segments){rad = ssd1306_DegToRad(count*approx_degree);}else{rad = ssd1306_DegToRad(loc_sweep);}xp2 = x + (int8_t)(sin(rad)*radius);yp2 = y + (int8_t)(cos(rad)*radius);ssd1306_DrawLine(xp1,yp1,xp2,yp2,color);}return;
}
//Draw circle by Bresenhem's algorithm
void ssd1306_DrawCircle(uint8_t par_x,uint8_t par_y,uint8_t par_r,SSD1306_COLOR par_color) {int32_t x = -par_r;int32_t y = 0;int32_t err = 2 - 2 * par_r;int32_t e2;if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) {return;}do {ssd1306_DrawPixel(par_x - x, par_y + y, par_color);ssd1306_DrawPixel(par_x + x, par_y + y, par_color);ssd1306_DrawPixel(par_x + x, par_y - y, par_color);ssd1306_DrawPixel(par_x - x, par_y - y, par_color);e2 = err;if (e2 <= y) {y++;err = err + (y * 2 + 1);if(-x == y && e2 <= x) {e2 = 0;}else{/*nothing to do*/}}else{/*nothing to do*/}if(e2 > x) {x++;err = err + (x * 2 + 1);}else{/*nothing to do*/}} while(x <= 0);return;
}//Draw rectangle
void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) {ssd1306_DrawLine(x1,y1,x2,y1,color);ssd1306_DrawLine(x2,y1,x2,y2,color);ssd1306_DrawLine(x2,y2,x1,y2,color);ssd1306_DrawLine(x1,y2,x1,y1,color);return;
}void ssd1306_DrawBitmap(const uint8_t* bitmap, uint32_t size)
{uint8_t rows = size * 8 / SSD1306_WIDTH;if (rows > SSD1306_HEIGHT) {rows = SSD1306_HEIGHT;}for (uint8_t y = 0; y < rows; y++) {for (uint8_t x = 0; x < SSD1306_WIDTH; x++) {uint8_t byte = bitmap[(y * SSD1306_WIDTH / 8) + (x / 8)];uint8_t bit = byte & (0x80 >> (x % 8));ssd1306_DrawPixel(x, y, bit ? White : Black);}}
}void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t* data, uint32_t size, uint32_t stride)
{if (x + w > SSD1306_WIDTH || y + h > SSD1306_HEIGHT || w * h == 0) {printf("%dx%d @ %d,%d out of range or invalid!\r\n", w, h, x, y);return;}w = (w <= SSD1306_WIDTH ? w : SSD1306_WIDTH);h = (h <= SSD1306_HEIGHT ? h : SSD1306_HEIGHT);stride = (stride == 0 ? w : stride);uint8_t rows = size * 8 / stride;for (uint8_t i = 0; i < rows; i++) {uint32_t base = i * stride / 8;for (uint8_t j = 0; j < w; j++) {uint32_t idx = base + (j / 8);uint8_t byte = idx < size ? data[idx] : 0;uint8_t bit  = byte & (0x80 >> (j % 8));ssd1306_DrawPixel(x + j, y + i, bit ? White : Black);}}
}void ssd1306_SetContrast(const uint8_t value) {const uint8_t kSetContrastControlRegister = 0x81;ssd1306_WriteCommand(kSetContrastControlRegister);ssd1306_WriteCommand(value);
}void ssd1306_SetDisplayOn(const uint8_t on) {uint8_t value;if (on) {value = 0xAF;   // Display onSSD1306.DisplayOn = 1;} else {value = 0xAE;   // Display offSSD1306.DisplayOn = 0;}ssd1306_WriteCommand(value);
}uint8_t ssd1306_GetDisplayOn() {return SSD1306.DisplayOn;
}

app/build.gn

# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.import("//build/lite/config/component/lite_component.gni")lite_component("app") {features = ["ssd1306:oled_ssd1306","examples:oled_test","libm_port:libm_port"]
}

c_cpp_properties.json

{"configurations": [{"name": "!!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT"},{"name": "Win32-debug","includePath": [//"F:/code-2.0-canary/include","F:/code-2.0-canary/src","F:/utils/native/lite/include","F:/domains/iot/link/libbuild","F:/base/iot_hardware/peripheral/interfaces/kits","F:/third_party/cmsis/CMSIS/RTOS2/Include","F:/code-2.0-canary/device/hisilicon/hispark_pegasus/sdk_liteos/include","F:/code-2.0-canary/applications/sample/wifi-iot/app/ssd1306","F:/code-2.0-canary/applications/sample/wifi-iot/app/libm_port",//"F:/code-2.0-canary/third_party/mingw-w64/mingw-w64-headers/crt",""],"browse": {"limitSymbolsToIncludedHeaders": true,"path": ["F:/code-2.0-canary/include","F:/code-2.0-canary/src","F:/code-2.0-canary/utils/native/lite/include",""]},"defines": [""],"intelliSenseMode": "clang-x64","compilerPath": "F:/hcc_riscv32_win/bin/riscv32-unknown-elf-gcc.exe","compilerArgs": [""]}],"version": 4
}

鸿蒙开发板Hi3861_驱动0.95_oled显示屏ssd1306_code-2.0-CANARY_双显示屏效果相关推荐

  1. 鸿蒙开发板HI3861 利用蜂鸣器播放音乐 open Harmony1.0.0(附cmsis_os2.h源码)

    本文利用鸿蒙开发板HI3861在鸿蒙1.0.0源码下利用蜂鸣器播放音乐. pwm_buz.c #include <stdio.h> #include "ohos_init.h&q ...

  2. 鸿蒙开发板Hi3861_通过GPIO12 PWM蜂鸣器播放<涛声依旧>-——基于code-2.0-CANARY

    //通过PWM蜂鸣器实验-A12连接, A12接长脚,蜂鸣器短脚接GND 编译报错参考: https://blog.csdn.net/txwtech/article/details/119853772 ...

  3. 鸿蒙开发板Hi3861模拟SPI驱动JLX12864_LCD(UC1701X)_基于code-2.0

    鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码-C文档类资源-CSDN下载鸿蒙开发板驱动晶联讯LCDjlx12864_lcd_hi3861源码博文介绍https://t更多下载资 ...

  4. 鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920_基于code-2.0-CANARY

    鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar-C文档类资源-CSDN下载鸿蒙开发板Hi3861模拟SPI驱动12864LCD_ST7920源码.rar博文链接:htt ...

  5. 鸿蒙开发板hi3861 hispark code 2.0 canary金丝雀版本,gpio如何上拉电阻呢?

    鸿蒙开发板hi3861 hispark code 2.0 canary金丝雀版本,gpio如何上拉电阻呢? code 2.0 LTS支持,canary没有这个功能呢 IoSetPull(WIFI_IO ...

  6. 龙芯智龙开发板:驱动步进电机实战入门

    本文面向初学者,请多各位高手包涵.我在此特别致谢勤为本先生为我提供的帮助. 步进电机 步进电机就是一种受脉冲控制的电机,步进电机接收到一系列某种调制顺序的脉冲,做出相应的反应,转到相应的角度或者相应的 ...

  7. 电脑客户端遥控鸿蒙开发板执行相应命令

    电脑端遥控控制鸿蒙开发板 项目需求 开发环境 使用的技术 UDP JSON JSON介绍 JSON 语法规则 具体设计 功能介绍 电脑客户端 页面设计 程序代码 MCU端 搭建的模块 主要代码 后续 ...

  8. 小表妹想学鸿蒙(HarmonyOS)开发板,于是我翻出了所有的鸿蒙开发板,靠,全给我抢走了,简直是野蛮表妹!

    目录 1. Neptune(海王星开发板) 2. HiSpark3861开发板 3. 小熊派(Hi3861芯片) 4. HiSpark 3518开发板 5. HiSpark 3516开发板 总结: 小 ...

  9. RK系列开发板音频驱动适配指南(二)

    背景: 上一篇文章RK系列开发板音频驱动适配指南-DAI模块适配中已经阐述音频驱动适配的DAI模块适配步骤以及核心代码的展示,本次主要介绍音频驱动适配中的DMA模块适配. RK系列开发板 DMA模块适 ...

  10. RK系列开发板音频驱动适配指南(一)

    背景: 多媒体系统目前在Linux操作系统,windows操作系统已经非常成熟,并且应用场景广泛,但是,基于OpenAtom OpenHarmony(以下简称"OpenHarmony&quo ...

最新文章

  1. 图像/视频去噪算法资源集锦
  2. jQuery版AJAX简易封装
  3. Visual Studio 2019更新到16.1.4
  4. python sql解析引擎_python SQLAlchemy 中的Engine详解
  5. vscode 配置php
  6. 使用PreloadJS加载图片资源
  7. Step-by-step to LSTM: 解析LSTM神经网络设计原理
  8. 苹果宣布将把语音助手Siri整合到Apple Music服务中
  9. 使用python搭配pandoc实现html批量转word
  10. C# 在采集数据时的验证与登录处理
  11. Java自学要多久?
  12. 平面杆系结构有限元分析C++程序设计思路
  13. 学习笔记图片从本地复制到csdn博客出现:外链图片转存失败:解决方法
  14. 大数据营销——构建数据价值分享模式
  15. 乱弹集锦:火柴棍艺术大神
  16. 微信公众号文章怎么插附件
  17. 手把手教你实现百度基础地图+定位功能+设置中心点+添加Marker
  18. Redis的常用应用场景
  19. android下的XMPP对应smack-4.2.1,实现登录,注册,发单聊,加聊天室,发群聊等简单功能
  20. 使用java获取硬盘序列号

热门文章

  1. 王道训练营3月24日
  2. go get失败时怎么办(golang.org/x/crypto/md4为例)
  3. kafka与zookeeper下载安装及kafka常用命令
  4. c语言取反运算详细步骤,C语言取反运算~
  5. access 数据库模糊查询
  6. web前端开发技术实验与实践(第三版)储久良编著 课外拓展训练5.2 HTML5是如何起步的
  7. 金蝶基础资料中物料信息中的计价方法详细解释!小白不能让客户虎住,多多了解
  8. SRIO的介绍和IP核解析
  9. 基于Echarts的图表绘制
  10. termux python turtle库_Python之Turtle库