鸿蒙硬件HI3861-OLED扫雷版本1

鸿蒙硬件HI3861-OLED扫雷版本

使用HI3861实现在OLED1602上面实现扫雷

效果请看:https://www.bilibili.com/video/BV1U54y1r78j/

1.OLED&按键

首先第一步是需要移植I2C显示屏代码

移植请看:https://bbs.elecfans.com/jishu_1999539_1_1.html

按键使用到的是OLED上面的两个按键,一个控制左一个控制右,HI3861上的按键时选中

2.扫雷代码

在OLED初始化启动之后调用mineclear_Start函数

static_library("mineclear") {
    sources = [
        "mineclear.c"
    ]
    include_dirs = [
        "//domains/iot/link/mineclear",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
        "//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
        "//domains/iot/link/ssd1306",
    ]
}

mineclear.h

#ifndef MINECLEAR_H
#define MINECLEAR_H


#define MINECLEAR_WIDTH 8
#define MINECLEAR_HEIGHT 16
#define MINECLEAR_MAX 128
#define MINE_MAX 10
#define ADC_LENGTH  64
#define VLT_MIN 100

void mineclear_Start(void);
void mine_init(void);
void mineMake(void);

#endif

mineclear.c 

#include "mineclear.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ohos_init.h"
#include "ssd1306.h"
#include <stddef.h>
#include "cmsis_os2.h"
#include <time.h>

#include <hi_io.h>
#include <hi_gpio.h>
#include <hi_stdlib.h>
#include "hi_adc.h"

#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include <hi_stdlib.h>

const uint32_t W = 8, H = 8;

uint8_t fonts[][8] = {
    {0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00},  // 默认状态
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},  // 没有雷
    {0x00,0x42,0x24,0x18,0x18,0x24,0x42,0x00},  // 有雷
    {0x55,0x80,0x01,0x80,0x01,0x80,0x01,0xAA},  // 选中
};  

uint32_t mine_data2[MINECLEAR_MAX];
uint32_t mineClear_data2[MINECLEAR_MAX];

hi_u16 key_adc_buf[ADC_LENGTH] = { 0 };
int key_flg;
uint32_t key_status = 0;
static uint32_t play_index = 0;


hi_void convert_to_voltage2(hi_u32 data_len){
    hi_u32 i;
    float vlt_max = 0;
    float vlt_min = VLT_MIN;

    float vlt_val = 0;

    hi_u16 vlt;
    for (i = 0; i < data_len; i++) {
        vlt = key_adc_buf[i];
        float voltage = (float)vlt * 1.8 * 4 / 4096.0;  /* vlt * 1.8 * 4 / 4096.0: Convert code into voltage */
        vlt_max = (voltage > vlt_max) ? voltage : vlt_max;
        vlt_min = (voltage < vlt_min) ? voltage : vlt_min;
    }

    vlt_val = (vlt_min + vlt_max)/2.0;

    if((vlt_val > 0.4) && (vlt_val < 0.6)){
        key_status = 1;
         //printf("[key]K1\r\n");
    }
    if((vlt_val > 0.8) && (vlt_val < 1.1)){
        key_status = 2;
         //printf("[key]K2\r\n",vlt_val);
    }

    if((vlt_val > 0.01) && (vlt_val < 0.3)){
        key_status = 3;
         //printf("[key]K3\r\n",vlt_val);
    }
}

void starttest2(void){
    hi_u32 ret, i;
    hi_u16 data;  /* 10 */

    memset_s(key_adc_buf, sizeof(key_adc_buf), 0x0, sizeof(key_adc_buf));
 
    for (i = 0; i < ADC_LENGTH; i++) {
        ret = hi_adc_read((hi_adc_channel_index)HI_ADC_CHANNEL_2, &data, HI_ADC_EQU_MODEL_1, HI_ADC_CUR_BAIS_DEFAULT, 0);
        if (ret != HI_ERR_SUCCESS) {
            printf("ADC Read Fail\n");
            return;
        }
        key_adc_buf[i] = data;
    }
    convert_to_voltage2(ADC_LENGTH);
}

void ssd1306_Draw(uint32_t x, uint32_t y,int type){
    ssd1306_DrawRegion(x, y, W, H, fonts[type], sizeof(fonts[type]), W);
}

