标题:
MSP430单片机非阻塞性菜单程序设计
[打印本页]
作者:
51hei单片
时间:
2016-3-14 19:50
标题:
MSP430单片机非阻塞性菜单程序设计
本程序是《MSP430系列单片机系统工程设计与实践》书里面的源码,(包含工程文件 例4.3.2)完整例程下载:
http://www.51hei.com/bbs/dpj-46245-1.html
关于本程序的详细解说大家可以点击上图下载电子书
主程序main:
/*
菜单程序范例(温度报警器)
说明:利用状态机实现非阻塞性的菜单。
(C)西安电子科技大学 测控技术与仪器教研中心 编 写:谢 楷 2008/07/01
*/
//
// 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++;
Menu_Process(); // 菜单处理
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; //扣除校准偏移量
if(Menu_State==MENU_QUIT)
{
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; // 下限报警
}
}
}
复制代码
菜单子程序:
#include <msp430x42x.h>
#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; /*报警上下限全局变量*/
int Menu_Temp; //调整数据的临时变量(为了实现放弃保存功能)
char Menu_State=0;
#define MENU_QUIT 0
#define MENU_SET 1
#define MENU_AH 2
#define MENU_AL 3
#define MENU_END 4
/*************************************************************************
* 名 称: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<MIN) Value=MAX; //超量程处理
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_Process()
* 功 能:菜单程序
* 入口参数:无
* 出口参数:无
* 说 明: 利用状态机实现的菜单,该程序不阻塞CPU的执行
*************************************************************************/
void Menu_Process()
{
char Key;
Key=Key_GetKey(); //从键盘缓冲区读取一次按键
static int Timer;
static int TimeOutTimer;
switch(Menu_State)
{
case MENU_QUIT: if(Key==KEY_ENT_FL) Menu_State=MENU_SET;
break;
case MENU_SET: LCD_Clear();
LCD_DisplayChar(SS,2);
LCD_DisplayChar(EE,1); // 显示"SET",提示菜单开始
LCD_DisplayChar(tt,0);
if(Key==KEY_ENT)
{
Menu_Temp=Alarm_H;
Menu_State=MENU_AH;
}
break;
case MENU_AH : Menu_Temp=Menu_SetValue(Menu_Temp,Key,-200,500,10);// 根据按键调整参数数值
LCD_DisplayDecimal(Menu_Temp,1); // 显示温度上限值,保留一位小数
LCD_DisplayChar(AA,6);
LCD_DisplayChar(HH,5); // 提示符"AH"
if(Key==KEY_ENT)
{
Alarm_H=Menu_Temp; // 更新报警上限全局变量
Flash_WriteWord(ADDR_AH,Alarm_H);// 报警上限值写入Flash
Menu_Temp=Alarm_L;
Menu_State=MENU_AL;
}
if(Key==KEY_ENT_FL)
{
Menu_Temp=Alarm_L;
Menu_State=MENU_AL;
}
break;
case MENU_AL : Menu_Temp=Menu_SetValue(Menu_Temp,Key,-200,500,10);// 根据按键调整参数数值
LCD_DisplayDecimal(Menu_Temp,1); // 显示温度下限值,保留一位小数
LCD_DisplayChar(AA,6);
LCD_DisplayChar(LL,5); // 提示符"AL"
if(Key==KEY_ENT)
{
Alarm_L=Menu_Temp; // 更新报警上限全局变量
Flash_WriteWord(ADDR_AL,Alarm_L);// 报警上限值写入Flash
Menu_State=MENU_END;
}
if(Key==KEY_ENT_FL) Menu_State=MENU_END;
break;
case MENU_END : LCD_Clear();
LCD_DisplayChar(EE,2);
LCD_DisplayChar(nn,1); // 显示"End",提示菜单结束
LCD_DisplayChar(DD,0);
if(++Timer>16) {Timer=0;Menu_State=MENU_QUIT;}//0.5秒后退出
break;
}
//---------------------------超时退出-----------------------------------
if(Key!=0) TimeOutTimer=0; //任何按键都可以将无操作时间清零
if(Menu_State!=MENU_QUIT) //在菜单中,对无操作时间计时
{
TimeOutTimer++;
if(TimeOutTimer>160) Menu_State = MENU_QUIT; //无操作超过10秒,退出菜单
}
else TimeOutTimer=0;
//---------------------------------------------------------------------
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1