香橙派KunpengPro测评之使用C语言操控40pin引脚

香橙派KunpengPro测评之使用C语言操控40pin引脚

  • 香橙派KunpengPro介绍
    • 香橙派实物图
    • 香橙派登录界面
      • 香橙派KunpengPro的登录界面
      • 香橙派KunpengPro的原始桌面
      • 香橙派KunpengPro内安装了VScode等软件
      • 香橙派KunpengPro的终端
    • 香橙派硬件参数
      • 核心性能
      • 图形与显示
      • 接口丰富性
      • 扩展与兼容性
      • 软件与应用生态
  • 香橙派KunpengPro搭建环境
    • 下载镜像和烧录镜像工具
      • 官方工具下载
    • 烧录镜像
      • 快速格式化TF卡
      • 烧录香橙派KunpengPro的镜像
    • 香橙派KunpengPro登录
      • 串口登录
      • 连接WiFi进行SSH登录
  • 香橙派KunpengPro使用C语言驱动40pin引脚
    • 方法1:使用system函数调用官方用户手册给出的命令
      • gpio_operate -h 命令
      • gpio_operate get_direction gpio_group gpio_pin 命令
      • gpio_operate set_direction gpio_group gpio_pin direction命令
      • gpio_operate get_value gpio_group gpio_pin 命令
      • gpio_operate set_value gpio_group gpio_pin value 命令
    • 方法2:使用我提供的gpioControl.c和gpioControl.h文件
      • gpio控制源文件
      • 调用GPIO控制函数控制蜂鸣器发出警报或LED闪烁
      • 驱动OLED屏幕
  • 香橙派KunpengPro配置开机自启动使用OLED屏幕显示IP地址
    • 写一个自动获取IP的程序
      • 文件列表
      • gpio_control.c和gpio_control.h
      • clear.c和可执行文件clear
      • oled.c和oled.h
      • server.c和server.h
      • mainPro.c和mainPro.h
      • 与QT上位机的交互
    • 创建一个开机自启动服务
      • 创建一个自启动服务文件
      • 重新加载 systemd 配置并启用服务
      • 查看服务是否成功开启
      • 重新启动服务,并查看服务状态
  • 体验总结

香橙派KunpengPro介绍

香橙派鲲鹏Pro是一款高性能开发板,搭载4核64位鲲鹏处理器与AI加速器,提供8/16GB LPDDR4X内存及多种存储扩展选项。它配备双HDMI输出、M.2插槽、USB 3.0/Type-C接口等,支持4K视频、高速数据传输及网络连接。预装openEuler操作系统,适合AI研发、云计算、大数据处理等应用场景,凭借其强大的性能与灵活扩展性,成为教育、开发及创新项目的优选平台。
在这里插入图片描述

香橙派实物图

香橙派KunpengPro正面图
在这里插入图片描述
香橙派KunpengPro反面图
在这里插入图片描述
香橙派KunpengPro左侧面图
在这里插入图片描述
香橙派KunpengPro右侧面图
在这里插入图片描述

香橙派登录界面

香橙派KunpengPro的登录界面

在这里插入图片描述

香橙派KunpengPro的原始桌面

在这里插入图片描述

香橙派KunpengPro内安装了VScode等软件

在这里插入图片描述

香橙派KunpengPro的终端

在这里插入图片描述

香橙派硬件参数

OrangePi Kunpeng Pro是一款高性能、高扩展性的单板计算机,专为需要强大AI算力、高速数据处理及多场景应用开发的用户设计,提供了从硬件到软件的全面解决方案。

核心性能

  • 处理器架构:搭载4核64位处理器,集成了专门的AI处理单元,针对人工智能任务优化。
  • AI算力:支持高达8TOPS(Tera Operations Per Second)的AI运算能力,适合机器学习与深度学习应用。
  • 存储扩展:可通过外接eMMC模块扩展存储,支持32GB至256GB不同容量,满足不同存储需求。
  • 内存配置:配备高端的8GB/16GB LPDDR4X内存,确保流畅的数据处理和运行效率。

图形与显示

  • 图形处理:集成高效图形处理器,强化视觉处理与高清输出能力。
  • 视频输出:支持双路4K高清视频输出,适用于多屏展示或高分辨率监控系统。

接口丰富性

  • 外部连接:提供全面的接口选项,包括双HDMI、GPIO、Type-C电源输入、M.2插槽(兼容SATA/NVMe SSD)、TF卡插槽、千兆以太网口、多个USB端口(含USB3.0及USB Type-C 3.0)、Micro USB(具备串口打印调试功能)。
  • 多媒体支持:配备MIPI接口,支持连接摄像头与显示屏,拓展物联网与视觉项目应用。

扩展与兼容性

  • M.2插槽:特别提及的M.2 2280插槽,支持快速SSD,提升系统响应速度与数据传输效率。
  • 电池接口预留:便于移动设备改造或低功耗应用的开发需求。

软件与应用生态

  • 操作系统:兼容openEuler操作系统,为开发者提供稳定且开源的操作环境。
  • 应用场景:广泛适用于AI算法验证、推理应用开发,以及云计算、大数据处理、分布式存储和高性能计算等领域,展现了其作为高性能计算平台的潜力。

香橙派KunpengPro搭建环境

准备的工具有内存32G以上的高速闪迪TF卡、一个读卡器、香橙派KunpengPro镜像、香橙派KunpengPro镜像烧录工具、HDMI显示屏和HDMI转HDMI线或者使用一根Micro数据线进行串口登录。

下载镜像和烧录镜像工具

打开香橙派官网http://www.orangepi.cn/,选择开源硬件中的开发板,选择OrangePi Kunpeng Pro。
在这里插入图片描述
点击下载
在这里插入图片描述
需要下载下面这三个内容
在这里插入图片描述

官方工具下载

官方工具下载下面这几个就够用了。
在这里插入图片描述

烧录镜像

快速格式化TF卡

将TF卡插入读卡器,插到电脑的USB口中,并打开格式化工具SDCardFormatter进行快速格式化。
在这里插入图片描述

烧录香橙派KunpengPro的镜像

选择目标镜像和目标TF卡。
在这里插入图片描述

开始烧录。
在这里插入图片描述
烧录完成后,把TF卡插到香橙派KunpengPro开发板上,并接上Micro数据线,先不接通电源。

香橙派KunpengPro登录

串口登录

接上Micro数据线,在设备管理器查看COM口。
在这里插入图片描述
使用MobaXterm软件建立串口连接。
在这里插入图片描述
串口号选择设备管理器对应的,波特率选择115200。
在这里插入图片描述
流控制选择NONE。
在这里插入图片描述
插上电源,查看登录日志。
在这里插入图片描述
输入账号:openEuler,密码:openEuler进行登录。
在这里插入图片描述

连接WiFi进行SSH登录

sudo nmcli dev wifi,扫描香橙派KunpengPro附近的WiFi。
在这里插入图片描述
sudo nmcli dev wifi connect 用户名 password 密码,连接WiFi。
在这里插入图片描述
ifconfig,查看IP地址。
在这里插入图片描述
建立SSH连接
在这里插入图片描述
输入密码,选择No,就可以SSH登录香橙派KunpengPro了。
在这里插入图片描述

