找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4194|回复: 0
收起左侧

MSP430单片机非阻塞性菜单程序设计

[复制链接]
ID:108615 发表于 2016-3-14 19:50 | 显示全部楼层 |阅读模式
本程序是《MSP430系列单片机系统工程设计与实践》书里面的源码,(包含工程文件  例4.3.2)完整例程下载:http://www.51hei.com/bbs/dpj-46245-1.html


关于本程序的详细解说大家可以点击上图下载电子书

主程序main:
  1. /*
  2.                
  3.                          菜单程序范例(温度报警器)


  4.   说明:利用状态机实现非阻塞性的菜单。


  5.   (C)西安电子科技大学 测控技术与仪器教研中心   编 写:谢 楷 2008/07/01
  6.   
  7. */
  8. //
  9. //                   MSP430FE425
  10. //             ----------------------
  11. //            |                   XIN|-
  12. //            |                      | 32kHz
  13. //            |RST               XOUT|-
  14. //            |                      |    +----------------------+
  15. //            |A0.6+ -|        S0-S15|--->|   SoftBaugh LCD_048  |
  16. //            |A0.6-  |     COM0-COM3|--->|   7.1Digit,4-Mux LCD |
  17. //            |     | |              |    +----------------------+
  18. //            |     | |         VREF |---+
  19. //      (P1.5)|    \| |/             |   |
  20. //   KEY1---->|     \_/              |  -+- 100nF
  21. //   ADD+     |    内部              |  -+-
  22. //            | 温度传感器           |   |
  23. //      (P1.6)|                 AVss |---+
  24. //   KEY2---->|                      |
  25. //   SUB-     |                      |
  26. //            |                      |
  27. //      (P1.7)|                      |
  28. //   KEY3---->|                      |
  29. //   ENT      |                      |
  30. //*****************************************************************************
  31. #include "MSP430X42X.h"      /*430单片机寄存器头文件*/
  32. #include "LCD_Display.h"     /*LCD显示函数库头文件*/
  33. #include "BasicTimer.h"      /*基础定时器函数库头文件*/
  34. #include "ADC16.h"           /*16位ADC函数库头文件*/
  35. #include "Menu.h"            /*菜单各函数的头文件*/
  36. #define LED_RED_ON      P1OUT|=BIT3
  37. #define LED_RED_OFF     P1OUT&=~BIT3
  38. #define LED_GREEN_ON    P1OUT|=BIT1
  39. #define LED_GREEN_OFF   P1OUT&=~BIT1


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

  42. /****************************************************************************
  43. * 名    称:main()主程序
  44. * 功    能:每1秒采集温度一次并显示;每1/16秒扫描一次按键并处理。
  45. * 入口参数:无
  46. * 出口参数:无
  47. ****************************************************************************/
  48. void main( void )
  49. { int i;
  50.   int ADC_Result=0;
  51.   int DegC;int Timer=0;
  52.   WDTCTL=WDTPW+WDTHOLD;  //停止看门狗
  53.   FLL_CTL0|=XCAP18PF;          //配置晶振负载电容
  54.   P1DIR|=BIT0+BIT1+BIT2+BIT3+BIT4;
  55.   P2DIR|=BIT0+BIT1+BIT2+BIT3;       //悬空的IO口要置为输出
  56.   P1OUT =0;                         //不确定电平会造成IO耗电
  57.   P2OUT =0;   
  58.   BT_Init(16);                      //BasicTimer设置为1/16秒中断(唤醒)CPU一次
  59.   LCD_Init();                       //LCD初始化
  60.   ADC16_Init(0,6,'S',1);//ADC16初始化,设置ADC0采样温度传感器,有符号,增益=1
  61.   Menu_DefaultSettings();
  62.   Menu_LoadSettings();
  63.   while(1)
  64.   {
  65.     Cpu_SleepWaitBT();//CPU休眠,等待被BasicTimer唤醒
  66.     Timer++;
  67.     Menu_Process();                     // 菜单处理
  68.     if(Timer>=16)   //---------以下代码每1秒执行一次-----------
  69.     {  Timer=0;      
  70.        ADC16_VrefOn();                  //打开基准源
  71.        for(i=0;i<30;i++);               //略等待,等基准稳定
  72.        ADC_Result=ADC16_Sample(0,1);    //采样ADC0,单次采样
  73.        ADC16_VrefOff();                 //关闭基准源
  74.        DegC=((long int)ADC_Result * 9090)/65536 - 2730;//计算摄氏度
  75.        DegC-=T_OFFSET;                  //扣除校准偏移量
  76.        if(Menu_State==MENU_QUIT)
  77.        {
  78.         LCD_DisplayDecimal(DegC,1);//显示摄氏度,带1位小数
  79.         LCD_InsertChar(DT);         
  80.         LCD_InsertChar(CC);              // 尾部添加单位: 'C
  81.        }
  82.        if(DegC>=Alarm_H) LED_RED_ON;
  83.        else              LED_RED_OFF;   // 上限报警
  84.        if(DegC<=Alarm_L) LED_GREEN_ON;
  85.        else              LED_GREEN_OFF; // 下限报警      
  86.     }
  87.   }
  88. }
