[资料分享] MSP430单片机阻塞性菜单程序设计

fish001   2017-8-25 16:11 楼主
主程序mian
/*

                         菜单程序范例(温度报警器)


  说明:在《温度计_基本原理》程序中,已经实现了一个温度测量和显示的系统,为其
        添加菜单。


  (C)西安电子科技大学 测控技术与仪器教研中心   编 写:谢 楷 2008/06/30

*/
//
//                   MSP430FE425
//             ----------------------
//            |                   XIN|-
//            |                      | 32kHz
//            |RST               XOUT|-
//            |                      |    +----------------------+
//            |A0.6+ -|        S0-S15|--->|   SoftBaugh LCD_048  |
//            |A0.6-  |     COM0-COM3|--->|   7.1Digit,4-Mux LCD |
//            |     | |              |    +----------------------+
//            |     | |         VREF |---+
//      (P1.5)|    \| |/             |   |
//   KEY1---->|     \_/              |  -+- 100nF
//   ADD+     |    内部              |  -+-
//            | 温度传感器           |   |
//      (P1.6)|                 AVss |---+
//   KEY2---->|                      |
//   SUB-     |                      |
//            |                      |
//      (P1.7)|                      |
//   KEY3---->|                      |
//   ENT      |                      |
//*****************************************************************************
#include "MSP430X42X.h"      /*430单片机寄存器头文件*/
#include "LCD_Display.h"     /*LCD显示函数库头文件*/
#include "BasicTimer.h"      /*基础定时器函数库头文件*/
#include "ADC16.h"           /*16位ADC函数库头文件*/
#include "Menu.h"            /*菜单各函数的头文件*/
#define LED_RED_ON      P1OUT|=BIT3
#define LED_RED_OFF     P1OUT&=~BIT3
#define LED_GREEN_ON    P1OUT|=BIT1
#define LED_GREEN_OFF   P1OUT&=~BIT1


#define T_OFFSET (0)         /*25度左右条件下,显示温度减去标准温度计温度*/
                             /*作为校准偏移值。注意要乘10倍,10=1.0度*/

/****************************************************************************
* 名    称:main()主程序
* 功    能:每1秒采集温度一次并显示;每1/16秒扫描一次按键并处理。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void main( void )
{ int i;
  int ADC_Result=0;
  int DegC;int Timer=0;
  WDTCTL=WDTPW+WDTHOLD;  //停止看门狗
  FLL_CTL0|=XCAP18PF;          //配置晶振负载电容
  P1DIR|=BIT0+BIT1+BIT2+BIT3+BIT4;
  P2DIR|=BIT0+BIT1+BIT2+BIT3;       //悬空的IO口要置为输出
  P1OUT =0;                         //不确定电平会造成IO耗电
  P2OUT =0;   
  BT_Init(16);                      //BasicTimer设置为1/16秒中断(唤醒)CPU一次
  LCD_Init();                       //LCD初始化
  ADC16_Init(0,6,'S',1);//ADC16初始化,设置ADC0采样温度传感器,有符号,增益=1
  Menu_DefaultSettings();
  Menu_LoadSettings();
  while(1)
  {
    Cpu_SleepWaitBT();//CPU休眠,等待被BasicTimer唤醒
    Timer++;
    if(Timer>=16)   //---------以下代码每1秒执行一次-----------
    {  Timer=0;      
       ADC16_VrefOn();                  //打开基准源
       for(i=0;i<30;i++);               //略等待,等基准稳定
       ADC_Result=ADC16_Sample(0,1);    //采样ADC0,单次采样
       ADC16_VrefOff();                 //关闭基准源
       DegC=((long int)ADC_Result * 9090)/65536 - 2730;//计算摄氏度
       DegC-=T_OFFSET;                  //扣除校准偏移量
       LCD_DisplayDecimal(DegC,1);      //显示摄氏度,带1位小数
       LCD_InsertChar(DT);         
       LCD_InsertChar(CC);              // 尾部添加单位: 'C
       if(DegC>=Alarm_H) LED_RED_ON;
       else              LED_RED_OFF;   // 上限报警
       if(DegC<=Alarm_L) LED_GREEN_ON;
       else              LED_GREEN_OFF; // 下限报警      
       Menu_Process();                  // 菜单处理
    }
  }
}
复制代码

菜单子程序:
#include
#include "KEY.h"
#include "LCD_Display.h"
#include "Flash.h"
#include "BasicTimer.h"
#define ADDR_DEFAULT    0  /*第一次上电标志*/
#define ADDR_AH         2  /*报警门限上限存储地址*/
#define ADDR_AL         4  /*报警门限下限存储地址*/
int Alarm_H;
int Alarm_L;               /*报警上下限全局变量*/

