通过232串口设置MSP430F149IPM单片机液晶显示时间的程序

59 阅读17分钟

通过232串口设置MSP430F149IPM单片机液晶显示时间的程序

 下面介绍一段通过232串口设置MSP430F149IPM单片机液晶显示时间的程序。用户通过串口发送0X01,0X02,0X03,0X04可以改变单片机液晶显示时间,当到达一定设置时间时,单片机P2端口输出7路高电平,1路低电平,

第二段程序,可以从单片机按键像计算机232串口发送0x00,同时单片机液晶屏显示时间。

MSP430单片机电路如下,程序通过IAR430V5.3软件编译通过,生成.txt文件,使用BSL下载软件-Msp430BSL

通过USB端口把.TXT文件烧写到单片机中。程序和电路可以在下面的网址下载:链接:pan.baidu.com/s/1PxUz7CXQ… ;

提取码:2kcy

链接:pan.baidu.com/s/1e1uS02vl… ;

提取码:kuw9

share.weiyun.com/5PIcLM9

程序1:

 

/*****************************************************

程序功能:在1602液晶上显示用MCU的TimerA模拟的数字

          式实时时钟。


测试说明:观察液晶显示


程序功能:接收来自PC机的字符,然后重新发送给PC机

程序功能:串口发送十六进制数01,液晶显示时间25:25:25,

串口发送十六进制数02,液晶显示时间35:35:35,

串口发送十六进制数03,液晶显示时间11:11:34,

液晶计时11:10:60时,P2口输出01111111,液晶显示33:33:11


通信格式:N.8.1,  9600

         无校验,8个数据位,1个停止位,波特率9600

*****************************************************/

#include <msp430x14x.h>

#include "cry1602.h"

#include "clock.h"

#include "cry1602.c"

#include "clock.c"

#define keyin    P3IN 

uchar tishi[]={"Current Time is"};   //提示信息

  void delay(void);

extern uchar second,minute,hour,hour0;

 

extern uchar pmin,phour,ps1;

 

#define SetTime(H,M,S) {second=S;minute=M;hour=H;hour0=H;}

uchar scandata[16] ;