香橙派KunpengPro使用C语言驱动40pin引脚

众所周知,香橙派、树莓派等Linux开发板操控引脚使用最多的方法便是利用wiringPi库,本次测评的香橙派KunpengPro本来也是打算使用wiringOP库进行操控引脚,但是香橙派KunpengPro这块开发板还未适配wiringOP库,所以只能使用其他的方法来操控GPIO口。

方法1:使用system函数调用官方用户手册给出的命令

这个方法不太推荐,有兴趣的小伙伴可以了解一下,必须要以root账户去执行这些操控GPIO口的命令。

gpio_operate -h 命令

gpio_operate -h 命令可以获取 gpio_operate 工具的帮助信息在这里插入图片描述

gpio_operate get_direction gpio_group gpio_pin 命令

gpio_operate get_direction gpio_group gpio_pin 命令用于查询 GPIO 管脚方向。
在这里插入图片描述
value的值是0,该引脚就是输入引脚,value的值是1,该引脚就是输出引脚,
在这里插入图片描述

在这里插入图片描述

gpio_operate set_direction gpio_group gpio_pin direction命令

gpio_operate set_direction gpio_group gpio_pin direction 用于设置 GPIO 管脚方向。
在这里插入图片描述
在这里插入图片描述

gpio_operate get_value gpio_group gpio_pin 命令

gpio_operate get_value gpio_group gpio_pin 命令用于查询 GPIO 管脚值。
在这里插入图片描述
查询到value的值是0,那么引脚电平就是低电平,查询到value的值是1,那么引脚电平就是高电平。
在这里插入图片描述

gpio_operate set_value gpio_group gpio_pin value 命令

gpio_operate set_value gpio_group gpio_pin value 命令用于设置 GPIO 管脚值为高电平或者低电平。
在这里插入图片描述
在这里插入图片描述

方法2:使用我提供的gpioControl.c和gpioControl.h文件

使用这两个文件,只需要调用相应的函数,就可以控制IO口的输入、输出方向,输出高低电平等等功能,而且减少了系统调用,增加了代码的健壮性,话不多说,直接上代码

gpio控制源文件

gpioControl.c

void write_to_file(const char *filename, const char *value)
{int fd = open(filename, O_WRONLY);if (fd < 0){perror("open");exit(EXIT_FAILURE);}if (write(fd, value, strlen(value)) < 0){perror("write");exit(EXIT_FAILURE);}close(fd);
}void gpio_export(int pin)
{char buffer[4];snprintf(buffer, sizeof(buffer), "%d", pin);write_to_file(GPIO_EXPORT, buffer);usleep(100000); // 等待GPIO初始化完成
}void gpio_unexport(int pin)
{char buffer[4];snprintf(buffer, sizeof(buffer), "%d", pin);write_to_file(GPIO_UNEXPORT, buffer);
}void gpio_set_direction_in(int pin)
{char path[50];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "direction");write_to_file(path, "in");
}void gpio_set_direction_outMode(int pin)
{char path[50];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "direction");write_to_file(path, "out");
}void gpio_set_direction_out(int pin, GPIO_Value value)
{char path[50];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "direction");write_to_file(path, "out");snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "value");write_to_file(path, value == HIGH ? "1" : "0");
}int gpio_get_value(int pin)
{char path[50];char value_str[3];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "value");int fd = open(path, O_RDONLY);if (fd < 0){perror("open");exit(EXIT_FAILURE);}if (read(fd, value_str, sizeof(value_str)) < 0){perror("read");exit(EXIT_FAILURE);}close(fd);return atoi(value_str);
}

gpioControl.h

#ifndef GPIO_CONTROL_H
#define GPIO_CONTROL_H#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>#define GPIO_PATH_FORMAT "/sys/class/gpio/gpio%d/%s"
#define GPIO_EXPORT "/sys/class/gpio/export"
#define GPIO_UNEXPORT "/sys/class/gpio/unexport"typedef enum {LOW = 0,HIGH = 1
} GPIO_Value;// 导出GPIO引脚
void gpio_export(int pin);// 取消导出GPIO引脚
void gpio_unexport(int pin);// 设置GPIO引脚为输入模式
void gpio_set_direction_in(int pin);// 设置GPIO引脚为输出模式
void gpio_set_direction_outMode(int pin);// 设置GPIO引脚为输出模式并设置电平
void gpio_set_direction_out(int pin, GPIO_Value value);// 读取GPIO引脚的状态
int gpio_get_value(int pin);#endif // GPIO_CONTROL_H

调用GPIO控制函数控制蜂鸣器发出警报或LED闪烁

利用gpioControl.c和gpioControl.h文件,我们可以轻松的控制IO口输出高低电平或读取输入电平。查看官方用户手册的引脚图,我们发现左边倒数第二根引脚,也就是第37号引脚的GPIO序号是3,所以在代码中,我们使用的引脚序号应该是3而不是37。
在这里插入图片描述
buzzer.c

#include <stdio.h>
#include "gpio_control.h"int main() {int pin = 3;  // 对应第37号引脚// 导出GPIO引脚gpio_export(pin);// 循环控制GPIO高低电平for (int i = 0; i < 3; i++) {gpio_set_direction_out(pin, HIGH); // 设置为高电平sleep(1);                          // 延时1sgpio_set_direction_out(pin, LOW);  // 设置为低电平sleep(1);                          // 延时1s}// 取消导出GPIO引脚gpio_unexport(pin);return 0;
}

此时,可以听到蜂鸣器每间接性响动,如果到了这步不能成功的话,大概率是因为你们之前下载了wiringOP这个库,导致引脚映射失败了,建议跟着前面的教程重新刷openEuler的镜像。

驱动OLED屏幕

有了前面操控引脚输出高低电平的方法后,现在只要操控引脚读取电平状态就能软件模拟IIC引脚,从而驱动OLED屏幕。这个使用C语言操控40pin引脚的方法不用安装任何库和配置环境,只需要上述代码就能随意操控IO口,使用左边倒数第四根引脚作为IIC_SCL引脚,即GPIO序号是128,左边倒数第2根作为IIC_SDA引脚,即GPIO序号是3。
oled.c

