智能车竞赛-大小级菜单编写的思路

目录

须知

大小级菜单

各级页面

按键初始化与按键扫描

最后


须知

我使用的是四个按键操作,2寸的IPS显示。

智能车竞赛-大小级菜单编写的思路_第1张图片

大小级菜单

大小级菜单就是在一个页面跳到另一个页面。类似于老年机的操作逻辑,在每个页面可以设置自己想要的东西,通过IPS、TFT或者OLED来显示,按键用来调参或者跳转页面。Dispay_Codename做为每个页面的编号。在每个页面中扫描按键可以更改Dispay_Codename页面编号,在函数外边使用while就可以因为Dispay_Codename页面编号的改变而改变页面。结束菜单系统的话,我选择按键4,当扫描按键4按下就结束菜单系统,进入跑车的环节。

//-------------------------------------------------------------------------------------------------------------------
//  @brief      菜单目录
//  @param      Dispay_Codename    页面编号
//  @param      
//  @param
//  @param
//  @return     void
//  @note       启用while来显示目标页面  在每个页面按键按键后都会改变到对应页面,此函数用于更新屏幕显示
//-------------------------------------------------------------------------------------------------------------------
void Keystroke_Menu(void)
{
    switch(Dispay_Codename)
    {
        case 0:
            Keystroke_Menu_HOME();
            break;
        case 1:
            Keystroke_Menu_ONE();
            break;
        case 11:
            Keystroke_Menu_ONE_One();
            break;
        case 12:
            Keystroke_Menu_ONE_Two();
            break;
        case 2:
            Keystroke_Menu_TWO();
            break;
        case 21:
            Keystroke_Menu_TWO_One();
            break;
        case 22:
            Keystroke_Menu_TWO_Two();
            break;
        case 3:
            Keystroke_Menu_THREE();
            break;
        case 31:
            Keystroke_Menu_THREE_One();
            break;
        case 32:
            Keystroke_Menu_THREE_Two();
            break;
    }
}

int mian(void)
{
	DIP_Switch_Init();   //先扫描拨码开关
	Keystroke_Init();    //初始化按键
	Display_Init();      //初始化IPS
	Beep_Init();         //初始化蜂鸣器

	while(1)     //菜单系统
	{
	    DIP_Switch_Contorl();  //拨码开关选择模式  模式0开启菜单系统
	    switch(MODE)           
	    {
	        case 0:
	            Keystroke_Menu();
	            break;
	        case 1:
	            RUN_STAR = 1;
	            break;
	        case 2:
	            RUN_STAR = 1;
	            break;
	        case 3:
	            RUN_STAR = 1;
	            break;
	    }
	    if(RUN_STAR == 1)    //菜单系统中按下按键4,RUN_STAR=1,就可以退出菜单系统
	    {
	        ips200_clear(WHITE);
	        EEPROM_FLASH();
	        if(MODE == 2)
	        {
	            Run_Voltage = 10.7;
	        }
	        else if(MODE == 3)
	        {
                Run_Voltage = 11;
	        }
	        break;
	    }
	}

	All_Config_CPU0();    //各个模块初始化
}

各级页面

一级主页面:用于去到二级页面。我因为不需要使用太多的页面,所以我选择按键直接进入:按键1、2、3用于进入对应页面,按键4用于结束菜单系统开始跑车,我的二级菜单也是两个或者一个小页面。如果需要分得较多的话可以使用小光标的方式,在每个页面标题前边跳动一个小光标,当光标对应到标题前边时,可以选择是否进入页面。

智能车竞赛-大小级菜单编写的思路_第2张图片智能车竞赛-大小级菜单编写的思路_第3张图片

 二级页面:用于去到三级页面或者调参。用于去到三级页面:按键1、2用于去到对应页面,按键3用于返回上一页面。用于调参:按键1用于+,按键2用于-,按键3用于返回上一页面。按键4始终作为结束菜单系统的按键。

void Keystroke_Menu_HOME(void)    //页面编号0
{
    ips200_showstr(0,0,"Parameter");   //参数页面     按键 1
    ips200_showstr(0,6,"Encoder");     //编码计数页面 按键 2
    ips200_showstr(0,12,"Control");    //控制策略页面 按键 3
    ips200_showstr(0,18,"Run");        //运行开关     按键 4
    Keystroke_Scan();                  //按键扫描函数,用于确定按下哪个按键
    switch(KeystrokeLabel)
    {
        case 0 :
            Dispay_Codename = 0;
            break;
        case KeystrokeONE :
            Dispay_Codename = 1;
            ips200_clear(WHITE);
            break;
        case KeystrokeTWO :
            Dispay_Codename = 2;
            ips200_clear(WHITE);
            break;
        case KeystrokeTHREE :
            Dispay_Codename = 3;
            ips200_clear(WHITE);
            break;
        case KeystrokeFOUR :
            RUN_STAR = 1;
            ips200_clear(WHITE);
            break;
    }
}