/*主函数/

void main(void)

{   

  

    /下面六行程序关闭所有的IO口/

    P1DIR = 0XFF;P1OUT = 0XFF;

    P2DIR = 0XFF;P2OUT = 0XFF;

    P3DIR = 0XFF;P3OUT = 0XFF;

    P4DIR = 0XFF;P4OUT = 0XFF;

    P5DIR = 0XFF;P5OUT = 0XFF;

    P6DIR = 0XFF;P6OUT = 0XFF;

  

    WDTCTL = WDTPW + WDTHOLD;   //关闭看门狗

   // P6DIR |= BIT2;P6OUT |= BIT2;//关闭电平转换

   // P6DIR |= BIT6;P6OUT &= ~BIT6;//关闭电平转换

P3SEL |= 0x30;                            // 选择P3.4和P3.5做UART通信端口

    ME1 |= UTXE0 + URXE0;                     // 使能USART0的发送和接受

    UCTL0 |= CHAR;                            // 选择8位字符

    UTCTL0 |= SSEL0;                          // UCLK = ACLK

    UBR00 = 0x03;                             // 波特率9600

    UBR10 = 0x00;                             //

    UMCTL0 = 0x4A;                            // Modulation

    UCTL0 &= ~SWRST;                          // 初始化UART状态机

   // IE1 |= URXIE0;                            // 使能USART0的接收中断

    CCR0 = 32768 - 1;           //设置定时器A的中断时间为1S

    TACTL = TASSEL_1 + MC_1;    //计数时钟ACLK, 增计数模式

    CCTL0 |= CCIE;              //使能CCR0比较中断

    _EINT();                    //打开全局中断

  //    IE1 |= URXIE0;                            // 使能USART0的接收中断

 

    //请在此处设置正确时间

    SetTime(11,11,34);           //顺序:时,分,秒,格式:BCD码

      

    LcdReset(); 

    DispNChar(0,0,15,tishi);     //显示提示文字

 

    Disp1Char(6,1,':');          //显示字符 :

    Disp1Char(9,1,':');

     P2DIR = 0xff;                   //设置P2口方向为输出

     //  SetTime( RXBUF0, RXBUF0, RXBUF0);           

     // P2OUT = 0x40;

       // if(IFG1 & URXIFG0)      //如果收到字符

       // {

          

        //SetTime( RXBUF0, RXBUF0, RXBUF0);           //顺序:时,分,秒,格式:BCD码

       // }

       //else

      // {

       //   SetTime(11,11,34);           //顺序:时,分,秒,格式:BCD码

       //}

    while(1)

    {

        // _EINT();                               //打开全局中断

      //  LPM1;                                  //进入LPM1模式

     //   while (!(IFG1 & UTXIFG0));             //等待以前的字符发送完毕

      //  TXBUF0 = RXBUF0;                       //将收到的字符发送出去 

         //  if(IFG1 & URXIFG0)      //如果收到字符

        //{

    // switch(RXBUF0)

      //  {

        //case 0x01:

                    if(RXBUF0 == 0x01)   //如果是第一个按键被按下

                    {

        second=25;

        minute=25;

        hour=25;

        //SetTime(19,19,19);

         TXBUF0 = RXBUF0;   

       // }

        //}

        }

          if(RXBUF0 == 0x02)   //如果是第一个按键被按下

                    {

        second=35;

        minute=35;

        hour=35;

        //SetTime(19,19,19);

         TXBUF0 = RXBUF0;   

       // }

        //}

        }

             if(RXBUF0 == 0x03)   //如果是第一个按键被按下

                    {

        second=34;

        minute=11;

        hour=11;

        //SetTime(19,19,19);

         TXBUF0 = RXBUF0;   

       // }

        //}

        }

     //  else

      // {

         // SetTime(11,11,34);           //顺序:时,分,秒,格式:BCD码

      // }

        

        //scandata[16] =RXBUF0; 

       // if(RXBUF0!=0X00)

      //  {

          

       // SetTime( RXBUF0, RXBUF0, RXBUF0);           //顺序:时,分,秒,格式:BCD码

       // }

          //LPM3;                    //进入LPM3低功耗模式

        Display();

        if(second == 60&minute==10&hour==11)   //如果是第一个按键被按下

                   {

                        

                       P2OUT = 0x80;

                          SetTime(33,33,11);           

                       }

  

        

          if(keyin == 0xbf)   //如果是第一个按键被按下

                    {

                        delay();

                        if(keyin == 0xbf)

                        {

                            while(keyin != 0xbf);       //等待按键放开

                       SetTime(22,22,11);           //顺序:时,分,秒,格式:BCD码

                            return;

                       }

  

        

    }

         

    }    

}

 

/*******************************************

函数名称:TimerA_ISR

功    能:定时器A的中断服务函数

参    数:无

返回值  :无

********************************************/

#pragma vector=TIMERA0_VECTOR

__interrupt void TimerA_ISR(void)

{

    Clock();

    LPM3_EXIT;

}

 

void delay(void)

{

    uint tmp;

    

    for(tmp = 12000;tmp > 0;tmp--);

}

 

/*******************************************

函数名称:UART0_RXISR

功    能:UART0的接收中断服务函数,在这里唤醒

          CPU,使它退出低功耗模式

参    数:无

返回值  :无

********************************************/

#pragma vector = UART0RX_VECTOR

__interrupt void UART0_RXISR(void)

{

  LPM1_EXIT;                 //退出低功耗模式

}

 

 

//#include <msp430x44x.h>

#include "cry1602.h"

 

/全局变量**/

uchar second,minute,hour,hour0;  //秒、分、时变量

uchar pmin,phour,ps1;            //辅助计算变量          

 

/*******************************************

函数名称:Clock

功    能:计算当前时间

参    数:无

返回值  :无

说明    :本函数对本文件开头定义的second,minute,

          hour,hour0四个全局变量进行操作

********************************************/

void Clock(void)

{

    second -= 1;

   // second<=60& second>=0;

   //  minute<=60&minute>=0;

   //  hour<=100&hour>=0;

    if(second == 0) 

    {

        second = 60;

        minute -= 1;

if(minute == 0)

{

    minute = 60;

    hour -= 1; hour0 -= 1;

    if(hour == 0)   hour = 24;

}

    }

}

//void Clock(void)

//{

   // second -= 1;

   // second<=60& second>=0;

   //  minute<=60&minute>=0;

   //  hour<=100&hour>=0;

    //if(second == 60) 

   // {

      //  second = 0;

     //   minute -= 1;

