1. 程式人生 > >430定時器按下開始再按暫停

430定時器按下開始再按暫停

main.c

#include <msp430x14x.h>
#include "Config.h"
#include"1602.c"
int second = 0, minute = 0, count = 0, flag = 0, a = 0, b = 0, c = 0;
unsigned char FlagLcd;
//*************************************************************************
// 初始化IO口子程式
//*************************************************************************
void Port_init()
{
        P1SEL = 0x00;                   //P1普通IO功能
        P1DIR = 0xF0;                   //P10~P13輸入模式,外部電路已接上拉電阻
        P1IE  = 0x0f;                   //開啟 位中斷
        P1IES = 0x00;                   //上升沿觸發中斷
        P1IFG = 0x00;                   //軟體清零中斷標誌暫存器
}
//***********************************************************************
//             TIMERA初始化,設定為UP模式計數
//***********************************************************************
void TIMERA_Init(void)                                   //UP模式計數,計數週期為CCR0+1
{
  TACTL |= TASSEL1 + TACLR + ID0 + ID1 + MC0 + TAIE;     //SMCLK做時鐘源,8分頻,增加計數模式,開中斷
  TACCR0 = 9999;                                         //CCR0=9999,10ms中斷一次
}
//***********************************************************************
//             關閉計時,暫停計數
//***********************************************************************
void TimerA_end(void)
{
    TACTL &= 0xfffd;
}
//**********************************************************************
//

掃描按鍵P1^2是否長按
//**********************************************************************
void GetKey()//掃描鍵盤
{
    unsigned char keyRetu=0; //返回的按鍵值
    static unsigned char s_keyState=0,keyTime=0; //按鍵狀態,按鍵按下的時間
    switch (s_keyState)
    {
    case 0:
      {
        if((P1IN&0x02)==0x00) //檢測到有按鍵,轉到狀態1,相當於是消抖過程。
        {
            s_keyState=1;
        } 
      }
       break;
    case 1:
      {
        if((P1IN&0x02)==0x00) //再次檢測到有按鍵,轉到狀態2
        {
            s_keyState=2;
            keyTime=0; //清零按鍵時間計數器
        }
        else
        {
            s_keyState=0; //沒有檢測到按鍵,說明狀態0檢測到是一個抖動,重新轉到狀態0
        }
      }
        break;
    case 2:
      {
        if((P1IN&0x02)==0x02) //檢測到按鍵鬆開
        {
            s_keyState=0; //狀態轉到狀態0
            keyRetu=1; //輸出1
        }
        else
        {
            if(++keyTime>=150) //按下時間>1s
                {
                    s_keyState=3; //轉到狀態3
                    keyTime=0; //清零按鍵時間計數器
                    keyRetu=2; // 輸出2
                }
        }
      }
        break;
    case 3:
      {
        if((P1IN&0x02)==0x02) //檢測到按鍵鬆開
        {
            s_keyState=0; //狀態轉到狀態0
        }
        else
        {
            s_keyState=3; //轉到狀態3
        }
      }
        break;
    }
}