复制代码

菜单子程序:
  1. #include <msp430x42x.h>
  2. #include "KEY.h"
  3. #include "LCD_Display.h"
  4. #include "Flash.h"
  5. #include "BasicTimer.h"
  6. #define ADDR_DEFAULT    0  /*第一次上电标志*/
  7. #define ADDR_AH         2  /*报警门限上限存储地址*/
  8. #define ADDR_AL         4  /*报警门限下限存储地址*/
  9. int Alarm_H;
  10. int Alarm_L;               /*报警上下限全局变量*/
  11. int Menu_Temp;            //调整数据的临时变量(为了实现放弃保存功能)

  12. char Menu_State=0;
  13. #define MENU_QUIT     0
  14. #define MENU_SET      1
  15. #define MENU_AH       2
  16. #define MENU_AL       3
  17. #define MENU_END      4

  18. /*************************************************************************
  19. * 名    称:Menu_SetValue()
  20. * 功    能:调整数值的大小
  21. * 入口参数:Value: 当前数值
  22.                 Key:按键
  23.                         MIN:被调整参数的最小值
  24.                         MAX:被调整参数的最大值
  25.                         Step:长按键的调整步长
  26. * 出口参数:被调整后的参数值
  27. * 说    明: 参数超过最大值,会变为最小值。小于最小值会变为最大值。
  28. *************************************************************************/
  29. int Menu_SetValue(int Value,char Key,int MIN,int MAX, int Step)
  30. {   switch(Key)
  31.      {
  32.       case KEY_ADD:         Value++;        break;  // 加减按键的处理
  33.       case KEY_SUB:        Value--;        break;
  34.       case KEY_ADD_L: Value+=Step;        break;  // 长按键的处理
  35.       case KEY_SUB_L:        Value-=Step;        break;
  36.       default:                                break;
  37.      }                       
  38.     if (Value>MAX) Value=MIN;                        //超量程处理
  39.     if (Value<MIN) Value=MAX;                        //超量程处理     
  40.    return(Value);
  41. }

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

  58. /*************************************************************************
  59. * 名    称:Menu_LoadSettings()
  60. * 功    能:从存储器中调出设置参数
  61. * 入口参数:无
  62. * 出口参数:无
  63. * 说    明: 主循环开始之前执行
  64. *************************************************************************/
  65. void Menu_LoadSettings()
  66. {
  67.    Alarm_H=Flash_ReadWord(ADDR_AH);      //读取温度上限
  68.    Alarm_L=Flash_ReadWord(ADDR_AL);      //读取温度上限   
  69. }



  70. /*************************************************************************
  71. * 名    称:Menu_Process()
  72. * 功    能:菜单程序
  73. * 入口参数:无
  74. * 出口参数:无
  75. * 说    明: 利用状态机实现的菜单,该程序不阻塞CPU的执行
  76. *************************************************************************/
  77. void Menu_Process()
  78. {
  79.   char Key;
  80.   Key=Key_GetKey();   //从键盘缓冲区读取一次按键
  81.   static int Timer;
  82.   static int TimeOutTimer;
  83.   switch(Menu_State)
  84.   {
  85.     case MENU_QUIT: if(Key==KEY_ENT_FL) Menu_State=MENU_SET;
  86.                     break;
  87.     case MENU_SET:  LCD_Clear();
  88.                     LCD_DisplayChar(SS,2);
  89.                     LCD_DisplayChar(EE,1);   // 显示"SET",提示菜单开始
  90.                     LCD_DisplayChar(tt,0);
  91.                     if(Key==KEY_ENT)   
  92.                       {
  93.                         Menu_Temp=Alarm_H;
  94.                         Menu_State=MENU_AH;
  95.                       }  
  96.                     break;
  97.     case MENU_AH :  Menu_Temp=Menu_SetValue(Menu_Temp,Key,-200,500,10);// 根据按键调整参数数值
  98.                     LCD_DisplayDecimal(Menu_Temp,1); // 显示温度上限值,保留一位小数
  99.                     LCD_DisplayChar(AA,6);
  100.                     LCD_DisplayChar(HH,5);           // 提示符"AH"        
  101.                     if(Key==KEY_ENT)
  102.                       {
  103.                         Alarm_H=Menu_Temp;               // 更新报警上限全局变量
  104.                         Flash_WriteWord(ADDR_AH,Alarm_H);// 报警上限值写入Flash
  105.                         Menu_Temp=Alarm_L;
  106.                         Menu_State=MENU_AL;
  107.                       }
  108.                     if(Key==KEY_ENT_FL)
  109.                       {
  110.                         Menu_Temp=Alarm_L;
  111.                         Menu_State=MENU_AL;
  112.                       }
  113.                     break;
  114.     case MENU_AL :  Menu_Temp=Menu_SetValue(Menu_Temp,Key,-200,500,10);// 根据按键调整参数数值
  115.                     LCD_DisplayDecimal(Menu_Temp,1);      // 显示温度下限值,保留一位小数
  116.                     LCD_DisplayChar(AA,6);
  117.                     LCD_DisplayChar(LL,5);               // 提示符"AL"  
  118.                     if(Key==KEY_ENT)
  119.                       {
  120.                         Alarm_L=Menu_Temp;               // 更新报警上限全局变量
  121.                         Flash_WriteWord(ADDR_AL,Alarm_L);// 报警上限值写入Flash
  122.                         Menu_State=MENU_END;
  123.                       }
  124.                     if(Key==KEY_ENT_FL) Menu_State=MENU_END;
  125.                     break;                       
  126.    case MENU_END :  LCD_Clear();
  127.                     LCD_DisplayChar(EE,2);
  128.                     LCD_DisplayChar(nn,1);   // 显示"End",提示菜单结束
  129.                     LCD_DisplayChar(DD,0);
  130.                     if(++Timer>16) {Timer=0;Menu_State=MENU_QUIT;}//0.5秒后退出
  131.                     break;
  132.     }
  133. //---------------------------超时退出-----------------------------------
  134.   if(Key!=0) TimeOutTimer=0;  //任何按键都可以将无操作时间清零
  135.   if(Menu_State!=MENU_QUIT)   //在菜单中,对无操作时间计时
  136.    {
  137.      TimeOutTimer++;        
  138.      if(TimeOutTimer>160) Menu_State = MENU_QUIT; //无操作超过10秒,退出菜单
  139.    }
  140.   else TimeOutTimer=0;
  141. //---------------------------------------------------------------------  
  142. }
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表