//if(minute == 60)

//{

//    minute = 0;

//    hour -= 1; hour0 -= 1;

//    if(hour == 24)   hour = 0;

//}

   // }

//}

/*******************************************

函数名称:Display

功    能:在1602液晶上显示时间

参    数:无

返回值  :无

说明    :本函数对本文件开头定义的全局变量进行

          操作

********************************************/

void Display(void)

{

    uchar s0,s1;

    uchar m0,m1;

    uchar h0,h1;

 

    s1 = second / 10;           //十位

    s0 = second - (s1 * 10);    //个位

    s1 += 48;                   //加上48等于其对应的ASCII码

    s0 += 48; 

    

    Disp1Char(11,1,s0);

  if(ps1 != s1)

    {

ps1 = s1;

  Disp1Char(10,1,s1);                         

    }

  

    if(pmin != minute)

{

    pmin = minute;

    m1 = minute / 10;

    m0 = minute - (m1 * 10);

    m1 += 48;

        m0 += 48;

    Disp1Char(7,1,m1);

        Disp1Char(8,1,m0);

}

if(phour != hour)

{

    phour = hour;

    h1 = hour / 10;

    h0 = hour - (h1 * 10);

    h1 += 48;

        h0 += 48;

    Disp1Char(4,1,h1);

        Disp1Char(5,1,h0); 

}

}

 

 

void Clock(void);

void Display(void);

 

 

#include <msp430x14x.h>

#include "cry1602.h"

typedef unsigned char uchar;

typedef unsigned int  uint;

 

/宏定义*/

#define DataDir     P2DIR

#define DataPort    P2OUT

#define Busy    0x80

#define CtrlDir     P6DIR

#define CLR_RS P6OUT&=~BIT3;    //RS = P3.0

#define SET_RS P6OUT|=BIT3;

#define CLR_RW P6OUT&=~BIT4;//RW = P3.1

#define SET_RW P6OUT|=BIT4;

#define CLR_EN P6OUT&=~BIT5;//EN = P3.2

#define SET_EN P6OUT|=BIT5;

/*******************************************

函数名称:DispNchar

功    能:让液晶从某个位置起连续显示N个字符

参    数:x--位置的列坐标

          y--位置的行坐标

          n--字符个数

          ptr--指向字符存放位置的指针

返回值  :无

********************************************/

void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) 

{

    uchar i;

    

    for (i=0;i<n;i++)

    {

        Disp1Char(x++,y,ptr[i]);

        if (x == 0x0f)

        {

           x = 0; 

            y ^= 1;

        }

    }

}

/*******************************************

函数名称:LocateXY

功    能:向液晶输入显示字符位置的坐标信息

参    数:x--位置的列坐标

          y--位置的行坐标

返回值  :无

********************************************/

void LocateXY(uchar x,uchar y) 

{

    uchar temp;

 

    temp = x&0x0f;

    y &= 0x01;

    if(y)   temp |= 0x40;  //如果在第2行

    temp |= 0x80;

 

    LcdWriteCommand(temp,1);

}

/*******************************************

函数名称:Disp1Char

功    能:在某个位置显示一个字符

参    数:x--位置的列坐标

          y--位置的行坐标

          data--显示的字符数据

返回值  :无

********************************************/

void Disp1Char(uchar x,uchar y,uchar data) 

{

    LocateXY( x, y );

    LcdWriteData( data );

}

/*******************************************

函数名称:LcdReset

功    能:对1602液晶模块进行复位操作

参    数:无

返回值  :无

********************************************/

void LcdReset(void) 

{

    CtrlDir |= 0x38;                 //控制线端口设为输出状态 

    DataDir  = 0xFF;                 //数据端口设为输出状态

  

    LcdWriteCommand(0x38, 0);    //规定的复位操作

    Delay5ms();

    LcdWriteCommand(0x38, 0);

    Delay5ms();

    LcdWriteCommand(0x38, 0);

    Delay5ms();

 

    LcdWriteCommand(0x38, 1);//显示模式设置

    LcdWriteCommand(0x08, 1);//显示关闭

    LcdWriteCommand(0x01, 1);    //显示清屏

    LcdWriteCommand(0x06, 1);//写字符时整体不移动

    LcdWriteCommand(0x0c, 1);//显示开,不开游标,不闪烁

}

