跳转至

多屏互动

项目要求

  1. 按照如下要求连接oled屏幕

  1. 手机app传送图片
  2. 打开服务器软件

项目编写

  1. applications/genkipi/app 下新建 oled_pic 文件夹
  2. oled_pic 下新建 main.c 文件
  3. oled_pic 下新建 BUILD.gn文件

代码部分

拷贝资料中的lcd.hlcd.coledfont.hWeather.h文件到oled文件夹中

main.c 文件内容

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "genki_wifi_sta.h"
#include "lwip/sockets.h"

#include "hi_io.h"
#include "iot_gpio.h"
#include "iot_io.h"
#include "genki_pin.h"
#include "iot_spi.h"
#include "lcd.h"
#include "Weather.h"
#include "a.h"

#define WIFI_SSID "itheima2"
#define WIFI_PASSWORD "12345678"
#define HOSTNAME "itcast"

//是否已经修改
int hasChange = 0;
//展示数据
uint16_t recv_data[10000];
//网络是否断开
uint8_t hasDisconnect = 0;

static void init_spi() {
    //5:RES 6:SCL(时钟) 7:DC(片选) 8:SDA(数据)
    /*------------------ 初始化引脚 ------------------*/
    //时钟和数据线
    IoTIoSetFunc(IOT_IO_NAME_6, IOT_IO_FUNC_6_SPI0_CK);

    IoTIoSetFunc(IOT_IO_NAME_8, IOT_IO_FUNC_8_SPI0_TXD);
    IoTIoSetDriverStrength(IOT_IO_NAME_6, IOT_IO_DRIVER_STRENGTH_2);


    //RES
    IoTIoSetFunc(IOT_IO_NAME_5, IOT_IO_FUNC_5_GPIO);
    IoTGpioSetDir(IOT_IO_NAME_5, IOT_GPIO_DIR_OUT);


    //DC
    IoTIoSetFunc(IOT_IO_NAME_7, IOT_IO_FUNC_7_GPIO);
    IoTGpioSetDir(IOT_IO_NAME_7, IOT_GPIO_DIR_OUT);


    /*------------------ spi配置 ------------------*/
    IoTSpiCfgBasicInfo spi_cfg_basic_info;
    spi_cfg_basic_info.cpha = IOT_SPI_CFG_CLOCK_CPHA_1;
    spi_cfg_basic_info.cpol = IOT_SPI_CFG_CLOCK_CPOL_1;
    spi_cfg_basic_info.dataWidth = IOT_SPI_CFG_DATA_WIDTH_E_8BIT;
    spi_cfg_basic_info.endian = 0;
    spi_cfg_basic_info.framMode = IOT_SPI_CFG_FRAM_MODE_MOTOROLA;
    spi_cfg_basic_info.freq = 40000000; /* set frequency 2000000 */

    IoTSpiCfgInitParam spi_init_param = {0};
    spi_init_param.isSlave = HI_FALSE;
    uint32_t ret = IoTSpiInit(IOT_SPI_ID_0, spi_init_param, &spi_cfg_basic_info);
    if (ret != HI_ERR_SUCCESS) {
        printf("init fail!\n");
    }
}


static void show_task() {
    printf("show task excute ===================================================");
    //初始化spi
    init_spi();
    //初始化oled板
    Lcd_Init();

    //清屏
    LCD_Clear(BLACK);
    //展示
    LCD_ShowGif(70, 70, 170 - 1, 170 - 1, bb, 10000);

    while (1) {
        if (hasChange == 1) {
            printf("show task excute ===================================================");
            //修改标志
            hasChange = 0;
            //清屏
            LCD_Clear(BLACK);
            //展示
            LCD_ShowGif(70, 70, 170 - 1, 170 - 1, recv_data, 10000);
        }
        usleep(1000 * 1000);
    }
}

static void oled_task(void) {

    wifi_sta_connect(WIFI_SSID, WIFI_PASSWORD, HOSTNAME);

    int sock_fd;
    int ret;
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0) {
        perror("[actuator_service]sock_fd create error\r\n");
        return;
    }

    // receive addr config
    struct sockaddr_in server_addr;
    socklen_t server_addr_len = sizeof(server_addr);

    memset((void *) &server_addr, 0, server_addr_len);
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("192.168.31.50");
    server_addr.sin_port = htons(8080);

    ret = connect(sock_fd, (struct sockaddr *) &server_addr, server_addr_len);
    if (ret == -1) {
        perror("connect error\r\n");
        return;
    }

    //发送角色
    char msg[1] = {'d'};
    ret = send(sock_fd, msg, sizeof(msg) / sizeof(char), 0);
    if (ret == -1) {
        printf("send role error\r\n");
        return;
    }

    printf("socket success --------------------------------------------");

    while (1) {
        uint8_t *pr = (uint8_t *) recv_data;
        while (1) {
            //接收数据
            uint8_t recv_buf[1024];
            int recv_len;
            recv_len = recv(sock_fd, recv_buf, sizeof(recv_buf), 0);
//            printf("recv_len:%d  -----------------------------------------------\n", recv_len);
//            printf("a:%d  %d  %d  %d -----------------------------\n", recv_buf[0], recv_buf[1], recv_buf[2], recv_buf[3]);
            if (recv_len <= 0) {
                hasDisconnect = 1;
                break;
            }
            //判断是否结束
            if (recv_len < 3) {
                break;
            }


            memcpy(pr, recv_buf, recv_len);
            pr += recv_len;

            if (recv_buf[recv_len - 1] == 0xff && recv_buf[recv_len - 2] == 0xff && recv_buf[recv_len - 3] == 0xff) {
                break;
            }
        }
        //如果已经断开了服务器
        if(hasDisconnect==1){
            break;
        }
        //已经修改
        hasChange = 1;
        printf("need show ===========================================================");
    }
}


static void start(void) {
    osThreadAttr_t attr;

    attr.name = "tcp_client_recv_send";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096 * 10;
    attr.priority = 25;

    if (osThreadNew((osThreadFunc_t) oled_task, NULL, &attr) == NULL) {
        printf("Create udp recv task Failed!\r\n");
    }

    osThreadAttr_t attr2;

    attr2.name = "show_task";
    attr2.attr_bits = 0U;
    attr2.cb_mem = NULL;
    attr2.cb_size = 0U;
    attr2.stack_mem = NULL;
    attr2.stack_size = 1024 * 4;
    attr2.priority = 25;

    if (osThreadNew((osThreadFunc_t) show_task, NULL, &attr2) == NULL) {
        printf("Create show task Failed!\r\n");
    }
}

APP_FEATURE_INIT(start);

项目Build.gn

tcp_server 目录下 BUILD.gn 内容为

static_library("oled_pic") {
    sources = [
        "main.c",
        "lcd.c"
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//base/iot_hardware/peripheral/interfaces/kits",
        "//device/itcast/genkipi/interfaces/kits",
        "//foundation/communication/wifi_lite/interfaces/wifiservice"
    ]
}

外部Build.gn

oled_pic文件夹上一级目录下BUILD.gn内容为

import("//build/lite/config/component/lite_component.gni")

lite_component("app") {
    features = [
        "oled_pic"
    ]
}