使用软件模拟按键显示屏,上下左右确认取消按键,来修改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");
}
}
}