/*******************************************

函数名称:LcdWriteCommand

功    能:向液晶模块写入命令

参    数:cmd--命令,

          chk--是否判忙的标志,1:判忙,0:不判

返回值  :无

********************************************/

void LcdWriteCommand(uchar cmd,uchar chk) 

{

 

    if (chk) WaitForEnable();   // 检测忙信号?

    

    CLR_RS;

    CLR_RW; 

    _NOP();

 

    DataPort = cmd;             //将命令字写入数据端口 

    _NOP();

    

    SET_EN;                     //产生使能脉冲信号

    _NOP();

    _NOP();

    CLR_EN;

}

/*******************************************

函数名称:LcdWriteData

功    能:向液晶显示的当前地址写入显示数据

参    数:data--显示字符数据

返回值  :无

********************************************/

void LcdWriteData( uchar data ) 

{

    WaitForEnable();        //等待液晶不忙

 

    SET_RS;

    CLR_RW; 

    _NOP();

 

    DataPort = data;        //将显示数据写入数据端口

    _NOP();

 

    SET_EN;                 //产生使能脉冲信号

    _NOP(); 

    _NOP(); 

    CLR_EN;

}

/*******************************************

函数名称:WaitForEnable

功    能:等待1602液晶完成内部操作

参    数:无

返回值  :无

********************************************/

void WaitForEnable(void) 

{

    P2DIR &= 0x00;  //将P4口切换为输入状态

 

    CLR_RS;

    SET_RW;

    _NOP();

    SET_EN; 

    _NOP();

    _NOP();

    

    while((P2IN & Busy)!=0);  //检测忙标志

 

    CLR_EN;

 

    P2DIR |= 0xFF;  //将P4口切换为输出状态

}

                       

/*******************************************

函数名称:Delay5ms

功    能:延时约5ms

参    数:无

返回值  :无

********************************************/

void Delay5ms(void)

    uint i=40000;

    while (i != 0)

    {

        i--;

    }

}

/*******************************************

函数名称:Delay400ms

功    能:延时约400ms

参    数:无

返回值  :无

********************************************/

void Delay400ms(void)

{

    uchar i=50;

    uint j;

 

    while(i--)

    {

            j=7269;

            while(j--);

    }

}

void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr);

void LocateXY(unsigned char x,unsigned char y);

void Disp1Char(unsigned char x,unsigned char y,unsigned char data);

void LcdReset(void);

void LcdWriteCommand(unsigned char cmd,unsigned char chk);

void LcdWriteData( unsigned char data );

void WaitForEnable(void);

void Delay5ms(void);

void Delay400ms(void);

  

 

第二段程序

#include  <msp430x14x.h>

typedef unsigned char uchar;

typedef unsigned int  uint;

 //unsigned char uchar;

  //unsigned int  uint;

/全局变量/

uchar key_Pressed;      //按键是否被按下:1--是,0--否

uchar key_val;          //存放键值

uchar key_Flag;         //按键是否已放开:1--是,0--否

//设置键盘逻辑键值与程序计算键值的映射

uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

 

/*******************************************

函数名称:Init_Keypad

功    能:初始化扫描键盘的IO端口

参    数:无

返回值  :无

********************************************/

void Init_Keypad(void)

{     

    P1DIR = 0xf0;       //P1.0P1.3设置为输入状态, P1.4P1.7设置为输出状态

    P1OUT |= 0xf0;      // P1.4~P1.7输出高电平

    key_Flag = 0;       

    key_Pressed = 0;   

    key_val = 0;

}

/*********************************************

  • Check_Key(),检查按键,确认键值

*********************************************/

/*******************************************

函数名称:Check_Key

功    能:扫描键盘的IO端口,获得键值

参    数:无

返回值  :无

********************************************/

void Check_Key(void)

{

    uchar row ,col,tmp1,tmp2;

    

    tmp1 = 0x80;

    for(row = 0;row < 4;row++)              //行扫描

    {

        P1OUT = 0xf0;                      //P1.4~P1.7输出全1

        P1OUT -= tmp1;                      //P1.4~p1.7输出四位中有一个为0

        tmp1 >>=1;                              

        if ((P1IN & 0x0f) < 0x0f)           //是否P1IN的P1.0~P1.3中有一位为0

        {                       

            tmp2 = 0x01;                         // tmp2用于检测出那一位为0  

            for(col = 0;col < 4;col++)              // 列检测 

            {          

                if((P1IN & tmp2) == 0x00)           // 是否是该列,等于0为是

                {          

                    key_val = key_Map[row * 4 + col];  // 获取键值

                    return;                         // 退出循环

                }

                tmp2 <<= 1;                        // tmp2右移1位 

            }

        }

    }      

}

