MSP430单片机课程设计实时时钟与键盘控制.docx

上传人:b****4 文档编号:11697540 上传时间:2023-03-30 格式:DOCX 页数:11 大小:33.88KB
下载 相关 举报
MSP430单片机课程设计实时时钟与键盘控制.docx_第1页
第1页 / 共11页
MSP430单片机课程设计实时时钟与键盘控制.docx_第2页
第2页 / 共11页
MSP430单片机课程设计实时时钟与键盘控制.docx_第3页
第3页 / 共11页
MSP430单片机课程设计实时时钟与键盘控制.docx_第4页
第4页 / 共11页
MSP430单片机课程设计实时时钟与键盘控制.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

MSP430单片机课程设计实时时钟与键盘控制.docx

《MSP430单片机课程设计实时时钟与键盘控制.docx》由会员分享,可在线阅读,更多相关《MSP430单片机课程设计实时时钟与键盘控制.docx(11页珍藏版)》请在冰豆网上搜索。

MSP430单片机课程设计实时时钟与键盘控制.docx

MSP430单片机课程设计实时时钟与键盘控制

MSP430单片机课程设计

实时时钟与键盘控制

一、设计思路

该算法的流程简图如下:

由于LCD无法完全显示时间日期,故采用page翻页的方式设计,每页6位显示。

设定page为奇数时表示当前在时间页面,page为偶数时表示当前在日期页面。

在修改时间时,采用的是输入字符串进行修改的方式。

1、显示当前时间time=hour*10000+min*100+sec。

在page为偶数时,前两位显示小时,中间两位显示分钟,最低两位显示秒。

2、显示当前日期date=year*10000+mon*100+day,并能与时间切换。

在page为奇数时,前两位显示年份,中间两位显示月份,最低两位显示天。

键盘上的up、down修改page的值,实现两页显示的切换。

2、能够读取键盘值进行修改

键盘通过中断的方式读取键值,每个键都有相应的操作。

具体的方案如下:

键值在0~F之间为对应的十六进制数。

按下UP键,page加1。

按下DOWN键,page加1,以上两键能使page奇偶变化。

按下L键,p加1,用于修改数据时修改位置的更改。

按下R键,p减1,用于修改数据时修改位置的更改。

按下ESC键,使set置1,进入修改模式,并在首位显示E。

按下START键,修改的数据生效,set置0。

按下STOP键,取消修改,set置0,清除首位显示。

按下ENTER键,确认当前位的修改,注意是单个位的修改。

3、体现430系列单片机的超低功耗的特性。

在中断处理结束,以及循环结束,或者等待键盘按键时,会进入低功耗工作模式,同时编程时也尽量减少函数的调用,并将一些变量定义为寄存器变量,提高运行效率。

二、参数计算

设计时钟时,应能做到分秒的60进1,时的24进1,年以两位数表示满100进1,月满12进1;关于天的计数较为复杂:

先根据年月判断该月的最大天数,实现进位。

三、编程步骤

1、编写时间显示函数,测试以确认函数功能正常。

2、设置初始值为04年2月28日。

利用定时器A控制秒信号的自加,并用LCD显示判断算法是否正确。

3、已经得到正确的秒信号,根据算法实现时间的进位。

4、设计键盘,使键盘能正确输入,读取键值。

5、设计翻页功能,实现时间和日期的切换。

6、设计时间的修改功能,以串输入修改数据的形式进行修改。

7、程序存档,测试检验基本功能。

8、优化程序算法,精简变量与函数调用,实现超低功耗,测试检验,提交最后成果。

四、实践感受

五、源程序

//实时时钟+键盘控制(串输入修改方式)

#include

#include

//定义液晶显示笔画

#definea(0x01)

#defineb(0x02)

#definec(0x10)

#defined(0x08)

#definee(0x40)

#definef(0x20)

#defineg(0x04)

//#defineh(0x80)

//显示字符的指针

constunsignedcharLCD_Tab[]={

a+b+c+d+e+f,//显示"0",LCD_Tab[00]

b+c,//显示"1",LCD_Tab[01]

a+b+d+e+g,//显示"2",LCD_Tab[02]

a+b+c+d+g,//显示"3",LCD_Tab[03]

b+c+f+g,//显示"4",LCD_Tab[04]

a+c+d+f+g,//显示"5",LCD_Tab[05]

a+c+d+e+f+g,//显示"6",LCD_Tab[06]

a+b+c,//显示"7",LCD_Tab[07]

a+b+c+d+e+f+g,//显示"8",LCD_Tab[08]

a+b+c+d+f+g,//显示"9",LCD_Tab[09]

a+b+c+e+f+g,//显示"A",LCD_Tab[0A]

c+d+e+f+g,//显示"b",LCD_Tab[0B]

a+d+e+f,//显示"C",LCD_Tab[0C]

b+c+d+e+g,//显示"d",LCD_Tab[0D]

a+d+e+f+g,//显示"E",LCD_Tab[0E]

a+e+f+g,//显示"F",LCD_Tab[0F]

0,//显示"",LCD_Tab[10]

};