#include "oled.h"int pin_scl = 128;
int pin_sda = 3;/************************************6*8的点阵************************************/
const unsigned F6x8[][6] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // "0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // #0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // %0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // &0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // '0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // (0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // )0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // *0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // +0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // ,0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // -0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // .0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // /0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 00x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 10x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 20x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 30x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 40x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 50x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 60x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 70x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 80x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 90x00, 0x00, 0x36, 0x36, 0x00, 0x00, // :0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ;0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // <0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // =0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // >0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ?0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // 550x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ]0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // '0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // horiz lines
};/****************************************8*16的点阵************************************/
unsigned char F8X16[] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 00x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 10x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 20x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 30x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 40xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 50x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 60x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 70x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 80x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 90x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 100x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 140x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 150x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 160x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 170x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 180x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 190x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 200x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 210x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 220x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 230x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 240x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 250x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 260x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 270x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 280x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 290x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 300x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 310xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 320x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 330x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 340xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 350x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 360x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 370x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 380xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 390x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 400x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 410x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 420x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 430x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 440x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 450x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 460xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 470x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 480xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 490x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 500x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 510x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 520x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 530x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 540xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 550x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 560x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 570x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 580x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 590x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 600x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 610x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 630x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 640x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 650x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 660x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 670x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 680x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 690x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 700x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 710x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 720x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 730x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 740x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 750x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 760x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 770x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 780x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 790x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 800x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 810x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 820x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 830x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 840x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 850x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 860x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 870x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 880x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 890x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 900x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 910x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 920x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 930x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
};void OLED_I2C_Delay(unsigned int t)
{usleep(t);
}void OLED_I2C_Start(void)
{gpio_set_direction_outMode(pin_sda);OLED_SDA_HIGH; // 发送起始条件的数据信号OLED_SCL_HIGH;OLED_I2C_Delay(5); // 起始条件建立时间大于4.7us,延时OLED_SDA_LOW;      // 发送起始信号OLED_I2C_Delay(5); // 起始条件锁定时间大于4μsOLED_SCL_LOW;      // 钳住I2C总线,准备发送或接收数据OLED_I2C_Delay(5);
}void OLED_I2C_Stop(void)
{gpio_set_direction_outMode(pin_sda);OLED_SDA_LOW; // 发送结束条件的数据信号OLED_SCL_LOW;OLED_I2C_Delay(5);OLED_SCL_HIGH;     // 发送结束条件的时钟信号OLED_I2C_Delay(5); // 结束条件建立时间大于4μsOLED_SDA_HIGH;     // 发送I2C总线结束信号OLED_I2C_Delay(5);
}unsigned char OLED_I2C_Write_Byte(unsigned char writeByte)
{unsigned char i;gpio_set_direction_outMode(pin_sda);OLED_SCL_LOW;OLED_I2C_Delay(5);for (i = 0; i < 8; i++) // 要传送的数据长度为8位{if (writeByte & 0x80) // 判断发送位{OLED_SDA_HIGH;}else{OLED_SDA_LOW;}OLED_I2C_Delay(5);OLED_SCL_HIGH;     // 输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样OLED_I2C_Delay(5); // 保证时钟高电平周期大于4μsOLED_SCL_LOW;OLED_I2C_Delay(5);writeByte <<= 1;}OLED_I2C_Delay(1);OLED_SDA_HIGH; // 8位发送完后释放数据线,准备接收应答位-ZLGOLED_I2C_Delay(5);OLED_SCL_HIGH; // MCU告知SHT2X数据发送完毕,等待从机的应答信号OLED_I2C_Delay(5);gpio_set_direction_in(pin_sda);/*以下是判断I2C总线接收应到应答信号是ACK还是NACK*/if (gpio_get_value(pin_sda) == 1) // SDA为高,收到NACK{OLED_I2C_Delay(5);OLED_SCL_LOW;return NACK;}else // SDA为低,收到ACK{OLED_I2C_Delay(5);OLED_SCL_LOW;return ACK;}
}unsigned char OLED_I2C_Read_Byte(unsigned char ackValue)
{unsigned char i = 0;unsigned char readByte = 0;gpio_set_direction_outMode(pin_sda);OLED_SCL_LOW; // 置时钟线为低,准备接收数据位OLED_I2C_Delay(5);OLED_SDA_HIGH; // 释放总线,置数据线为输入方式gpio_set_direction_in(pin_sda);for (i = 0; i < 8; i++){OLED_SCL_HIGH; // SCL高电平期间,采集SDA信号,并作为有效数据 //置时钟线为高使数据线上数据有效OLED_I2C_Delay(5);readByte <<= 1;                 // 移位if (gpio_get_value(pin_sda) == 1) // 采样获取数据{readByte |= 0x01;}else{readByte &= 0xfe;}OLED_I2C_Delay(5);OLED_SCL_LOW; // 下降沿,从机给出下一位值OLED_I2C_Delay(5);}gpio_set_direction_outMode(pin_sda);/*以下是I2C总线发送应答信号ACK或者NACK*/gpio_set_direction_out(pin_sda,ackValue);OLED_I2C_Delay(5);OLED_SCL_HIGH;OLED_I2C_Delay(5); // 时钟低电平周期大于4μsOLED_SCL_LOW;      // 清时钟线,钳住I2C总线以便继续接收OLED_I2C_Delay(5);return readByte;
}// OLED写入一条指令
void oledWriteCmd(char writeCmd)
{OLED_I2C_Start();OLED_I2C_Write_Byte(0x78);OLED_I2C_Write_Byte(0x00);OLED_I2C_Write_Byte(writeCmd);OLED_I2C_Stop();
}void oledWriteData(char writeData)
{OLED_I2C_Start();OLED_I2C_Write_Byte(0x78);OLED_I2C_Write_Byte(0x40);OLED_I2C_Write_Byte(writeData);OLED_I2C_Stop();
}// 更新显存到LCD
void oled_Clear(void)
{unsigned char i, n;for (i = 0; i < 8; i++){oledWriteCmd(0xb0 + i); // 设置页地址(0~7)oledWriteCmd(0x00);     // 设置显示位置—列低地址oledWriteCmd(0x10);     // 设置显示位置—列高地址for (n = 0; n < 130; n++){oledWriteData(0);}}OLED_I2C_Delay(500000);
}// 开启OLED显示
void OLED_Display_On(void)
{oledWriteCmd(0X8D); // SET DCDC命令oledWriteCmd(0X14); // DCDC ONoledWriteCmd(0XAF); // DISPLAY ON
}// 关闭OLED显示
void OLED_Display_Off(void)
{oledWriteCmd(0XAE); // SET DCDC命令oledWriteCmd(0X8D); // DCDC OFFoledWriteCmd(0X10); // DISPLAY OFF
}// 设置光标
void OLED_Set_Pos(unsigned char x, unsigned char y)
{oledWriteCmd(0xB0 + y);oledWriteCmd((x & 0x0f));oledWriteCmd(((x & 0xf0) >> 4) | 0x10);
}// 屏幕初始化函数
void oled_Init(void)
{// 导出GPIO引脚gpio_export(pin_scl);gpio_export(pin_sda);gpio_set_direction_out(pin_scl, HIGH);gpio_set_direction_out(pin_sda, HIGH);oledWriteCmd(0xAE); // 关闭显示oledWriteCmd(0x00); // 设置时钟分频因子,震荡频率oledWriteCmd(0x10); //[3:0],分频因子;[7:4],震荡频率oledWriteCmd(0x40); // 设置驱动路数oledWriteCmd(0xB0); // 默认0X3F(1/64)oledWriteCmd(0x81); // 默认为0oledWriteCmd(0xFF); // 设置显示开始行 [5:0],行数.oledWriteCmd(0xA1); // 电荷泵设置oledWriteCmd(0xA6); // bit2,开启/关闭oledWriteCmd(0xA8); // 设置内存地址模式oledWriteCmd(0x3F); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;oledWriteCmd(0xC8); // 段重定义设置,bit0:0,0->0;1,0->127;oledWriteCmd(0xD3); // 设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数oledWriteCmd(0x00); // 设置COM硬件引脚配置oledWriteCmd(0xD5); //[5:4]配置oledWriteCmd(0x80); // 对比度设置oledWriteCmd(0xD9); // 1~255;默认0X7F (亮度设置,越大越亮)oledWriteCmd(0xF1); // 设置预充电周期oledWriteCmd(0xDA); //[3:0],PHASE 1;[7:4],PHASE 2;oledWriteCmd(0x12); // 设置VCOMH 电压倍率oledWriteCmd(0xDB); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vccoledWriteCmd(0x40); // 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)oledWriteCmd(0x8D); // 设置显示方式;bit0:1,反相显示;0,正常显示oledWriteCmd(0x14); // 开启显示oledWriteCmd(0xAF); // 开启显示 OLED_Clear();OLED_Set_Pos(0, 0);oled_Clear();
}void oled_DeInit(void)
{gpio_unexport(pin_scl);gpio_unexport(pin_sda);
}// 在指定位置显示一个字符,包括部分字符
// x:0~127
// y:0~63
// mode:0,反白显示;1,正常显示
// size:选择字体 16/12
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char chr)
{unsigned char c = 0, i = 0;c = chr - ' ';if (x > Max_Column){x = 0;y = y + 2;}if (SIZE == 16) // ×Ö·û´óСÈç¹ûΪ16 =8 *16{OLED_Set_Pos(x, y); // ´Óx,y¿ªÊ¼»­µãfor (i = 0; i < 8; i++){oledWriteData(F8X16[c * 16 + i]);}OLED_Set_Pos(x, y + 1); // ´Óx,y¿ªÊ¼»­µãfor (i = 0; i < 8; i++){oledWriteData(F8X16[c * 16 + i + 8]);}}else // 6 =6*8{OLED_Set_Pos(x, y);for (i = 0; i < 6; i++)oledWriteData(F6x8[c][i]);}
}// 显示字符串
// x,y:起点坐标
// size:字体大小
//*p:字符串起始地址
void oled_ShowString(unsigned char x, unsigned char y, const unsigned char *chr)
{unsigned char j = 0;while (chr[j] != '\0'){OLED_ShowChar(x, y, chr[j]);x += 8;if (x >= 128){x = 0;y += 2;}j++;}
}void main()
{oled_Init();oled_ShowString(0,0,"jiangxiaoya");oled_DeInit();
}