/*******************************************

函数名称:delay

功    能:延时约15ms,完成消抖功能

参    数:无

返回值  :无

********************************************/

void delay()

{

    uint tmp;

     

    for(tmp = 12000;tmp > 0;tmp--);

}

/*******************************************

函数名称:Key_Event

功    能:检测按键,并获取键值

参    数:无

返回值  :无

********************************************/

void Key_Event(void)

{     

    uchar tmp;

     

    P1OUT &= 0x00;              // 设置P1OUT全为0,等待按键输入

    tmp = P1IN;                 // 获取 p1IN

    if ((key_Pressed == 0x00)&&((tmp & 0x0f) < 0x0f)) //如果有键按下

    {                     

        key_Pressed = 1;        // 如果有按键按下,设置key_Pressed标识

        delay();                //消除抖动

        Check_Key();            // 调用check_Key(),获取键值 

    }     

    else if ((key_Pressed == 1)&&((tmp & 0x0f) == 0x0f)) //如果按键已经释放

    {                     

        key_Pressed = 0;        // 清除key_Pressed标识

        key_Flag    = 1;        // 设置key_Flag标识

    }

    else 

    {

        _NOP();

    }     

}

 

 

 

//#include <msp430x44x.h>

#include "cry1602.h"

 

/全局变量**/

uchar second,minute,hour,hour0;  //秒、分、时变量

uchar pmin,phour,ps1;            //辅助计算变量          

 

/*******************************************

函数名称:Clock

功    能:计算当前时间

参    数:无

返回值  :无

说明    :本函数对本文件开头定义的second,minute,

          hour,hour0四个全局变量进行操作

********************************************/

void Clock(void)

{

    second -= 1;

   // second<=60& second>=0;

   //  minute<=60&minute>=0;

   //  hour<=100&hour>=0;

    if(second == 0) 

    {

        second = 60;

        minute -= 1;

if(minute == 0)

{

    minute = 60;

    hour -= 1; hour0 -= 1;

    if(hour == 0)   hour = 24;

}

    }

}

//void Clock(void)

//{

   // second -= 1;

   // second<=60& second>=0;

   //  minute<=60&minute>=0;

   //  hour<=100&hour>=0;

    //if(second == 60) 

   // {

      //  second = 0;

     //   minute -= 1;

//if(minute == 60)

//{

//    minute = 0;

//    hour -= 1; hour0 -= 1;

//    if(hour == 24)   hour = 0;

//}

   // }

//}

/*******************************************

函数名称:Display

功    能:在1602液晶上显示时间

参    数:无

返回值  :无

说明    :本函数对本文件开头定义的全局变量进行

          操作

********************************************/

void Display(void)

{

    uchar s0,s1;

    uchar m0,m1;

    uchar h0,h1;

 

    s1 = second / 10;           //十位

    s0 = second - (s1 * 10);    //个位

    s1 += 48;                   //加上48等于其对应的ASCII码

    s0 += 48; 

    

    Disp1Char(11,1,s0);

  if(ps1 != s1)

    {

ps1 = s1;

  Disp1Char(10,1,s1);                         

    }

  

    if(pmin != minute)

{

    pmin = minute;

    m1 = minute / 10;

    m0 = minute - (m1 * 10);

    m1 += 48;

        m0 += 48;

    Disp1Char(7,1,m1);

        Disp1Char(8,1,m0);

}

if(phour != hour)

{

    phour = hour;

    h1 = hour / 10;

    h0 = hour - (h1 * 10);

    h1 += 48;

        h0 += 48;

    Disp1Char(4,1,h1);

        Disp1Char(5,1,h0); 

}

}

 

void Clock(void);

void Display(void);

 

 

#include <msp430x14x.h>

#include "cry1602.h"

typedef unsigned char uchar;

typedef unsigned int  uint;

 

/宏定义*/

#define DataDir     P2DIR