//定义时钟2004-02-2823:

59:

53

unsignedshortintyear=04,mon=2,day=28,hour=23,min=59,sec=53;

unsignedshortintx,num,page=0;

unsignedcharp3;

doubledx;

unsignedintset=0,p=0;//p表示当前修改哪个位

unsignedintkey=0,temp=10;

longintdiv_val=1,div=1,data=0,dat=0;

voidmInitSTDIO()//系统初始化

{

unsignedchari;

//主时钟初始化

WDTCTL=WDTPW+WDTHOLD;//stopwatchdogtimer

FLL_CTL0|=XCAP14PF;//Configureloadcaps

//定时器A初始化

TACTL=TASSEL0+TACLR;//ACLK,clearTAR

TACCTL0=CCIE;//CCR0interruptenabled

TACCR0=32768;//定时器常数(1秒)

TACTL|=MC0;//StartTimer_ainupmode

//定时器B初始化

TBCTL=TASSEL0+TACLR;//ACLK,clearTAR

TBCCTL0=CCIE;//CCR0interruptenabled

TBCCR0=328;//定时器常数(1/100秒)

TBCTL|=MC0;

//P口初始化

P1DIR=0;//设置P1.0~P1.7为输入方式

P1IFG=0;//清除P1的中断标志

P1IE=0xFF;//设置P1.0~P1.7中断

P1IES=0xFF;//设置P1.0~P1.7下降沿中断

P2DIR|=0xCF;//设置P2.0~P2.3,P2.6,P2.7为输出方式

P3DIR=0xFF;//设置P3.0~P3.7为输出方式

P4DIR|=0xFC;//设置P4.2~P4.7为输出方式

P5SEL=0xFF;//P5用于LCD显示

P6SEL=1;//P6.0用于ADC

P3DIR|=0xFE;//设置P6.1~P6.7为输出方式(临时)

//初始化LCD

LCDCTL=LCDON+LCD4MUX+LCDP0;//4-MuxLCD,segmentsS0-S15

BTCTL=BTFRFQ1;

for(i=0;i<8;i++)LCDMEM[i]=0;//清除显示

}

//========================主程序====================================

voidmain(void)

{

charx=0;

mInitSTDIO();//系统初始化

_EINT();//开启中断

for(dx=0;dx<1000;dx++);

printf("Start\n");

while

(1)

{

while(page%2==0&&set==0)//判断条件为偶数页,显示时分秒

{

LCDMEM[0]=LCD_Tab[sec%10];

LCDMEM[1]=LCD_Tab[sec/10];

LCDMEM[2]=LCD_Tab[min%10];

LCDMEM[3]=LCD_Tab[min/10];

LCDMEM[4]=LCD_Tab[hour%10];

LCDMEM[5]=LCD_Tab[hour/10];

//_BIS_SR(LPM3_bits);//EnterLPM3

_BIS_SR(LPM0_bits);//EnterLPM0

}

while(page%2==1&&set==0)//判断条件为奇数页,显示年月日

{

LCDMEM[0]=LCD_Tab[day%10];

LCDMEM[1]=LCD_Tab[day/10];

LCDMEM[2]=LCD_Tab[mon%10];

LCDMEM[3]=LCD_Tab[mon/10];

LCDMEM[4]=LCD_Tab[year%10];

LCDMEM[5]=LCD_Tab[year/10];

_BIS_SR(LPM3_bits);//EnterLPM3

_BIS_SR(LPM0_bits);//EnterLPM0

}

while(set==1)//set=1时,设置模式

{

LCDMEM[0]=LCD_Tab[temp];//最低位闪烁

for(dx=0;dx<1000;dx++);

LCDMEM[0]=LCD_Tab[16];//空白,不显示

for(dx=0;dx<2000;dx++);

//-------------------------------字符串输入------------------------------------------

while(key<0x0a)//按键为0~9,可进行修改

{

data=data*10+key;dat=data;

x=p;

do

{LCDMEM[x--]=LCD_Tab[dat/div];

dat%=div;

div/=10;

}while(div);

div_val=div_val*10;div=div_val;

p++;p%=6;temp=key;key=0x0a;

}//data为输入的6位数,start键确认修改

}//设置模式end~~~

//修改建议:

尝试按位修改时间

}//while

(1)

}//=======main结束=========

