当前位置: 首页 > article >正文

使用软件模拟按键显示屏,上下左右确认取消按键,来修改IP端口号等参数。

设备有上下左右确认取消这六个按键,来进行设备参数修改,要修改的参数有IP、端口号、高度角等,手里暂时没有硬件,使用软件模拟的方式,来进行功能开发,打印代替显示屏。电脑键盘123456按键分别表示上下左右确认取消。纯手敲,测试正常,如有问题欢迎指正。代码如下。

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

#define MAX_DIGITS 16 // IP地址的最大数字位数
#define MAX_PAGE 3
#define MAX_IP_LEN 64
typedef struct
{
    int page;              // 当前页面(1: 高度角, 2: 端口号, 3: IP地址)
    int editing;           // 是否在编辑模式
    int position;          // 当前编辑的位置
    int value[MAX_DIGITS]; // 当前值,拆分为数字存储
    int value_length;      // 当前值的长度
    char buffer[16];       // 用于显示和存储编辑的字符串
} MenuState;

typedef struct
{
    int angle; // 当前页面(1: 高度角, 2: 端口号, 3: IP地址)
    char ip[MAX_IP_LEN];
    uint16_t port;

} device_Param;
// 菜单状态
typedef enum
{

    MENU_HEIGHT_ANGLE = 1,
    MENU_PORT,
    MENU_IP_ADDRESS,
} MenuStateENUM;
device_Param deviceParam;
void editMode(MenuState *state);
void mergeData(MenuState *state);
void print_menu(MenuState *state)
{
    int i;
    // system("cls");
    if (state->editing)
    {
        switch (state->page)
        {
        case MENU_HEIGHT_ANGLE:
            printf("Editing: Angle: ");
            break;
        case MENU_PORT:
            printf("Editing:PORT: ");
            break;
        case MENU_IP_ADDRESS:
            printf("Editing:IP: ");
            break;
        }
        for (i = 0; i < state->value_length; i++)
        {
            printf("%d", state->value[i]);
            if (i == state->position)
            {
                printf("_");
            }
            if ((i % 3 == 2) && (state->page == MENU_IP_ADDRESS) && (i != state->value_length - 1))
            {
                printf(".");
            }
        }
        printf("\n");
    }
    else
    {
        switch (state->page)
        {
        case MENU_HEIGHT_ANGLE:
            printf("Menu 1:  Angle %d\n", deviceParam.angle);
            break;
        case MENU_PORT:
            printf("Menu 2:  Port   %d \n", deviceParam.port);
            break;
        case MENU_IP_ADDRESS:
            printf("Menu 3:  IP  %s \n", deviceParam.ip);
            break;
        }
    }
}
uint8_t mergeIPAddr(const char *ip_address, int *buf)
{
    int part[4] = {0}, i;

    for (i = 0; i < 4; i++)
    {
        part[i] = buf[i * 3] * 100 + buf[i * 3 + 1] * 10 + buf[i * 3 + 2];
    }
    // 使用sscanf函数解析IP地址
    sprintf(ip_address, "%d.%d.%d.%d", part[0], part[1], part[2], part[3]);
    printf("%s", ip_address);

    return 0;
}
uint8_t splitIPAddr(const char *ip_address, int *buf)
{
    int part[4] = {0}, i;

    // 使用sscanf函数解析IP地址
    if (sscanf(ip_address, "%d.%d.%d.%d", &part[0], &part[1], &part[2], &part[3]) == 4)
    {
        for (i = 0; i < 4; i++)
        {
            buf[i * 3] = part[i] / 100;
            buf[i * 3 + 1] = part[i] % 100 / 10;
            buf[i * 3 + 2] = part[i] % 10;
        }
    }
    else
    {
        printf("The IP address is not in the correct format\n");
        return 1;
    }
    return 0;
}
void splitData(MenuState *state)
{
    uint16_t portNum = deviceParam.port;
    uint8_t data[16] = {0}, i;
    state->position = 0;
    state->value_length = 0;
    memset(state->value, 0, sizeof(state->value));

    switch (state->page)
    {
    case MENU_HEIGHT_ANGLE:
        state->value_length = 2;
        state->value[1] = deviceParam.angle % 10;
        state->value[0] = deviceParam.angle / 10;
        printf("高度角拆分: ");
        break;
    case MENU_PORT:
        while (portNum)
        {
            data[state->value_length++] = portNum % 10;
            portNum /= 10;
        }
        for (i = 0; i < state->value_length; i++)
        {
            state->value[i] = data[state->value_length - i - 1];
        }
        printf("port拆分: ");
        break;
    case MENU_IP_ADDRESS:
        if (splitIPAddr(deviceParam.ip, state->value) == 0)
        {
            state->value_length = 12;
        }
        printf("IP拆分: ");
        break;
    }

    for (int i = 0; i < state->value_length; i++)
    {
        printf("%d", state->value[i]);
    }
    printf("\n");
}