oled.h

#ifndef OLED_H
#define OLED_H#include <stdio.h>
#include "gpio_control.h"#define SIZE 16           // 字符大小
#define Max_Column 128    // 最大列数#define OLED_IIC_ADDRESS 0x3C#define ACK 0  // 应答信号
#define NACK 1 // 非应答信号#define OLED_SCL_HIGH gpio_set_direction_out(pin_scl, HIGH)
#define OLED_SCL_LOW  gpio_set_direction_out(pin_scl, LOW)
#define OLED_SDA_HIGH gpio_set_direction_out(pin_sda, HIGH)
#define OLED_SDA_LOW  gpio_set_direction_out(pin_sda, LOW)void oled_Init(void);
void oled_DeInit(void);
void oled_Clear(void);
void oled_ShowString(unsigned char x, unsigned char y, const unsigned char *chr);#endif // OLED_H

显示效果如下图:在这里插入图片描述
它会有一个清屏函数,动图如下,清屏效果可能有点慢,动态图如下。

香橙派KunpengPro配置开机自启动使用OLED屏幕显示IP地址

写一个自动获取IP的程序

文件列表

程序文件列表如下:
clear.c:主要是清除引脚的使用,后面会将clear.c单独gcc编译成可执行文件clear,编译成功后可以将clear.c删掉了。
oled.c、oled.h
server.c、server.h
mainPro.c、mainPro.h

gpio_control.c和gpio_control.h

gpio_control.h

#ifndef GPIO_CONTROL_H
#define GPIO_CONTROL_H#define GPIO_PATH_FORMAT "/sys/class/gpio/gpio%d/%s"
#define GPIO_EXPORT "/sys/class/gpio/export"
#define GPIO_UNEXPORT "/sys/class/gpio/unexport"typedef enum {LOW = 0,HIGH = 1
} GPIO_Value;// 导出GPIO引脚
void gpio_export(int pin);// 取消导出GPIO引脚
void gpio_unexport(int pin);// 设置GPIO引脚为输入模式
void gpio_set_direction_in(int pin);// 设置GPIO引脚为输出模式
void gpio_set_direction_outMode(int pin);// 设置GPIO引脚为输出模式并设置电平
void gpio_set_direction_out(int pin, GPIO_Value value);// 读取GPIO引脚的状态
int gpio_get_value(int pin);#endif // GPIO_CONTROL_H

gpio_control.c

#include "mainPro.h"void write_to_file(const char *filename, const char *value)
{int fd = open(filename, O_WRONLY);if (fd < 0){perror("open");exit(EXIT_FAILURE);}if (write(fd, value, strlen(value)) < 0){perror("write");exit(EXIT_FAILURE);}close(fd);
}void gpio_export(int pin)
{char buffer[4];snprintf(buffer, sizeof(buffer), "%d", pin);write_to_file(GPIO_EXPORT, buffer);usleep(100000); // 等待GPIO初始化完成
}void gpio_unexport(int pin)
{char buffer[4];snprintf(buffer, sizeof(buffer), "%d", pin);write_to_file(GPIO_UNEXPORT, buffer);
}void gpio_set_direction_in(int pin)
{char path[50];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "direction");write_to_file(path, "in");
}void gpio_set_direction_outMode(int pin)
{char path[50];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "direction");write_to_file(path, "out");
}void gpio_set_direction_out(int pin, GPIO_Value value)
{char path[50];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "direction");write_to_file(path, "out");snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "value");write_to_file(path, value == HIGH ? "1" : "0");
}int gpio_get_value(int pin)
{char path[50];char value_str[3];snprintf(path, sizeof(path), GPIO_PATH_FORMAT, pin, "value");int fd = open(path, O_RDONLY);if (fd < 0){perror("open");exit(EXIT_FAILURE);}if (read(fd, value_str, sizeof(value_str)) < 0){perror("read");exit(EXIT_FAILURE);}close(fd);return atoi(value_str);
}

clear.c和可执行文件clear

clear.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>#define GPIO_PATH_FORMAT "/sys/class/gpio/gpio%d/%s"
#define GPIO_EXPORT "/sys/class/gpio/export"
#define GPIO_UNEXPORT "/sys/class/gpio/unexport"void write_to_file(const char *filename, const char *value)
{int fd = open(filename, O_WRONLY);if (fd < 0){perror("open");exit(EXIT_FAILURE);}if (write(fd, value, strlen(value)) < 0){perror("write");exit(EXIT_FAILURE);}close(fd);
}void gpio_unexport(int pin)
{char buffer[4];snprintf(buffer, sizeof(buffer), "%d", pin);write_to_file(GPIO_UNEXPORT, buffer);
}void main()
{gpio_unexport(3);gpio_unexport(128);
}