#define DataPort    P2OUT

#define Busy    0x80

#define CtrlDir     P6DIR

#define CLR_RS P6OUT&=~BIT3;    //RS = P3.0

#define SET_RS P6OUT|=BIT3;

#define CLR_RW P6OUT&=~BIT4;//RW = P3.1

#define SET_RW P6OUT|=BIT4;

#define CLR_EN P6OUT&=~BIT5;//EN = P3.2

#define SET_EN P6OUT|=BIT5;

/*******************************************

函数名称:DispNchar

功    能:让液晶从某个位置起连续显示N个字符

参    数:x--位置的列坐标

          y--位置的行坐标

          n--字符个数

          ptr--指向字符存放位置的指针

返回值  :无

********************************************/

void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) 

{

    uchar i;

    

    for (i=0;i<n;i++)

    {

        Disp1Char(x++,y,ptr[i]);

        if (x == 0x0f)

        {

           x = 0; 

            y ^= 1;

        }

    }

}

/*******************************************

函数名称:LocateXY

功    能:向液晶输入显示字符位置的坐标信息

参    数:x--位置的列坐标

          y--位置的行坐标

返回值  :无

********************************************/

void LocateXY(uchar x,uchar y) 

{

    uchar temp;

 

    temp = x&0x0f;

    y &= 0x01;

    if(y)   temp |= 0x40;  //如果在第2行

    temp |= 0x80;

 

    LcdWriteCommand(temp,1);

}

/*******************************************

函数名称:Disp1Char

功    能:在某个位置显示一个字符

参    数:x--位置的列坐标

          y--位置的行坐标

          data--显示的字符数据

返回值  :无

********************************************/

void Disp1Char(uchar x,uchar y,uchar data) 

{

    LocateXY( x, y );

    LcdWriteData( data );

}

/*******************************************

函数名称:LcdReset

功    能:对1602液晶模块进行复位操作

参    数:无

返回值  :无

********************************************/

void LcdReset(void) 

{

    CtrlDir |= 0x38;                 //控制线端口设为输出状态 

    DataDir  = 0xFF;                 //数据端口设为输出状态

  

    LcdWriteCommand(0x38, 0);    //规定的复位操作

    Delay5ms();

    LcdWriteCommand(0x38, 0);

    Delay5ms();

    LcdWriteCommand(0x38, 0);

    Delay5ms();

 

    LcdWriteCommand(0x38, 1);//显示模式设置

    LcdWriteCommand(0x08, 1);//显示关闭

    LcdWriteCommand(0x01, 1);    //显示清屏

    LcdWriteCommand(0x06, 1);//写字符时整体不移动

    LcdWriteCommand(0x0c, 1);//显示开,不开游标,不闪烁

}

/*******************************************

函数名称:LcdWriteCommand

功    能:向液晶模块写入命令

参    数:cmd--命令,

          chk--是否判忙的标志,1:判忙,0:不判

返回值  :无

********************************************/

void LcdWriteCommand(uchar cmd,uchar chk) 

{

 

    if (chk) WaitForEnable();   // 检测忙信号?

    

    CLR_RS;

    CLR_RW; 

    _NOP();

 

    DataPort = cmd;             //将命令字写入数据端口 

    _NOP();

    

    SET_EN;                     //产生使能脉冲信号

    _NOP();

    _NOP();

    CLR_EN;

}

/*******************************************

函数名称:LcdWriteData

功    能:向液晶显示的当前地址写入显示数据

参    数:data--显示字符数据

返回值  :无

********************************************/

void LcdWriteData( uchar data ) 

{

    WaitForEnable();        //等待液晶不忙

 

    SET_RS;

    CLR_RW; 

    _NOP();

 

    DataPort = data;        //将显示数据写入数据端口

    _NOP();

 

    SET_EN;                 //产生使能脉冲信号

    _NOP(); 

    _NOP(); 

    CLR_EN;

}

/*******************************************

函数名称:WaitForEnable

功    能:等待1602液晶完成内部操作

参    数:无

返回值  :无

********************************************/

void WaitForEnable(void) 

{

    P2DIR &= 0x00;  //将P4口切换为输入状态

 

    CLR_RS;

    SET_RW;

    _NOP();

    SET_EN; 

    _NOP();

    _NOP();

    

    while((P2IN & Busy)!=0);  //检测忙标志

 

    CLR_EN;

 

    P2DIR |= 0xFF;  //将P4口切换为输出状态

}

                       