void mergeData(MenuState *state)
{
    uint8_t i;

    switch (state->page)
    {
    case MENU_HEIGHT_ANGLE:
        deviceParam.angle = state->value[0] * 10 + state->value[1];
        printf("merge angle:%d\n", deviceParam.angle);
        break;
    case MENU_PORT:
        deviceParam.port = 0;
        for (i = 0; i < state->value_length; i++)
        {
            deviceParam.port = deviceParam.port * 10 + state->value[i];
        }
        printf("merge port:%d\n", deviceParam.port);
        break;
    case MENU_IP_ADDRESS:
        memset(deviceParam.ip, 0, sizeof(deviceParam.ip));
        mergeIPAddr(deviceParam.ip, state->value);
        printf("merge ip: %s\n", deviceParam.ip);
        break;
    }
}

int main()
{
    MenuState state;
    deviceParam.angle = 45;
    memcpy(deviceParam.ip, "192.168.1.11", sizeof("192.168.1.11"));
    deviceParam.port = 1234;
    state.page = 1;

    while (1)
    {
        print_menu(&state);
        int key = getchar();
        getchar(); // 读取换行符

        switch (key - '0')
        {

        case 1:
        case 3:
            if (state.page == 1)
            {
                state.page = MAX_PAGE;
            }
            else
            {
                state.page--;
            }

            break;
        case 2:
        case 4:
            if (state.page == MAX_PAGE)
            {
                state.page = 1;
            }
            else
            {
                state.page++;
            }
            break;
        case 5:

            state.editing = 1;
            splitData(&state);
            editMode(&state);
            printf("return menu\n");
            break;
        default:
            printf("invalid input\n");
        }
    }

    return 0;
}
void editMode(MenuState *state)
{

    while (state->editing)
    {
        print_menu(state);
        int key = getchar();
        getchar(); // 读取换行符
        printf("input%d\n", key- '0');
        switch (key - '0')
        {

        case 1:
            if (state->value[state->position] == 9)
            {
                state->value[state->position] = 0;
            }
            else
            {
                state->value[state->position]++;
            }
            break;
        case 2:
            if (state->value[state->position] == 0)
            {
                state->value[state->position] = 9;
            }
            else
            {
                state->value[state->position]--;
            }
            break;
        case 3:
            if (state->position == 0)
            {
                state->position = state->value_length - 1;
            }
            else
            {
                state->position--;
            }
            break;
        case 4:
            if (state->position == state->value_length - 1)
            {
                state->position = 0;
            }
            else
            {
                state->position++;
            }
            break;

        case 5: // 确认键:进入编辑模式或保存修改
            if (state->editing == 1)
            {
                mergeData(state);
                printf("save state\n");
            }

            break;
        case 6: // 取消键:退出编辑模式或返回上一级菜单
            state->editing = 0;
            break;
        default:
            printf("invalid input\n");
        }
    }
}


http://www.kler.cn/news/355597.html

相关文章:

  • Hi3061M——VL53L0X激光测距(IIC)(同样适用于其他MCU)2
  • rk3588 opencv 的使用
  • Android 编译时出现Android resource linking failed.without required default value.
  • perl读取目录,写入文件
  • 高校企业数据可视化平台功能介绍/特色功能
  • 骑砍霸主MOD天芒传奇Ⅱ·前传-序章
  • 压缩感知解谱
  • EI会议将截稿|第三届环境工程与与可持续能源国际会议(EESE 2024)
  • Git常用操作
  • 国家计算机二级MSOffice计算机选择题题库汇总精选
  • VS code部署Vue项目Demo
  • Apache POI
  • C#从零开始学习(基本语法概念)(2)
  • 腐蚀膨胀预处理
  • Java - 使用AOP+SpEL基于DB中的用户ID自动补全用户姓名
  • 【网络安全】盲SSRF+CSP绕过实现XSS
  • 使用ROS资源编排一键部署LNMP建站环境,手动整理教程
  • @PostConstruct和afterPropertiesSet方法执行多次的原因
  • DirectX 11 和 Direct3D 11 的关系
  • WordPress官方发布“新”插件“SCF”(安全自定义字段)