//***********************************************************************
//             TIMERA中斷服務程式,需要判斷中斷型別
//***********************************************************************
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
  switch(TAIV)                                  //需要判斷中斷的型別
  {
  case 2:break;
  case 4:break;
  case 10:count++;break;                         //設定標誌位Flag
  }
  if(count==100)                                 //100次為1秒
  {
    second++;
    count=0;                       
  }
  if(second == 60)
  {
    minute++;
    second = 0;
  }
  GetKey();
}
//**********************************************************************
//
P1口中斷服務程式,需要判斷
//**********************************************************************
#pragma vector = PORT1_VECTOR
__interrupt void P1_IRQ(void)
{
  switch(P1IFG&0x0F)
  {
  case 0x01: {
                  
                  flag++;
                  P1IFG=0x00;
              }
              break;
  default:P1IFG = 0x00;break;                   
  }
}
//***********************************************************************
//      主程式
//***********************************************************************
void main(void)
{
     WDT_Init();                        //看門狗設定                        
     Clock_Init();                       //系統時鐘設定
     Port_init();                        //系統初始化,設定IO口屬性
     Port_Init();                         //設定顯示屏埠
     delay_ms(100);                      //延時100ms
     LCD_init();                         //液晶引數初始化設定
     LCD_clear();                        //清屏
     TIMERA_Init();
     _EINT();
     while (1) 
      {
                if(flag%2==0)
                {
                  LCD_write_str(0,1,c/10);
                  LCD_write_str(1,1,c%10);
                  LCD_write_char(2,1,0x3a);
                  LCD_write_str(3,1,b/10);
                  LCD_write_str(4,1,b%10);
                  LCD_write_char(5,1,0x3a);
                  LCD_write_str(6,1,a/10);
                  LCD_write_str(7,1,a%10);
                }
                else
                {
                  count = a;
                  second = b;
                  minute = c;
                  LCD_write_str(0,1,minute/10);
                  LCD_write_str(1,1,minute%10);
                  LCD_write_char(2,1,0x3a);
                  LCD_write_str(3,1,second/10);
                  LCD_write_str(4,1,second%10);
                  LCD_write_char(5,1,0x3a);
                  LCD_write_str(6,1,count/10);
                  LCD_write_str(7,1,count%10);
                  a = count;
                  b = second;
                  c = minute;
                }
      }

}


1602.c

//*************************************************************************
// 初始化IO口子程式
//*************************************************************************
void Port_Init()
{


P4SEL = 0x00;
        P4DIR = 0xFF;                   //資料口輸出模式
        P5SEL = 0x00;
        P5DIR|= BIT5 + BIT6 + BIT7;     //控制口設定為輸出模式
}


//***********************************************************************
// 顯示屏命令寫入函式
//***********************************************************************
void LCD_write_com(unsigned char com) 
{
RS_CLR;
RW_CLR;
EN_SET;
DataPort = com;                 //命令寫入埠
delay_ms(5);
EN_CLR;
}


//***********************************************************************
// 顯示屏資料寫入函式
//***********************************************************************
void LCD_write_data(unsigned char data) 
{
RS_SET;
RW_CLR;
EN_SET;
DataPort = data;                //資料寫入埠
delay_ms(5);
EN_CLR;
}


//***********************************************************************
// 顯示屏清空顯示
//***********************************************************************
void LCD_clear(void) 
{
LCD_write_com(0x01);            //清螢幕顯示
delay_ms(5);
}


//***********************************************************************
// 顯示屏字串寫入函式
//***********************************************************************
void LCD_write_str(unsigned char x,unsigned char y,int w) 
{

    if (y == 0) 
    {
    LCD_write_com(0x80 + x);        //第一行顯示
    }
    else 
    {
    LCD_write_com(0xC0 + x);        //第二行顯示
    }


    LCD_write_data(48+w);
   
}


//***********************************************************************
// 顯示屏單字元寫入函式
//***********************************************************************
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data) 
{

    if (y == 0) 
    {
    LCD_write_com(0x80 + x);        //第一行顯示
    }
    else 
    {
    LCD_write_com(0xC0 + x);        //第二行顯示
    }
    
    LCD_write_data( data);  
}


//***********************************************************************
// 顯示屏初始化函式
//***********************************************************************
void LCD_init(void) 
{
    LCD_write_com(0x38); //顯示模式設定  
    delay_ms(5);
    LCD_write_com(0x08); //顯示關閉
    delay_ms(5);
    LCD_write_com(0x01); //顯示清屏
    delay_ms(5);
    LCD_write_com(0x06); //顯示游標移動設定
    delay_ms(5);
    LCD_write_com(0x0C); //顯示開及游標設定
    delay_ms(5);
}