/*******************************************

函数名称:Delay5ms

功    能:延时约5ms

参    数:无

返回值  :无

********************************************/

void Delay5ms(void)

    uint i=40000;

    while (i != 0)

    {

        i--;

    }

}

/*******************************************

函数名称:Delay400ms

功    能:延时约400ms

参    数:无

返回值  :无

********************************************/

void Delay400ms(void)

{

    uchar i=50;

    uint j;

 

    while(i--)

    {

            j=7269;

            while(j--);

    }

}

 

 

 

void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr);

void LocateXY(unsigned char x,unsigned char y);

void Disp1Char(unsigned char x,unsigned char y,unsigned char data);

void LcdReset(void);

void LcdWriteCommand(unsigned char cmd,unsigned char chk);

void LcdWriteData( unsigned char data );

void WaitForEnable(void);

void Delay5ms(void);

void Delay400ms(void);

 

 

#include  <msp430x14x.h>

typedef unsigned char uchar;

typedef unsigned int  uint;

 //unsigned char uchar;

  //unsigned int  uint;

/全局变量/

uchar key_Pressed;      //按键是否被按下:1--是,0--否

uchar key_val;          //存放键值

uchar key_Flag;         //按键是否已放开:1--是,0--否

//设置键盘逻辑键值与程序计算键值的映射

uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

 

/*******************************************

函数名称:Init_Keypad

功    能:初始化扫描键盘的IO端口

参    数:无

返回值  :无

********************************************/

void Init_Keypad(void)

{     

    P1DIR = 0xf0;       //P1.0P1.3设置为输入状态, P1.4P1.7设置为输出状态

    P1OUT |= 0xf0;      // P1.4~P1.7输出高电平

    key_Flag = 0;       

    key_Pressed = 0;   

    key_val = 0;

}

/*********************************************

  • Check_Key(),检查按键,确认键值

*********************************************/

/*******************************************

函数名称:Check_Key

功    能:扫描键盘的IO端口,获得键值

参    数:无

返回值  :无

********************************************/

void Check_Key(void)

{

    uchar row ,col,tmp1,tmp2;

    

    tmp1 = 0x80;

    for(row = 0;row < 4;row++)              //行扫描

    {

        P1OUT = 0xf0;                      //P1.4~P1.7输出全1

        P1OUT -= tmp1;                      //P1.4~p1.7输出四位中有一个为0

        tmp1 >>=1;                              

        if ((P1IN & 0x0f) < 0x0f)           //是否P1IN的P1.0~P1.3中有一位为0

        {                       

            tmp2 = 0x01;                         // tmp2用于检测出那一位为0  

            for(col = 0;col < 4;col++)              // 列检测 

            {          

                if((P1IN & tmp2) == 0x00)           // 是否是该列,等于0为是

                {          

                    key_val = key_Map[row * 4 + col];  // 获取键值

                    return;                         // 退出循环

                }

                tmp2 <<= 1;                        // tmp2右移1位 

            }

        }

    }      

}

/*******************************************

函数名称:delay

功    能:延时约15ms,完成消抖功能

参    数:无

返回值  :无

********************************************/

void delay()

{

    uint tmp;

     

    for(tmp = 12000;tmp > 0;tmp--);

}

/*******************************************

函数名称:Key_Event

功    能:检测按键,并获取键值

参    数:无

返回值  :无

********************************************/

void Key_Event(void)

{     

    uchar tmp;

     

    P1OUT &= 0x00;              // 设置P1OUT全为0,等待按键输入

    tmp = P1IN;                 // 获取 p1IN

    if ((key_Pressed == 0x00)&&((tmp & 0x0f) < 0x0f)) //如果有键按下

    {                     

        key_Pressed = 1;        // 如果有按键按下,设置key_Pressed标识

        delay();                //消除抖动

        Check_Key();            // 调用check_Key(),获取键值 

    }     

    else if ((key_Pressed == 1)&&((tmp & 0x0f) == 0x0f)) //如果按键已经释放

    {                     

        key_Pressed = 0;        // 清除key_Pressed标识

        key_Flag    = 1;        // 设置key_Flag标识

    }

    else 

    {

        _NOP();

    }     

}