博客
关于我
2019年嵌入式第十届省赛真题解析
阅读量:798 次
发布时间:2023-04-16

本文共 6591 字,大约阅读时间需要 21 分钟。

一、题目

本实验旨在研究如何利用状态机和按键控制的方式来实现电压测量和显示功能。通过分析状态机的运行逻辑和按键的交互作用,设计并实现对电压数据的采集、存储、处理和显示。


二、分析

实验中,状态机负责根据电压数据的变化而进行相应的状态切换和操作。按键则用于控制状态机的运行逻辑和参数设置。整个系统主要分为以下两部分:

  • 按键控制的状态机

    按键负责触发状态机的状态切换和参数调整。具体来说,按键1用于切换显示界面,按键2用于状态的前后循环,按键3和4分别用于增加和减少电压范围及灯的亮度。

  • 状态机的动作和变换

    状态机根据当前电压值和按键输入的变化,执行以下操作:

    • 切换显示界面(状态0与其他状态之间切换)。
    • 调整最大值和最小值(状态1和状态2)。
    • 调整上限和下限灯的亮度(状态3和状态4)。

  • 三、程序

    1. 按键控制逻辑

    void Key_Proc(void) {    // 减速函数,避免抖动问题    if ((uwTick - uwTick_Key_Set_Point) < 50) {        return;    }    uwTick_Key_Set_Point = uwTick;    ucKey_Val = Key_Scan(); // 扫描按键状态    unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val); // 刚才被按下    ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val); // 刚才被释放    ucKey_Old = ucKey_Val;    if (unKey_Down == 1) { // 切换界面        if (state == 0) {            state = 1;            LCD_Clear(White);        } else if (state == 1 || state == 2 || state == 3 || state == 4) {            if (upp_led != low_led && max_v > min_v) {                state = 0;                LCD_Clear(White);                max = max_v * 10;                min = min_v * 10;                Iic_24c02_write(&max, 0, 1);                HAL_Delay(10);                Iic_24c02_write(&min, 1, 1);                HAL_Delay(10);                Iic_24c02_write(&upp_led, 2, 1);                HAL_Delay(10);                Iic_24c02_write(&low_led, 3, 1);                HAL_Delay(10);            }        }    }    if (unKey_Down == 2) { // 状态前后循环        if (state != 0) {            if (++state == 5) {                state = 1;            }        }    }    if (unKey_Down == 3) { // 增加        switch (state) {            case 1:                max_v += 0.3;                if ((max_v + 0.3) > 3.3) {                    max_v = 3.3;                }                break;            case 2:                if ((max_v - min_v) > 0.3) {                    min_v += 0.3;                }                break;            case 3:                if (++upp_led > 8) {                    upp_led = 8;                }                if (upp_led == low_led) {                    if (low_led == 8) {                        upp_led = 7;                    } else {                        if (++upp_led > 8) {                            upp_led = 8;                        }                    }                }                break;            case 4:                if (++low_led > 8) {                    low_led = 8;                }                if (upp_led == low_led) {                    if (upp_led == 8) {                        low_led = 7;                    } else {                        if (++low_led > 8) {                            low_led = 8;                        }                    }                }                break;        }    }    if (unKey_Down == 4) { // 减少        switch (state) {            case 1:                if ((max_v - min_v) > 0.3) {                    max_v -= 0.3;                }                break;            case 2:                min_v -= 0.3;                if ((min_v - 0.3) < 0) {                    min_v = 0;                }                break;            case 3:                if (--upp_led == 0) {                    upp_led = 1;                }                if (upp_led == low_led) {                    if (low_led == 1) {                        upp_led = 2;                    } else {                        if (--upp_led == 0) {                            upp_led = 1;                        }                    }                }                break;            case 4:                if (--low_led == 0) {                    low_led = 1;                }                if (upp_led == low_led) {                    if (upp_led == 1) {                        low_led = 2;                    } else {                        if (--upp_led == 0) {                            upp_led = 1;                        }                    }                }                break;        }    }}

    2. LED显示逻辑

    void Led_Proc(void) {    // 减速函数,避免闪烁问题    if ((uwTick - uwTick_Led_Set_Point) < 200) {        return;    }    uwTick_Led_Set_Point = uwTick;    if (v37 > max_v) {        ucLed = 0;        ucLed ^= (1 << (upp_led - 1));        disp = 2; // 高亮显示    } else if (v37 < min_v) {        ucLed ^= (1 << (low_led - 1));        disp = 0; // 低亮显示    } else if (v37 >= min_v && v37 <= max_v) {        ucLed = 0;        disp = 1; // 正常显示    }    LED_Disp(ucLed);}

    3. LCD显示逻辑

    void Lcd_Proc(void) {    // 减速函数,避免显示问题    if ((uwTick - uwTick_Lcd_Set_Point) < 100) {        return;    }    uwTick_Lcd_Set_Point = uwTick;    v37 = 3.3 * getADC2() / 4096;    if (state == 0) { // 数据显示模式        sprintf(Lcd_Disp_String, "        Main    ");        LCD_DisplayStringLine(Line2, Lcd_Disp_String);        sprintf(Lcd_Disp_String, "     Volt: %4.2f V  ", v37);        LCD_DisplayStringLine(Line5, Lcd_Disp_String);        switch (disp) {            case 0:                sprintf(Lcd_Disp_String, "     Status: Lower    ");                break;            case 1:                sprintf(Lcd_Disp_String, "     Status: Normal    ");                break;            case 2:                sprintf(Lcd_Disp_String, "     Status: Upper    ");                break;        }        LCD_DisplayStringLine(Line7, Lcd_Disp_String);    } else { // 设置模式        LCD_SetBackColor(White);        sprintf(Lcd_Disp_String, "        Setting    ");        LCD_DisplayStringLine(Line1, Lcd_Disp_String);        if (state == 1) {            LCD_SetBackColor(Green);        } else {            LCD_SetBackColor(White);        }        sprintf(Lcd_Disp_String, "Max Volt: %3.1fV    ", max_v);        LCD_DisplayStringLine(Line3, Lcd_Disp_String);        LCD_SetBackColor(White);        if (state == 2) {            LCD_SetBackColor(Green);        } else {            LCD_SetBackColor(White);        }        sprintf(Lcd_Disp_String, "Min Volt: %3.1fV    ", min_v);        LCD_DisplayStringLine(Line5, Lcd_Disp_String);        LCD_SetBackColor(White);        if (state == 3) {            LCD_SetBackColor(Green);        } else {            LCD_SetBackColor(White);        }        sprintf(Lcd_Disp_String, "Upper: LD%d         ", upp_led);        LCD_DisplayStringLine(Line7, Lcd_Disp_String);        LCD_SetBackColor(White);        if (state == 4) {            LCD_SetBackColor(Green);        } else {            LCD_SetBackColor(White);        }        sprintf(Lcd_Disp_String, "Lower: LD%d         ", low_led);        LCD_DisplayStringLine(Line9, Lcd_Disp_String);        LCD_SetBackColor(White);    }}

    四、总结

    通过本实验,我们成功实现了电压测量、显示和设置功能。状态机与按键控制的结合,使得系统具有良好的灵活性和可扩展性。未来可以通过增加更多的功能模块和优化代码来进一步提升系统性能。

    转载地址:http://qygfk.baihongyu.com/

    你可能感兴趣的文章
    MySQL Order By实现原理分析和Filesort优化
    查看>>
    mysql problems
    查看>>
    mysql replace first,MySQL中处理各种重复的一些方法
    查看>>
    MySQL replace函数替换字符串语句的用法(mysql字符串替换)
    查看>>
    mysql replace用法
    查看>>
    Mysql Row_Format 参数讲解
    查看>>
    mysql select, from ,join ,on ,where groupby,having ,order by limit的执行顺序和书写顺序
    查看>>
    MySQL Server 5.5安装记录
    查看>>
    mysql server has gone away
    查看>>
    mysql slave 停了_slave 停止。求解决方法
    查看>>
    MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
    查看>>
    MYSQL sql语句针对数据记录时间范围查询的效率对比
    查看>>
    mysql sum 没返回,如果没有找到任何值,我如何在MySQL中获得SUM函数以返回'0'?
    查看>>
    mysql Timestamp时间隔了8小时
    查看>>
    Mysql tinyint(1)与tinyint(4)的区别
    查看>>
    mysql union orderby 无效
    查看>>
    mysql v$session_Oracle 进程查看v$session
    查看>>
    mysql where中如何判断不为空
    查看>>
    MySQL Workbench 使用手册:从入门到精通
    查看>>
    mysql workbench6.3.5_MySQL Workbench
    查看>>