clear可执行文件
在这里插入图片描述

oled.c和oled.h

oled.h

#ifndef OLED_H
#define OLED_H#define SIZE 16           // 字符大小
#define Max_Column 128    // 最大列数#define OLED_IIC_ADDRESS 0x3C#define ACK 0  // 应答信号
#define NACK 1 // 非应答信号#define OLED_SCL_HIGH gpio_set_direction_out(pin_scl, HIGH)
#define OLED_SCL_LOW  gpio_set_direction_out(pin_scl, LOW)
#define OLED_SDA_HIGH gpio_set_direction_out(pin_sda, HIGH)
#define OLED_SDA_LOW  gpio_set_direction_out(pin_sda, LOW)void oled_Init(void);
void oled_DeInit(void);
void oled_Clear(void);
void oled_ShowString(unsigned char x, unsigned char y, const unsigned char *chr);#endif // OLED_H

oled.c

#include "mainPro.h"int pin_scl = 128;
int pin_sda = 3;/************************************6*8的点阵************************************/
const unsigned F6x8[][6] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // "0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // #0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // %0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // &0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // '0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // (0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // )0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // *0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // +0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // ,0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // -0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // .0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // /0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 00x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 10x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 20x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 30x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 40x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 50x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 60x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 70x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 80x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 90x00, 0x00, 0x36, 0x36, 0x00, 0x00, // :0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ;0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // <0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // =0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // >0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ?0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // 550x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ]0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // '0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // horiz lines
};/****************************************8*16的点阵************************************/
unsigned char F8X16[] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 00x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 10x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //" 20x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 30x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$ 40xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //% 50x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //& 60x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //' 70x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //( 80x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //) 90x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //* 100x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+ 110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //, 120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //- 130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //. 140x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 150x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 160x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 170x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 180x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 190x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 200x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 210x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 220x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 230x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 240x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 250x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 260x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //; 270x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //< 280x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //= 290x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //> 300x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //? 310xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@ 320x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 330x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 340xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 350x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 360x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 370x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 380xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 390x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 400x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 410x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 420x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 430x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 440x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 450x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 460xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 470x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 480xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 490x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 500x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 510x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 520x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 530x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 540xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 550x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 560x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 570x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 580x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[ 590x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\ 600x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //] 610x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^ 620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_ 630x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //` 640x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 650x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 660x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 670x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 680x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 690x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 700x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 710x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 720x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 730x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 740x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 750x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 760x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 770x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 780x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 790x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 800x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 810x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 820x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 830x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 840x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 850x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 860x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 870x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 880x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 890x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 900x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{ 910x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //| 920x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //} 930x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
};void OLED_I2C_Delay(unsigned int t)
{usleep(t);
}void OLED_I2C_Start(void)
{gpio_set_direction_outMode(pin_sda);OLED_SDA_HIGH; // 发送起始条件的数据信号OLED_SCL_HIGH;OLED_I2C_Delay(5); // 起始条件建立时间大于4.7us,延时OLED_SDA_LOW;      // 发送起始信号OLED_I2C_Delay(5); // 起始条件锁定时间大于4μsOLED_SCL_LOW;      // 钳住I2C总线,准备发送或接收数据OLED_I2C_Delay(5);
}void OLED_I2C_Stop(void)
{gpio_set_direction_outMode(pin_sda);OLED_SDA_LOW; // 发送结束条件的数据信号OLED_SCL_LOW;OLED_I2C_Delay(5);OLED_SCL_HIGH;     // 发送结束条件的时钟信号OLED_I2C_Delay(5); // 结束条件建立时间大于4μsOLED_SDA_HIGH;     // 发送I2C总线结束信号OLED_I2C_Delay(5);
}unsigned char OLED_I2C_Write_Byte(unsigned char writeByte)
{unsigned char i;gpio_set_direction_outMode(pin_sda);OLED_SCL_LOW;OLED_I2C_Delay(5);for (i = 0; i < 8; i++) // 要传送的数据长度为8位{if (writeByte & 0x80) // 判断发送位{OLED_SDA_HIGH;}else{OLED_SDA_LOW;}OLED_I2C_Delay(5);OLED_SCL_HIGH;     // 输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样OLED_I2C_Delay(5); // 保证时钟高电平周期大于4μsOLED_SCL_LOW;OLED_I2C_Delay(5);writeByte <<= 1;}OLED_I2C_Delay(1);OLED_SDA_HIGH; // 8位发送完后释放数据线,准备接收应答位-ZLGOLED_I2C_Delay(5);OLED_SCL_HIGH; // MCU告知SHT2X数据发送完毕,等待从机的应答信号OLED_I2C_Delay(5);gpio_set_direction_in(pin_sda);/*以下是判断I2C总线接收应到应答信号是ACK还是NACK*/if (gpio_get_value(pin_sda) == 1) // SDA为高,收到NACK{OLED_I2C_Delay(5);OLED_SCL_LOW;return NACK;}else // SDA为低,收到ACK{OLED_I2C_Delay(5);OLED_SCL_LOW;return ACK;}
}unsigned char OLED_I2C_Read_Byte(unsigned char ackValue)
{unsigned char i = 0;unsigned char readByte = 0;gpio_set_direction_outMode(pin_sda);OLED_SCL_LOW; // 置时钟线为低,准备接收数据位OLED_I2C_Delay(5);OLED_SDA_HIGH; // 释放总线,置数据线为输入方式gpio_set_direction_in(pin_sda);for (i = 0; i < 8; i++){OLED_SCL_HIGH; // SCL高电平期间,采集SDA信号,并作为有效数据 //置时钟线为高使数据线上数据有效OLED_I2C_Delay(5);readByte <<= 1;                 // 移位if (gpio_get_value(pin_sda) == 1) // 采样获取数据{readByte |= 0x01;}else{readByte &= 0xfe;}OLED_I2C_Delay(5);OLED_SCL_LOW; // 下降沿,从机给出下一位值OLED_I2C_Delay(5);}gpio_set_direction_outMode(pin_sda);/*以下是I2C总线发送应答信号ACK或者NACK*/gpio_set_direction_out(pin_sda,ackValue);OLED_I2C_Delay(5);OLED_SCL_HIGH;OLED_I2C_Delay(5); // 时钟低电平周期大于4μsOLED_SCL_LOW;      // 清时钟线,钳住I2C总线以便继续接收OLED_I2C_Delay(5);return readByte;
}// OLED写入一条指令
void oledWriteCmd(char writeCmd)
{OLED_I2C_Start();OLED_I2C_Write_Byte(0x78);OLED_I2C_Write_Byte(0x00);OLED_I2C_Write_Byte(writeCmd);OLED_I2C_Stop();
}void oledWriteData(char writeData)
{OLED_I2C_Start();OLED_I2C_Write_Byte(0x78);OLED_I2C_Write_Byte(0x40);OLED_I2C_Write_Byte(writeData);OLED_I2C_Stop();
}// 更新显存到LCD
void oled_Clear(void)
{unsigned char i, n;for (i = 0; i < 8; i++){oledWriteCmd(0xb0 + i); // 设置页地址(0~7)oledWriteCmd(0x00);     // 设置显示位置—列低地址oledWriteCmd(0x10);     // 设置显示位置—列高地址for (n = 0; n < 130; n++){oledWriteData(0);}}OLED_I2C_Delay(500000);
}// 开启OLED显示
void OLED_Display_On(void)
{oledWriteCmd(0X8D); // SET DCDC命令oledWriteCmd(0X14); // DCDC ONoledWriteCmd(0XAF); // DISPLAY ON
}// 关闭OLED显示
void OLED_Display_Off(void)
{oledWriteCmd(0XAE); // SET DCDC命令oledWriteCmd(0X8D); // DCDC OFFoledWriteCmd(0X10); // DISPLAY OFF
}// 设置光标
void OLED_Set_Pos(unsigned char x, unsigned char y)
{oledWriteCmd(0xB0 + y);oledWriteCmd((x & 0x0f));oledWriteCmd(((x & 0xf0) >> 4) | 0x10);
}// 屏幕初始化函数
void oled_Init(void)
{// 导出GPIO引脚gpio_export(pin_scl);gpio_export(pin_sda);gpio_set_direction_out(pin_scl, HIGH);gpio_set_direction_out(pin_sda, HIGH);oledWriteCmd(0xAE); // 关闭显示oledWriteCmd(0x00); // 设置时钟分频因子,震荡频率oledWriteCmd(0x10); //[3:0],分频因子;[7:4],震荡频率oledWriteCmd(0x40); // 设置驱动路数oledWriteCmd(0xB0); // 默认0X3F(1/64)oledWriteCmd(0x81); // 默认为0oledWriteCmd(0xFF); // 设置显示开始行 [5:0],行数.oledWriteCmd(0xA1); // 电荷泵设置oledWriteCmd(0xA6); // bit2,开启/关闭oledWriteCmd(0xA8); // 设置内存地址模式oledWriteCmd(0x3F); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;oledWriteCmd(0xC8); // 段重定义设置,bit0:0,0->0;1,0->127;oledWriteCmd(0xD3); // 设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数oledWriteCmd(0x00); // 设置COM硬件引脚配置oledWriteCmd(0xD5); //[5:4]配置oledWriteCmd(0x80); // 对比度设置oledWriteCmd(0xD9); // 1~255;默认0X7F (亮度设置,越大越亮)oledWriteCmd(0xF1); // 设置预充电周期oledWriteCmd(0xDA); //[3:0],PHASE 1;[7:4],PHASE 2;oledWriteCmd(0x12); // 设置VCOMH 电压倍率oledWriteCmd(0xDB); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vccoledWriteCmd(0x40); // 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)oledWriteCmd(0x8D); // 设置显示方式;bit0:1,反相显示;0,正常显示oledWriteCmd(0x14); // 开启显示oledWriteCmd(0xAF); // 开启显示 OLED_Clear();OLED_Set_Pos(0, 0);oled_Clear();
}void oled_DeInit(void)
{gpio_unexport(pin_scl);gpio_unexport(pin_sda);
}// 在指定位置显示一个字符,包括部分字符
// x:0~127
// y:0~63
// mode:0,反白显示;1,正常显示
// size:选择字体 16/12
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char chr)
{unsigned char c = 0, i = 0;c = chr - ' ';if (x > Max_Column){x = 0;y = y + 2;}if (SIZE == 16) // ×Ö·û´óСÈç¹ûΪ16 =8 *16{OLED_Set_Pos(x, y); // ´Óx,y¿ªÊ¼»­µãfor (i = 0; i < 8; i++){oledWriteData(F8X16[c * 16 + i]);}OLED_Set_Pos(x, y + 1); // ´Óx,y¿ªÊ¼»­µãfor (i = 0; i < 8; i++){oledWriteData(F8X16[c * 16 + i + 8]);}}else // 6 =6*8{OLED_Set_Pos(x, y);for (i = 0; i < 6; i++)oledWriteData(F6x8[c][i]);}
}// 显示字符串
// x,y:起点坐标
// size:字体大小
//*p:字符串起始地址
void oled_ShowString(unsigned char x, unsigned char y, const unsigned char *chr)
{unsigned char j = 0;while (chr[j] != '\0'){OLED_ShowChar(x, y, chr[j]);x += 8;if (x >= 128){x = 0;y += 2;}j++;}
}

