基于MSP430实现的多级菜单功能
通过MSP430核心板的ADC监测IO板模拟输出管脚的变化,判断哪一个按键或编码器的旋转发生了变化,进而控制1.44寸LCD屏幕的菜单显示,实现了主菜单和二级菜单。
标签
MSP430
2023寒假在家练
多级菜单
冷月烟
更新2023-03-27
486

项目介绍

通过MSP430核心板的ADC监测IO板模拟输出管脚的变化,判断哪一个按键或编码器的旋转发生了变化,进而控制1.44寸LCD屏幕的菜单显示,实现了主菜单和二级菜单。

设计思路

1.按键检测

IO扩展板上的2个按键和旋转编码器的3个输入端口是通过R-2R电阻网络的方式连接在一起,生成一个模拟电压量。按下任何一个按键都会改变这个模拟电压量的值。这时,输出的电压就会发生变化,单片机不断采集ADC数据,通过读取电压值判断出哪一个按键被按下。

2.多级菜单

多级菜单的实现,大体分为两种设计思路:通过双向链表实现、通过数组查表实现。

总体思路都是把菜单的各个界面联系起来,可以从上级菜单跳到下级菜单,也可从下级菜单返回上级菜单。

数组查表的方式比较简单,易于理解,本篇就来使用数组查表发在MSP430上实现多级菜单的显示。

3.屏幕显示

通过SPI总线进行访问LCD屏幕,其为128*128分辨率的1.44寸彩色屏幕。

硬件介绍

FqDKZS7tSDk02vvfs6-ruEvOL7GQFqltf7A1YcLzUmmdMi_5ZH2EK2GN

MSP-EXP430F5529LP是一款针对MSP430F5529 USB微控 制器的廉价而简单的开发套件。它为MSP430 MCU提供了一种简单的方法,具有用于编程和调试的板载仿真,以及用于简单用户界面的按钮和LED。

  • 支持 USB 2.0 的 MSP430F5529 16 位微控制器
  • 高达 25 MHz
  • 128KB 闪存和 8KB 内存
  • 12 位 SAR 模数转换器
  • 提供各种 USB 设备类示例和嵌入式软件库(CDC、HID、MSC)
  • eZ-FET lite:带应用程序 UART 的开源板载调试器
  • 通过使用板载 USB 集线器,为仿真器和目标提供 USB 连接
  • USB 作为电源:5V 和 3.3V 通过高效 DC/DC 转换器
  • 40 针 LaunchPad 标准,利用 BoosterPack 生态系统

Fnc4RDCc6PM5ohGntlk3Y2jpVxwE

扩展板包含如下功能:

  • 按键、旋转编码器输入 - 以模拟信号的方式
  • 双电位计控制输入 - 以数字信号的方式
  • RGB三色LED显示
  • 1.44寸128*128 LCD,SPI总线访问
  • MMA7660三轴姿态传感器
  • 电阻加热
  • 温度传感器
  • 与MSP430 Launch Pad开发板的接口

主要代码

识别编码器与按键动作

void adc_key_change(uint16_t adc)
{
    static uint8_t adc_key = 0;
    static uint8_t his_rev_key = 0;

    if(adc >= 3900)
    {
        if(adc_key == 10)      key_flag = 1;
        else if(adc_key == 11) key_flag = 2;
        adc_key = 0;
        his_rev_key = 0;
    }
    else if(adc < 3000 && adc >= 2890) adc_key = 10;//2940
    else if(adc < 2000 && adc >= 1800) adc_key = 11;//1921
    else if(adc < 3900 && adc >= 3790) adc_key = 1; //3838
    //else if(adc < 3620 && adc >= 3530) ; //3581
    else if(adc < 3760 && adc >= 3660) adc_key = 2; //3709
    if(adc_key != his_rev_key)
    {
        if(his_rev_key == 1 && adc_key == 2)
            revolve_flag = 1;
        else if(his_rev_key == 2 && adc_key == 1)
            revolve_flag = 2;

        his_rev_key = adc_key;
    }
}

菜单定义