//-------------------------------------------------------------------------------------------------------------------
//  @brief      控制菜单目录
//  @param
//  @param
//  @param
//  @param
//  @return     void
//  @note       此页面为编号为2
//-------------------------------------------------------------------------------------------------------------------
void Keystroke_Menu_TWO(void) //2
{
    EEPROM_GarageDistance = flash_read(EEPROM_DistanceG,0,uint16);
    EEPROM_ChBat = flash_read(EEPROM_DistanceC,0,float);
    ips200_showstr(0,0,"GarageDistance");
    ips200_showuint16(120,0,EEPROM_GarageDistance);
    ips200_showstr(0,6,"CHBAT");
    ips200_showfloat(120,6,EEPROM_ChBat,2,1);
    Keystroke_Scan();
    switch(KeystrokeLabel)
    {
        case 0 :
            Dispay_Codename = 2;
            break;
        case KeystrokeONE :                     //按键1 进入下一页面
            Dispay_Codename = 21;
            ips200_clear(WHITE);
            break;
        case KeystrokeTWO :
            Dispay_Codename = 22;               //按键2 进入下一页面
            ips200_clear(WHITE);
            break;
        case KeystrokeTHREE :                   //按键3 返回上一页面
            Dispay_Codename = 0;
            ips200_clear(WHITE);
            break;
        case KeystrokeFOUR :                    //按键4 结束菜单系统
            RUN_STAR = 1;
            break;
    }
}
//-------------------------------------------------------------------------------------------------------------------
//  @brief      控制菜单中的出库编码器计步菜单
//  @param
//  @param
//  @param
//  @param
//  @return     void
//  @note       此页面为编号为21
//-------------------------------------------------------------------------------------------------------------------
void Keystroke_Menu_TWO_One(void)   //21
{
    EEPROM_GarageDistance = flash_read(EEPROM_DistanceG,0,uint16);
    ips200_showstr(0,0,"GarageDistance");
    ips200_showuint16(120,0,EEPROM_GarageDistance);
    Keystroke_Scan();
    switch(KeystrokeLabel)
    {
        case 0 :
            Dispay_Codename = 21;
            break;
        case KeystrokeONE :                  //按键1 目标编码值+100  使用flash
            EEPROM_GarageDistance = flash_read(EEPROM_DistanceG,0,uint16);
            EEPROM_GarageDistance += 100;
            if(flash_check(EEPROM_DistanceG,0) == 1)
            {
                eeprom_erase_sector(EEPROM_DistanceG);
            }
            Write_Date = (uint32)EEPROM_GarageDistance;
            eeprom_page_program(EEPROM_DistanceG,0,&Write_Date);
            Dispay_Codename = 21;
            ips200_clear(WHITE);
            break;
        case KeystrokeTWO :                  //按键2 目标编码值-100  使用flash
            EEPROM_GarageDistance = flash_read(EEPROM_DistanceG,0,uint16);
            EEPROM_GarageDistance = EEPROM_GarageDistance - 100;
            if(flash_check(EEPROM_DistanceG,0) == 1)
            {
                eeprom_erase_sector(EEPROM_DistanceG);
            }
            Write_Date = (uint32)EEPROM_GarageDistance;
            eeprom_page_program(EEPROM_DistanceG,0,&Write_Date);
            Dispay_Codename = 21;
            ips200_clear(WHITE);
            break;
        case KeystrokeTHREE :                //按键3 返回上一页面
            Dispay_Codename = 2;
            ips200_clear(WHITE);
            break;
        case KeystrokeFOUR :                 //按键4 结束菜单页面
            RUN_STAR = 1;
            break;
    }
}

按键初始化与按键扫描

const PIN_enum ButtonPins[ButtonCnt] =
{
    P15_6,
    P15_8,
    P14_0,
    P15_7
};
//-------------------------------------------------------------------------------------------------------------------
//  @brief      按键初始化
//  @param
//  @param
//  @param
//  @param
//  @return     void
//  @note
//-------------------------------------------------------------------------------------------------------------------
void Keystroke_Init(void)
{
    for(uint8 Cnt=0;Cnt

按键扫描应该出现在各个页面显示中。

最后

菜单系统可以各种花里胡哨,但是核心思路是如何能显示各个页面,如何达到目的。本文章写的非常粗糙,详情源代码:「菜单系统」https://www.aliyundrive.com/s/uZ1YRMLhrbS 。智能车的代码已经全部开源,开源地址:GitHub - StingeMoZGD/17th-SmartCar: 17届智能车竞赛,无线充电组

在B站上有演示视频:【智能车菜单系统-极其简单的按键系统】 https://www.bilibili.com/video/BV1n14y1s7c1?share_source=copy_web&vd_source=dcee5db3a992452fdf8223dc0bb853e2

如果有什么不理解的地方可以评论或私信我,欢迎各位多多交流。

你可能感兴趣的:(c++)