server.c和server.h

server.h

#ifndef SERVER_H
#define SERVER_H#define MAX_MATCHES 10                          // 正则表达式匹配次数
#define IP_REGEX "([0-9]{1,3}\\.){3}[0-9]{1,3}" // 正则表达式,匹配xxx.xxx.xxx.xxx#define BUF_SIZE 128  // readBuffer和writeBuffer的大小#define SERVER_PORT "8006"void *server_pthread(void *arg);#endif /* SERVER_H */

server.c

#include "mainPro.h"int server_Fd = 0;char IP_ADDRESS[24] = {'\0'};void get_ip_address()
{// 调用终端执行ifconfig命令char tmpBuf[1024] = {'\0'};FILE *fp = popen("ifconfig wlan0", "r");int readCnt = fread(tmpBuf, 1, 1024, fp);pclose(fp);regex_t regex;                   // 正则表达式结构体,用来存储编译后的正则表达式regmatch_t matches[MAX_MATCHES]; // 匹配结果数组,用来存储匹配到的结果int ret;ret = regcomp(&regex, IP_REGEX, REG_EXTENDED); // 编译正则表达式,REG_EXTENDED使用扩展正则表达式模式if (ret != 0){fprintf(stderr, "Failed to compile regex\n");return;}ret = regexec(&regex, tmpBuf, MAX_MATCHES, matches, 0); // 目标字符串匹配正则表达式,MAX_MATCHES为匹配的最大次数if (ret != 0){fprintf(stderr, "No IP address found\n");regfree(&regex);return;}char *ip_address = malloc(16);if (ip_address == NULL){fprintf(stderr, "Failed to allocate memory\n");regfree(&regex); // 释放编译的正则表达式结构体return;}memset(ip_address, '\0', 16);int len = matches[0].rm_eo - matches[0].rm_so;strncpy(ip_address, tmpBuf + matches[0].rm_so, len);// Free the regexregfree(&regex); // 释放编译的正则表达式结构体// oled_Clear();// oled_ShowString(0 + 2, 0, ip_address);  // 第一行// oled_ShowString(0 + 2, 6, SERVER_PORT); // 最后一行memset(IP_ADDRESS,0,24);strncpy(IP_ADDRESS,ip_address,16);
}void *server_SendData_pthread(void *arg)
{int connectFd = *((int *)arg);char writeBuf[BUF_SIZE] = "Hello Orange KunPengPro";while (1){write(connectFd, writeBuf, strlen(writeBuf));usleep(3000000); // 延时1000ms}return NULL;
}void *server_clientConnect_pthread(void *arg)
{int connectFd = *((int *)arg);char readBuf[BUF_SIZE];int readSize;pthread_t server_SendData_tid;if (pthread_create(&server_SendData_tid, NULL, server_SendData_pthread, arg) != 0){perror("pthread_create");}while (1){memset(readBuf, '\0', sizeof(readBuf));readSize = read(connectFd, readBuf, sizeof(readBuf));if (readSize < 0){perror("read");break;}else if (readSize == 0){printf("Client disconnected\n");break;}else{printf("Message from client: %s\n", readBuf);}}pthread_cancel(server_SendData_tid);close(connectFd);free(arg);return NULL;
}int serverInit()
{get_ip_address();server_Fd = socket(AF_INET, SOCK_STREAM, 0);if (server_Fd < 0){perror("socket");return -1;}struct sockaddr_in my_net;memset(&my_net, 0, sizeof(struct sockaddr_in));my_net.sin_family = AF_INET;my_net.sin_port = htons(atoi(SERVER_PORT));inet_aton(IP_ADDRESS, &my_net.sin_addr);if (bind(server_Fd, (struct sockaddr *)&my_net, sizeof(struct sockaddr_in)) < 0){perror("bind");return -1;}if (listen(server_Fd, 15) < 0){perror("listen");return -1;}return 0;
}void *server_pthread(void *arg)
{int connectFd = 0;struct sockaddr_in msg_addr;int tmp = 0;int size = sizeof(struct sockaddr_in);serverInit();printf("OrangeKunPengPro_IP:%s,OrangeKunPengPro_Port:%s\n", IP_ADDRESS, SERVER_PORT);oled_ShowString(0, 0, IP_ADDRESS);oled_ShowString(0, 6, SERVER_PORT);while (1){memset(&msg_addr, 0, sizeof(struct sockaddr_in));connectFd = accept(server_Fd, (struct sockaddr *)&msg_addr, &size);if (connectFd < 0){perror("accept");}tmp++;printf("Got connection %d from %s\n", tmp, inet_ntoa(msg_addr.sin_addr));int *connectFd_ptr = (int *)malloc(sizeof(int));*connectFd_ptr = connectFd;pthread_t server_clientConnect_tid;if (pthread_create(&server_clientConnect_tid, NULL, server_clientConnect_pthread, connectFd_ptr) != 0){perror("pthread_create");free(connectFd_ptr);}pthread_detach(server_clientConnect_tid);}
}

mainPro.c和mainPro.h

mainPro.h

#ifndef MAINPRO_H
#define MAINPRO_H#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <regex.h>#include "gpio_control.h"
#include "oled.h"
#include "server.h"#endif /* MAINPRO_H */

mainPro.c

#include "mainPro.h"int main(int argc, char *argv[])
{system("sudo /home/openEuler/GPIO_CONTROL/clear");oled_Init();pthread_t server_tid;if (pthread_create(&server_tid, NULL, server_pthread, NULL) != 0){perror("pthread_create");}pthread_join(server_tid, NULL);oled_ShowString(0,0,"jiangxiaoya");oled_DeInit();return 0;
}

与QT上位机的交互

因为架设了Socket服务端,因此,我们可以通过网络调试助手或者QT上位机来与香橙派KunpengPro进行网络通信。
在这里插入图片描述

创建一个开机自启动服务

创建一个开机自启动服务,该服务连上网后才会执行。
在这里插入图片描述

创建一个自启动服务文件

sudo vi /etc/systemd/system/haozige.service,haozige是文件名,可以自行修改,内容填下面的,记得使用root权限,如果有报错,把中文注释删掉。

[Unit]
Description=Haozige #这里是这个服务的描述,可以不用管
After=network.target #连上网才启动服务
[Service]
User=root #用户名
ExecStart=/home/openEuler/GPIO_CONTROL/haozige #可执行文件的路径,就是你gcc编译出来的可执行文件
Restart=on-failure #服务失败后选择重启操作
StandardOutput=journal #服务的标准输出流,选择日志,可以用journalctl -u haozige.service -e命令查看
[Install]
WantedBy=multi-user.target
在这里插入图片描述

重新加载 systemd 配置并启用服务

sudo systemctl daemon-reload
sudo systemctl restart haozige.service

查看服务是否成功开启

sudo systemctl status haozige.service,这里发现服务开启失败了。
在这里插入图片描述

重新启动服务,并查看服务状态

sudo systemctl start haozige.service,重新启动服务,sudo systemctl status haozige.service重新查看服务状态。
在这里插入图片描述
此时已经成功开启服务了,我们可以使用sudo reboot命令重启香橙派KunpengPro开发板,查看开机显示IP效果。
在这里插入图片描述

体验总结

作为一名即将毕业的嵌入式爱好者,最近有幸参与了香橙派KunpengPro开发板的亲身体验,香橙派KunpengPro最吸引我的地方在于它那颗强大的“心脏”——4核64位处理器+AI处理器,搭配上8GB或16GB的大内存,运行速度快得起飞,即便是同时运行多个编程环境或者开发工具也不在话下。而且,它那AI处理能力,8TOPS的算力也算得上是性能怪兽。无论是图像识别的小实验,还是语音助手的复杂demo,都能轻松驾驭。

我平时的主要研究方向就是水下智能机器人、智能家居、智能鸡舍、智能小车等智能系统,期间用的开发板在OpenCV的折磨下,都发烫的厉害,从而造成系统卡顿以及程序因温度过高而崩溃,香橙派KunpengPro搭配了良好的散热套装,在这几天的体验下来,明显感觉到香橙派KunpengPro在程序运行期间的流畅性,而且板子温度也不高,以后有机会可以用来开发出各种各样的智能系统。

总的来说,香橙派KunpengPro就像是我数字生活里的瑞士军刀,功能多样又实用,无论是日常的学习探索,还是突发的创新灵感,它都能完美匹配,让我的技术之旅更加多彩多姿。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17888.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十四天学会Vue——Vue核心(理论+实战)上篇(第一天)

一、Vue核心&#xff08;上篇&#xff09; 热身tops&#xff1a;选取开发模式 ①用于开发模式 我们只需要知道 我们是开发模式&#xff0c;开发模式他会跟你提示代码出现错误的地方以及出错原因&#xff0c;而生产模式比较简洁。 ②用于生产模式 1.1 new Vue()实例 了解Vue&a…

数据库语法树优化

目录 一、σ、π、⋈ 1.选择σ 2.投影π 3.连接⋈ 二、 构建语法树 ① 解读sql语句 ② 写出关系代数表达式 ③ 画出语法树 三、优化语法树 四、练习 语法树优化方法 一、σ、π、⋈ 1.选择σ 选择就是在关系R中选择满足给定条件的诸元组。 通过条件SdeptIS选择出系别…

基于香橙派搭建家庭网盘

一、概述 家庭网盘是一种用于家庭用户的在线存储和文件共享服务。它允许家庭成员在云端存储、同步和分享照片、视频、文档等文件&#xff0c;方便快捷地访问和管理个人和家庭数据。家庭网盘通常提供安全可靠的数据存储和备份功能&#xff0c;保障用户数据的安全性。此外&#x…

一文解决弹窗交互设计难题,轻松上手

弹窗交互的分类 我们每天所说的弹出窗口是一个非常笼统的概念。我们习惯性地称所有的对话框、浮层和提示条为弹出窗口。事实上&#xff0c;弹出窗口可以分为两种类型&#xff1a;模态弹出框和非模态弹出框。在 UI 在设计中&#xff0c;当它迫使用户与之交互时&#xff0c;我们…

【算法】【二叉树,DFS,哈希集合,分类讨论】力扣1110. 删点成林

1110. 删点成林 文章目录 【算法】力扣【二叉树&#xff0c;DFS&#xff0c;哈希集合&#xff0c;分类讨论】1110. 删点成林题目描述示例 1&#xff1a;示例 2&#xff1a; 输入输出示例解释思路解析核心思想算法步骤复杂度分析 代码实现总结 【算法】力扣【二叉树&#xff0c…

ElasticSearch - 删除已经设置的认证密码(7.x)

文章目录 Pre版本号 7.x操作步骤检查当前Elasticsearch安全配置停止Elasticsearch服务修改Elasticsearch配置文件删除密码重启Elasticsearch服务验证配置 小结 Pre Elasticsearch - Configuring security in Elasticsearch 开启用户名和密码访问 版本号 7.x ES7.x 操作步骤 …

马斯克xAI融资60亿美元,宣布打造世界第一超算中心,10万张H100GPU

昨天&#xff0c;埃隆马斯克的xAI初创公司宣布获得60亿美元的巨额融资&#xff0c;主要用于打造一台巨大的超级计算机&#xff0c;马斯克称之为“超级计算工厂”。 从创立OpenAI到如今的xAI&#xff0c;技术和算力的发展历经了几个时代&#xff0c;但似乎马斯克的吸金能力一直…

代码随想录算法训练营day21|530.二叉搜索树的最小绝对值差、501.二叉搜索树中的众数、236.二叉树的最近公共祖先

二叉搜索树的最小绝对值差 递归法 首先需考虑这是一个二叉搜索树&#xff0c;在中序遍历后的结果为从小到大的一个序列&#xff0c;寻找二叉搜索树的最小绝对值差&#xff0c;只需比较一个节点与之后的差值即可。在遍历的过程中&#xff0c;我们需要一个节点保存前节点…

短道速滑短视频:四川京之华锦信息技术公司

短道速滑短视频&#xff1a;冰雪激情的视觉盛宴 随着冬奥会的热度不断攀升&#xff0c;短道速滑作为其中一项紧张刺激、充满观赏性的运动&#xff0c;受到了越来越多人的关注。而在社交媒体和短视频平台的助力下&#xff0c;短道速滑短视频成为了人们了解、欣赏这项运动的新窗…

vxe-form-design 表单设计器的使用

vxe-form-design 在 vue3 中表单设计器的使用 查看官网 https://vxeui.com 安装 npm install vxe-pc-ui // ... import VxeUI from vxe-pc-ui import vxe-pc-ui/lib/style.css // ...// ... createApp(App).use(VxeUI).mount(#app) // ...使用 github vxe-form-design 用…

Python在忘mysql密码后该如何重新连mysql

步骤一 先到mysql的bin目录下 步骤二 用mysqld delete mysql 把之前的库删了 步骤三 通过管理员模式进去后 用命令mysqld --skip-grant-tables越过验证 再输入mysql -u root 直达账户 步骤四 用FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY new_password; 指…

Echarts x轴坐标二级分组

在使用echarts 封装组件的时候&#xff0c;偶尔会遇到需要x轴坐标进行二层分组的需求。那么如何对echarts 进行二层分组呢&#xff0c;有以下几个步骤&#xff1a; 仅介绍二层分组的逻辑。有兴趣的可以进行三层延伸。 1&#xff0c;修改echarts Options 中xAxis 的配置。 此…

【机器学习】K-近邻算法(KNN)全面解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 K-近邻算法&#xff08;KNN&#xff09;全面解析概述1. 基本概念与原理1.1 KNN算…

Excel表格保护密码遗忘怎么办?三秒钟破解密码,轻松解锁!

在我们的日常工作中&#xff0c;Excel表格是一个非常实用的工具&#xff0c;但在某些情况下&#xff0c;我们可能会遇到密码忘记的问题&#xff0c;或者在尝试打开或删除文件时被锁定。别担心&#xff0c;这里有三个简单的解决方法来帮助您解决问题。 一、尝试默认密码或常见密…

使用 Orange Pi AIpro开发板基于 YOLOv8 进行USB 摄像头实时目标检测

文章大纲 简介算力指标与概念香橙派 AIpro NPU 纸面算力直观了解 手把手教你开机与基本配置开机存储挂载设置风扇设置 使用 Orange Pi AIpro进行YOLOv8 目标检测Pytorch pt 格式直接推理NCNN 格式推理 是否可以使用Orange Pi AIpro 的 NPU 进行推理 呢&#xff1f;模型开发流程…

gitlab push 代码,密码正确,仍然提示HTTP Basic: Access denied. The provided password

HTTP Basic: Access denied. The provided password or token is incorrect or your account has 2FA enabled and you must use a personal access token instead of a password gitlab 登录账户密码确认正确&#xff0c;登录获取代码仍然提示以上问题&#xff0c;解决方案 …

①单细胞学习-数据读取、降维和分群

目录 ①数据读取 ②计算线粒体基因比例 ③分开进行质控 ④两组单细胞数据合并 ⑤细胞周期评分 ⑥降维标准流程 降维 UMAP可视化 选择分群 ⑦marker基因 分析marker基因 marker基因可视化 ⑧细胞定群命名 单细胞的数据格式学习&#xff1a;单细胞 10X 和seurat对象…

【软件设计师】算法

1、算法的效率 时间复杂度:程序从开始到结束所需要的时间 空间复杂度&#xff1a;算法在运行过程中临时占用存储空间大小的度量 时间渐近复杂度&#xff1a;时间复杂度由最高次幂决定(判断大小技巧&#xff1a;将n10代入&#xff09; O(log2 n):二分查找法 O(n&#xff09;:for…

家政预约小程序07服务分类展示

目录 1 创建服务分类页面2 侧边栏选项卡配置3 配置数据列表4 从首页跳转到分类页总结 上一篇我们开发了首页的服务展示功能&#xff0c;本篇我们讲解一下服务分类功能的开发。在小程序中通常在底部导航栏有一个菜单可以展示所有服务&#xff0c;侧边选项卡可以展示分类信息&…

Python零基础一天丝滑入门教程(非常详细)

目录 第1章 初识python 第1节 python介绍 1.为什么要学习Python&#xff1f; 2.python排名 3.python起源 4.python 的设计目标 第2节 软件安装 第2章 快速上手&#xff1a;基础知识 第1节 Python3 基础语法 Python 变量 字面量 数据类型转换 Python3 注释 数据类…