typedef struct
{
    uint8_t current;
    uint8_t up;
    uint8_t down;
    uint8_t enter;
    uint8_t back;
    void (*current_operation)();
} key_table;
key_table table[30]=
{
    {0,2,1,3,0,(*fun0)},
    {1,0,2,6,1,(*fun1)},
    {2,1,0,8,2,(*fun2)},

    {3,5,4,3,0,(*fun3)},
    {4,3,5,4,0,(*fun4)},
    {5,4,3,5,0,(*fun5)},

    {6,7,7,6,1,(*fun6)},
    {7,6,6,7,1,(*fun7)},

    {8,9,9,8,2,(*fun8)},
    {9,8,8,9,2,(*fun9)},

};

void fun0()
{
    LCD_ShowString(0,0, "1.LED   ",BLACK,WHITE,32,0);
    LCD_ShowString(0,32,"2.KEY   ",WHITE,BLACK,32,0);
    LCD_ShowString(0,64,"3.LCD   ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun1()
{
    LCD_ShowString(0,0, "1.LED   ",WHITE,BLACK,32,0);
    LCD_ShowString(0,32,"2.KEY   ",BLACK,WHITE,32,0);
    LCD_ShowString(0,64,"3.LCD   ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun2()
{
    LCD_ShowString(0,0, "1.LED   ",WHITE,BLACK,32,0);
    LCD_ShowString(0,32,"2.KEY   ",WHITE,BLACK,32,0);
    LCD_ShowString(0,64,"3.LCD   ",BLACK,WHITE,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun3()
{
    LCD_ShowString(0,0, "1.LED1  ",BLACK,WHITE,32,0);
    LCD_ShowString(0,32,"2.LED2  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,64,"3.LED3  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun4()
{
    LCD_ShowString(0,0, "1.LED1  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,32,"2.LED2  ",BLACK,WHITE,32,0);
    LCD_ShowString(0,64,"3.LED3  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun5()
{
    LCD_ShowString(0,0, "1.LED1  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,32,"2.LED2  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,64,"3.LED3  ",BLACK,WHITE,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun6()
{
    LCD_ShowString(0,0, "1.KEY1  ",BLACK,WHITE,32,0);
    LCD_ShowString(0,32,"2.KEY2  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,64,"        ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun7()
{
    LCD_ShowString(0,0, "1.KEY1  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,32,"2.KEY2  ",BLACK,WHITE,32,0);
    LCD_ShowString(0,64,"        ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun8()
{
    LCD_ShowString(0,0, "1.LCD1  ",BLACK,WHITE,32,0);
    LCD_ShowString(0,32,"2.LCD2  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,64,"        ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}
void fun9()
{
    LCD_ShowString(0,0, "1.LCD1  ",WHITE,BLACK,32,0);
    LCD_ShowString(0,32,"2.LCD2  ",BLACK,WHITE,32,0);
    LCD_ShowString(0,64,"        ",WHITE,BLACK,32,0);
    LCD_ShowString(0,96,"        ",WHITE,BLACK,32,0);
}

菜单控制

for(;;)
{
    adc_key_change(ADC12MEM0);
    if(revolve_flag > 0 || key_flag > 0)
    {
        if(revolve_flag == 1)      func_index=table[func_index].down;
        else if(revolve_flag == 2) func_index=table[func_index].up;
        else if(key_flag == 1)     func_index=table[func_index].enter;
        else if(key_flag == 2)     func_index=table[func_index].back;

        table[func_index].current_operation();
        revolve_flag = 0;
        key_flag = 0;
    }
}

实现的功能及图片展示

主菜单

Fvkx9WQFn1yhQTF3wPXM2s_vd19H

二级菜单 一

FoFWQQZCjBRV7_HFA3AIYzoeO-r-

二级菜单 二

FqiGMJiORSxSZ1TiqzkQdCgj6Qgd

二级菜单 三

FpnyXVzhwrJTpgL7DiCUBxS91Ye6

遇到的主要难题及解决方法

问题:很难抓取到编码器的ADC数值变化,识别不出来旋转方向。

方法:对芯片进行倍频到25MHz,减少显示部分,让空闲时间都在采集ADC数据。但是在编码器旋转速度过快的情况下还是没有办法处理,以后再研究这个问题。

问题:刷新效果差,闪烁严重。

方法:不清屏,显示时多加几个空格,覆盖刷新。

未来的计划或建议

希望加热电路能够有硬件上的关闭开关,或者是把加热电路做成外部的单独模块,避免因为不小心开启加热电路后烫伤手。

附件下载
temp.zip
程序
团队介绍
爱摸鱼的工程师
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号