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;
}
//**********************************************************************
//
//**********************************************************************
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();
}
//**********************************************************************
//
//**********************************************************************
#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);
}