main.c
#include
#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);
}