博客
关于我
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与mem_细说 MySQL 之 MEM_ROOT
    查看>>
    MySQL与Oracle的数据迁移注意事项,另附转换工具链接
    查看>>
    mysql丢失更新问题
    查看>>
    MySQL两千万数据优化&迁移
    查看>>
    MySql中 delimiter 详解
    查看>>
    MYSQL中 find_in_set() 函数用法详解
    查看>>
    MySQL中auto_increment有什么作用?(IT枫斗者)
    查看>>
    MySQL中B+Tree索引原理
    查看>>
    mysql中cast() 和convert()的用法讲解
    查看>>
    mysql中datetime与timestamp类型有什么区别
    查看>>
    MySQL中DQL语言的执行顺序
    查看>>
    mysql中floor函数的作用是什么?
    查看>>
    MySQL中group by 与 order by 一起使用排序问题
    查看>>
    mysql中having的用法
    查看>>
    MySQL中interactive_timeout和wait_timeout的区别
    查看>>
    mysql中int、bigint、smallint 和 tinyint的区别、char和varchar的区别详细介绍
    查看>>
    mysql中json_extract的使用方法
    查看>>
    mysql中json_extract的使用方法
    查看>>
    mysql中kill掉所有锁表的进程
    查看>>
    mysql中like % %模糊查询
    查看>>