/*************************************************************************
* 名    称:Menu_SetValue()
* 功    能:调整数值的大小
* 入口参数:Value: 当前数值
                Key:按键
                        MIN:被调整参数的最小值
                        MAX:被调整参数的最大值
                        Step:长按键的调整步长
* 出口参数:被调整后的参数值
* 说    明: 参数超过最大值,会变为最小值。小于最小值会变为最大值。
*************************************************************************/
int Menu_SetValue(int Value,char Key,int MIN,int MAX, int Step)
{   switch(Key)
     {
      case KEY_ADD:         Value++;        break;  // 加减按键的处理
      case KEY_SUB:        Value--;        break;
      case KEY_ADD_L: Value+=Step;        break;  // 长按键的处理
      case KEY_SUB_L:        Value-=Step;        break;
      default:                                break;
     }                       
    if (Value>MAX) Value=MIN;                        //超量程处理
    if (Value    return(Value);
}

/*************************************************************************
* 名    称:Menu_DefaultSettings()
* 功    能:初始化各参数,写为默认值
* 入口参数:无
* 出口参数:无
* 说    明: 该函数内的参数初始化程序只会在第一次通电时执行
*************************************************************************/
void Menu_DefaultSettings()
{
  if(Flash_ReadChar(ADDR_DEFAULT)!=0x00)    //如果第0单元内容非0(第一次上电)
     {
        Flash_WriteWord(ADDR_AH,400);      //上限40.0度
        Flash_WriteWord(ADDR_AL,0);            //下限0度
        Flash_WriteChar(ADDR_DEFAULT,0x00); //第0单元写入0(以后再也不运行)
     }
}

/*************************************************************************
* 名    称:Menu_LoadSettings()
* 功    能:从存储器中调出设置参数
* 入口参数:无
* 出口参数:无
* 说    明: 主循环开始之前执行
*************************************************************************/
void Menu_LoadSettings()
{
   Alarm_H=Flash_ReadWord(ADDR_AH);      //读取温度上限
   Alarm_L=Flash_ReadWord(ADDR_AL);      //读取温度上限   
}


/*************************************************************************
* 名    称:Menu_SettingAH()
* 功    能:报警上限设置
* 入口参数:无
* 出口参数:无
* 说    明: 该程序会阻塞CPU的执行
*************************************************************************/
void Menu_SettingAH()
{
   int Temp;                                    // 临时变量
   char Key;                                    // 按键
   Temp=Alarm_H;                                // 被调整的变量是Alarm_H
   while(1)                                     // 每项菜单设置都是一个死循环
   {
     LCD_DisplayDecimal(Temp,1);                //显示温度上限值,保留一位小数
     LCD_DisplayChar(AA,6);
     LCD_DisplayChar(HH,5);                     //提示符"AH"
     Key=Key_WaitKey();                         // 等待一次按键
     Temp=Menu_SetValue(Temp,Key,-200,500,10);  //根据按键调整参数数值
     if(Key==KEY_ENT)                           //当ENT键按下时
      {
         Alarm_H=Temp;                          //更新报警上限全局变量
         Flash_WriteWord(ADDR_AH,Alarm_H);      //报警上限值写入Flash
         return;                                //退出本项菜单循环
      }
     if(Key==KEY_ENT_FL) return;                //当ENT键长按时,不保存直接退出
   }
}

/*************************************************************************
* 名    称:Menu_SettingAL()
* 功    能:报警下限设置
* 入口参数:无
* 出口参数:无
* 说    明: 该程序会阻塞CPU的执行
*************************************************************************/
void Menu_SettingAL()
{
   int Temp;                                    // 临时变量
   char Key;                                    // 按键
   Temp=Alarm_L;                                // 被调整的变量是Alarm_L
   while(1)                                     // 每项菜单设置都是一个死循环
   {
     LCD_DisplayDecimal(Temp,1);                // 显示温度上限值,保留一位小数
     LCD_DisplayChar(AA,6);
     LCD_DisplayChar(LL,5);                     // 提示符"AL"
     Key=Key_WaitKey();                         // 等待一次按键
     Temp=Menu_SetValue(Temp,Key,-200,500,10);  // 根据按键调整参数数值
     if(Key==KEY_ENT)                           // 当ENT键按下时
      {
         Alarm_L=Temp;                          // 更新报警下限全局变量
         Flash_WriteWord(ADDR_AL,Alarm_L);      // 报警上限值写入Flash
         return;                                // 退出本项菜单循环
      }
     if(Key==KEY_ENT_FL) return;                // 当ENT键长按时,不保存直接退出
   }
}

/*************************************************************************
* 名    称:Menu_Process()
* 功    能:菜单程序
* 入口参数:无
* 出口参数:无
* 说    明: 该程序会阻塞CPU的执行
*************************************************************************/
void Menu_Process()
{
  if(Key_GetKey()!=KEY_ENT_FL) return;      // 长按ENT键才能进入菜单
  LCD_Clear();
  LCD_DisplayChar(SS,2);
  LCD_DisplayChar(EE,1);                    // 显示"SET",提示菜单开始
  LCD_DisplayChar(tt,0);
  while(Key_WaitKey()!=KEY_ENT);            // 等待一次短按键(防止连续长键)
//-------------------------------------------------  
  Menu_SettingAH();                         // 设置报警上限
  Menu_SettingAL();                         // 设置报警下限
//-------------------------------------------------  
  LCD_Clear();  
  LCD_DisplayChar(EE,2);
  LCD_DisplayChar(nn,1);                    // 显示"END",提示菜单已结束
  LCD_DisplayChar(DD,0);
  Cpu_SleepDelay(8);                        // "END"持续0.5秒
}

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复