void mineClear_Refresh2(uint32_t d[]){
    uint32_t i = 0, j = 0, h = 0;
    ssd1306_Fill(Black);
    for(i=0;i<MINECLEAR_WIDTH;i++){
        for(j=0;j<MINECLEAR_HEIGHT;j++){
            uint32_t md_data = d[h];

            if(md_data == 0){
                ssd1306_Draw((j*W),(i*H),0);
            }else if(md_data == 1){
                ssd1306_Draw((j*W),(i*H),2);
            }else if(md_data == 102){
                ssd1306_Draw((j*W),(i*H),3);
            }else if(md_data == 2){
                ssd1306_Draw((j*W),(i*H),1);
            }else{

            }

            h++;
        }
    }
    ssd1306_UpdateScreen();
}

void mine_init(void){
    uint32_t i;
    ssd1306_Fill(Black);
    for(i=0;i<MINECLEAR_MAX;i++){
        mineClear_data2[i] = 0;
    }

    mineClear_Refresh2(mineClear_data2);
}

/**
 *  制作炸弹 
 */
void mineMake(void){
    int count = MINE_MAX-1;
    int mine_rand = 0;

    while (true){
        if(count<0) break;
        mine_rand = rand() % MINECLEAR_MAX;
        if (mine_data2[mine_rand] == 0){
            mine_data2[mine_rand] = 1;
            count--;
        }
    }
    
    //mineClear_Refresh2(mine_data2);
}

/**
 * 移动光标
 */
void mouse_move(void){

    int index = play_index - 1;

    printf("[key]2--%d\r\n",index);

    if(index == 0){
        if(mineClear_data2[1] == 102 && mineClear_data2[1] != 0){
            mineClear_data2[1] = 0;
        }
        if(mineClear_data2[MINECLEAR_MAX-1] == 102 && mineClear_data2[MINECLEAR_MAX-1] != 0){
            mineClear_data2[MINECLEAR_MAX-1] = 0;
        }
    }else if(index == (MINECLEAR_MAX-1)){
         printf("[key]laster\r\n");
        if(mineClear_data2[0] == 102 && mineClear_data2[0] != 0){
            mineClear_data2[0] = 0;  
        }
        if(mineClear_data2[index-1] == 102 && mineClear_data2[index-1] != 0){
            mineClear_data2[index-1] = 0;
        }
    }else{
        if(mineClear_data2[index-1] == 102 && mineClear_data2[index-1] != 0){
            mineClear_data2[index-1] = 0;
        }
        if(mineClear_data2[index+1] == 102 && mineClear_data2[index+1] != 0){
            mineClear_data2[index+1] = 0;
        }
    }

    if(mineClear_data2[index] != 2){
        mineClear_data2[index] = 102;
    }

    mineClear_Refresh2(mineClear_data2);

    ssd1306_UpdateScreen();
}

void mine_find_num(void){
    mineClear_data2[play_index-1] = 2;
    ssd1306_UpdateScreen();

    // 获取周围8方块的雷

}

static void *MineClearTask(const char *arg){
    (void)arg;
    play_index = 1;
    while(1){
        starttest2();
        if(key_status == 1){    // 左移动
            if(play_index == 0){
                play_index = MINECLEAR_MAX;
            }  
            play_index--;  
            mouse_move();
        }

        if(key_status == 2){    // 右移动
            if(play_index > (MINECLEAR_MAX-1)){
                play_index = 0;
            }
            play_index++;  
            mouse_move();
        }

        if(key_status == 3){    // 选中
            
            if(mine_data2[play_index-1] == 1){  // 炸弹
                mineClear_data2[play_index-1] = 1;
                mineClear_Refresh2(mineClear_data2);
                osDelay(40);
                mineClear_Refresh2(mine_data2);
                break;
            }else{
                mine_find_num();
            }
            //printf("[11]%d\r\n",play_index);
        }

        key_status = 0;
        osDelay(10);
    }

    printf("GAME OVER\r\n");

    return NULL;
}

void mineclear_Start(void){

    osThreadAttr_t attr;

    attr.name = "MineClearTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = 34;
    mineMake();
    // osDelay(10);
    mine_init();
    osDelay(10);

    if (osThreadNew((osThreadFunc_t)MineClearTask, NULL, &attr) == NULL) {
        printf("[DoorDemo] Falied to create DoorTask!\n");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33259323/article/details/110351431