//------------------------------TimerA0中断服务程序--------------------------------------------

#pragmavector=TIMERA0_VECTOR

__interruptvoidTimer_A0(void)

{

p3<<=1;

if(p3==0)p3=1;

P3OUT=p3;//LED流水灯

switch(mon)//判断每个月的天数,保存为num

{

case1:

num=31;break;

case2:

if(year%4==0)num=29;

elsenum=28;break;

case3:

num=31;break;

case4:

num=30;break;

case5:

num=31;break;

case6:

num=30;break;

case7:

num=31;break;

case8:

num=31;break;

case9:

num=30;break;

case10:

num=31;break;

case11:

num=30;break;

case12:

num=31;break;

}

if(sec>=59)//实现时间的进位

{sec=0;

if(min>=59)

{min=0;

if(hour>=23)

{hour=0;

if(day>=num)

{day=1;

if(mon>=112)

{mon=1;year++;year%=100;}

elsemon++;

}

elseday++;

}

elsehour++;

}

elsemin++;

}

elsesec++;

//_BIC_SR_IRQ(LPM3_bits);//ClearLPM3bitsfrom0(SR)

_BIC_SR_IRQ(LPM0_bits);//ClearLPM0,SETBREAKPOINTHERE

//修改建议:

判断部分移入main函数

}

//TimerB0中断服务程序

#pragmavector=TIMERB0_VECTOR

__interruptvoidTimer_B0(void)

{

x<<=1;//键盘扫描

if((x&0x07)==0)x=1;

P2OUT=(~x)&0x07;

//_BIC_SR_IRQ(LPM3_bits);//ClearLPM3bitsfrom0(SR)

_BIC_SR_IRQ(LPM0_bits);//ClearLPM0,SETBREAKPOINTHERE

}

//~~~~~~~~~~~~~~~~~~P1中断服务程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#pragmavector=PORT1_VECTOR

__interruptvoidP1INT(void)

{registerintscan=0,pressed;//寄存器变量存储按键中间值

do

{scan=~P2IN;

scan&=0x0007;

scan<<=8;

scan|=P1IFG;//扫描得到scan

for(dx=0;dx<800;dx++);//延时数值自己调整

pressed=~P2IN;

pressed&=0x0007;

pressed<<=8;

pressed|=P1IFG;//延时后得到pressed

}while(scan!

=pressed);//可以确定键值,下一步操作

switch(scan)

{

case0x0101:

key=0;break;//"0"键键值

case0x0102:

key=1;break;//"1"键键值

case0x0104:

key=2;break;//"2"键键值

case0x0108:

key=3;break;//"3"键键值

case0x0110:

key=4;break;//"4"键键值

case0x0120:

key=5;break;//"5"键键值

case0x0140:

key=6;break;//"6"键键值

case0x0180:

key=7;break;//"7"键键值

case0x0201:

key=8;break;//"8"键键值

case0x0202:

key=9;break;//"9"键键值

case0x0204:

key=0x0a;break;//"A"键键值

case0x0208:

key=0x0b;break;//"B"键键值

case0x0210:

key=0x0c;break;//"C"键键值

case0x0220:

key=0x0d;break;//"D"键键值

case0x0240:

key=0x0e;break;//"E"键键值

case0x0280:

key=0x0f;break;//"F"键键值

case0x0401:

key=0x10;page++;break;//"UP"键键值

case0x0402:

key=0x11;page++;break;//"DN"键键值

case0x0404:

key=0x12;p++;break;//"L"键键值

case0x0408:

key=0x13;p--;break;//"R"键键值

case0x0410:

key=0x14;//"STRAT"键键值

if(page%2==0)

{hour=data/10000;

min=(data%10000)/100;

sec=data%100;}

if(page%2==1)

{year=data/10000;

mon=(data%10000)/100;

day=data%100;}

set=0;//start确认修改

LCDMEM[6]=LCD_Tab[16];

break;

case0x0420:

key=0x15;//"STOP"键键值

set=0;//按stop取消修改

LCDMEM[6]=LCD_Tab[16];

break;

case0x0440:

key=0x16;//"ESC"键键值

set=1;p=0;data=0;dat=0;div=0;div_val=0;//记得初始化

LCDMEM[6]=LCD_Tab[14];//首位显示E表示进入手动设置

LCDMEM[p]=LCD_Tab[10];//修改处显示A

break;

case0x0480:

key=0x17;break;//"ENTER"键键值

default:

LCDMEM[6]=0;break;//其它情况

}

P1IFG=0;

_BIC_SR_IRQ(LPM0_bits);//ClearLPM3bitsfrom0(SR)

}

资料仅供参考!

!

!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 少儿英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1