LETS GO DIY设计+ 基于Launchpad的爱情万年历.docx
- 文档编号:7663121
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:18
- 大小:82.52KB
LETS GO DIY设计+ 基于Launchpad的爱情万年历.docx
《LETS GO DIY设计+ 基于Launchpad的爱情万年历.docx》由会员分享,可在线阅读,更多相关《LETS GO DIY设计+ 基于Launchpad的爱情万年历.docx(18页珍藏版)》请在冰豆网上搜索。
LETSGODIY设计+基于Launchpad的爱情万年历
本来是在准备重庆市TI电子设计大赛,这块launchpad的板子也是自己买的。
学习过程中越来越感觉得到launchpad的强大,一边学一边做东西,做到万年历的时候花了三天时间,终于调试成功,心里那个美啊。
后来想到女朋友在培训不在身边,就有了制作这个万年历的想法。
一、首先说一下硬件:
1、launchpad开发板一块(板载MSP430G2553)
2、LCD1602液晶屏一块
3、DS1302数字时钟芯片
4、32.768KHz晶振一枚
5、按键两枚
6、电位器一枚
7、电容、导线等
二、要实现的功能:
1、精确显示年月日时分秒
2、闰年、二月自动调节时间
3、两个按键控制调节时间日期等
4、显示自定义的语句
5、恋爱纪念日提醒,显示不一样的画面(We’vebeentogetherforXXyears!
)
三、硬件电路图
四、整体思路
//设置P1口作为输出连接LCD1602的数据端D0-D7,P2.0为rs,P2.1为rw,P2.2为e(都配置为输出)作为LCD1602的控制端口。
//配置P2.3为SCLK,P2.4为SDA,P2.5为RST(都配置为输出)作为DS1302的控制端
//P2.6、P2.7接两个按键,配置为输入,下降沿中断,中断处理函数voidkey_pro(),P2、6接key1(控制光标),P2.7接key2,控制调节
//grace配置中设置P2.0---P2.5为输出,MCLK=1MHz,关闭看门狗
//在做DS1302的硬件时应该特别注意:
数据线RST、SCLK、SDA一定上拉电阻,晶振添加负载电容,连接线尽量短
先列写出主函数,是思路清晰点:
voidmain(void)
{
CSL_init();//初始化单片机
lsd1602_init();//初始化LCD1602
ds1302_init();//初始化DS1302
while
(1)
{
_DINT();//关闭中断
data_pro();//从DS1302中读取并处理数据
_EINT();
if(month==0x03&&date==0x07)//3月7日是我们的纪念日
jww();//如果是3月7号则显示不同的画面(jww是处理函数)
update_disbuf();//更新LCD1602显示空间(在2553中开辟)
display();//控制LCD1602显示时间
if(month==0x03&&date==0x07)//3月7日纪念日
__delay_cycles(1000000);
}
}
就这样很简单的思路,全部使用了子程序调用,所以看起来清晰点,下面贴出来整个函数。
注释的挺多了,有什么建议或者交流的直接回复帖子。
五、程序
说一下阅读方法,先看懂了上边的主函数,然后对应主函数调用的子函数,一个一个来看,逐个看懂,就很简单。
(有一个难点,就是按键处理。
因为只用了两个按键,key1每按一次会有全局变量i增加一,控制LCD1602光标的显示位置,另外一个按键调节时间)
//设置P0作为输出连接LCD1602的数据端D0-D7,P2.3为SCLK,P2.4为SDA,P2.5为RST(都配置为输出)
//P2.0为rs,P2.1为rw,P2.2为e(都配置为输出)
//P2.67配置为输入,下降沿中断,中断处理函数voidkey_pro(),P2。
6接key1(控制光标),P2.7接key2,控制调节(增加)
//grace配置中设置P2.345为输出,MCLK=1MHz,
//本程序将数据用ASCII表示,方便LCD1602显示
//在做DS1302的硬件时应该特别注意:
数据线RST。
SCLK、SDA一定上拉电阻,晶振添加负载电容,连接线尽量短
//date代表日,day代表星期几
#include
#include
//定义全局变量年月日时分秒
charyear,month,date,hour,minute,second,n;//n代表周几
charlove_years;//恋爱纪念年
charday[7][3]={"MON","TUE","WED","THI","FRI","SAT","SUN"};
chari=0;//用来记录key1按下的次数
chardis_buf1[16];//lcd上排显示缓冲区
chardis_buf2[16];//lcd下排显示缓冲区
charweiwei1[16]={"weiwei:
Iloveu"};
charweiwei2[16]={"somuch!
byxuxu"};
charlove1[16]={"We'vebeentoget"};
charlove2[16]={"herforyears"};
//LCD1602控制位
#definers_0(P2OUT&=~BIT0)
#definers_1(P2OUT|=BIT0)
#definerw_0(P2OUT&=~BIT1)
#definerw_1(P2OUT|=BIT1)
#definee_0(P2OUT&=~BIT2)
#definee_1(P2OUT|=BIT2)
//DS1302控制位
#defineSCLK_0(P2OUT&=~BIT3)
#defineSCLK_1(P2OUT|=BIT3)
#defineSDA_0(P2OUT&=~BIT4)
#defineSDA_1(P2OUT|=BIT4)
#defineRST_0(P2OUT&=~BIT5)
#defineRST_1(P2OUT|=BIT5)
#defineSDA(P2IN&=BIT4)
//宏定义DS1302数据地址
#definewrite_second0x80
#defineread_second0x81
#definewrite_minute0x82
#defineread_minute0x83
#definewrite_hour0x84
#defineread_hour0x85
#definewrite_date0x86
#defineread_date0x87
#definewrite_month0x88
#defineread_month0x89
#definewrite_year0x8c
#defineread_year0x8d
#definewrite_day0x8a
#defineread_day0x8b
#definewrite_protect0x8e
#definewrite_power0x90
//*******************以下为LCD1602的子函数************************//
//***********************************************************//
//查询是否忙碌(每次输入指令前都要判断液晶模块是否处于忙的状态)
charbusy(void)
{
charbusyc;
rs_0;
rw_1;
e_1;
__delay_cycles(1000);
P1DIR=0x00;//P1口置为输入,读取LCD状态
busyc=P1IN&BIT7;//从P1输入是否忙碌(D7高电平表示忙碌)
P1DIR=0xff;
e_0;
returnbusyc;
}
//向LCD1602写字节命令
voidwrite_command(charcommand)
{
while(busy());//判断LCD是否忙碌
rs_0;
rw_0;
P1OUT=command;
__delay_cycles
(1);//时间间隔MIN=30nS
e_1;
__delay_cycles
(1);//MIN=150nS
e_0;
}
//向LCD1602写数据命令
voidwrite_data(chardata)
{
while(busy());//判断LCD是否忙碌
rs_1;
rw_0;
__delay_cycles
(1);
e_1;
P1OUT=data;
__delay_cycles
(1);
e_0;
}
//LCD1602初始化函数
voidlsd1602_init()
{
e_0;
write_command(0x38);
__delay_cycles(15000);
write_command(0x0c);
write_command(0x06);
write_command(0x01);
}
voidupdate_disbuf()
{
dis_buf1[0]='2';
dis_buf1[1]='0';
dis_buf1[2]=year/16+0x30;
dis_buf1[3]=year%16+0x30;
dis_buf1[4]='-';
dis_buf1[5]=month/16+0x30;
dis_buf1[6]=month%16+0x30;
dis_buf1[7]='-';
dis_buf1[8]=date/16+0x30;
dis_buf1[9]=date%16+0x30;
dis_buf1[10]='';
dis_buf1[11]='';
dis_buf1[12]='';
dis_buf1[13]=day[n-1][0];
dis_buf1[14]=day[n-1][1];
dis_buf1[15]=day[n-1][2];
dis_buf2[0]='';
dis_buf2[1]='j';
dis_buf2[2]='w';
dis_buf2[3]='w';
dis_buf2[4]='&';
dis_buf2[5]='z';
dis_buf2[6]='x';
dis_buf2[7]='';
dis_buf2[8]=hour/16+0x30;
dis_buf2[9]=hour%16+0x30;
dis_buf2[10]=':
';
dis_buf2[11]=minute/16+0x30;
dis_buf2[12]=minute%16+0x30;
dis_buf2[13]=':
';
dis_buf2[14]=second/16+0x30;
dis_buf2[15]=second%16+0x30;
}
voiddisplay()
{
chart;
write_command(0x80);
for(t=0;t<=15;t++)
{write_data(dis_buf1[t]);}
write_command(0xc0);
for(t=0;t<=15;t++)
{write_data(dis_buf2[t]);}
}
//********************以下为DS1302的子函数************************//
//***********************************************************//
//向DS1302写一个字节的数据
voidds1302_Wbyte(chardat)
{
chars,temp;
temp=dat;
for(s=0;s<8;s++)
{if(temp&0x01)//从低位开始传输数据
{SDA_1;}
else
SDA_0;
SCLK_1;//上升沿锁存数据
temp=temp>>1;//数据右移一位为下次输出做准备
SCLK_0;//为下一次做准备
}
}
//从DS1302读取8位数据
chards1302_Rbyte()
{
charu,temp;
P2DIR&=~BIT4;
for(u=8;u>0;u--)
{
temp=temp>>1;
temp+=(P2IN&BIT4)<<3;
SCLK_1;
SCLK_0;
}
P2DIR|=BIT4;
return(temp);
}
//向DS1302写入地址然后读取数据
chards1302_Read(charcmd)
{
chardat;
RST_0;//初始化RST为低
SCLK_0;//SLK=0
RST_1;//开始传输数据
ds1302_Wbyte(cmd);//传输命令字,写入要读取的时间、日期地址
dat=ds1302_Rbyte();//读取八位数据
RST_0;//结束数据传输
SCLK_0;//拉高时钟线
return(dat);
}
//向DS1302写入地址后写入数据
voidds1302_Write(charcmd,chardat)
{
RST_0;
SCLK_0;//在RST的上升沿,SCLK必须为0
RST_1;//开始传输数据
ds1302_Wbyte(cmd);//写入要修改的地址
ds1302_Wbyte(dat);//写入数据
SCLK_1;//拉高时钟线
RST_0;//拉低RST
}
//初始化DS1302的程序
voidds1302_init(void)
{
ds1302_Write(write_protect,0x00);//关闭写保护
ds1302_Write(write_second,0x00);//初始化秒为00,不暂停时钟(BIT7)
ds1302_Write(write_minute,0x59);//初始化分为00
ds1302_Write(write_hour,0x23);//初始化时为23,设置为24小时制(BIT7)
ds1302_Write(write_date,0x01);//初始化日期为01
ds1302_Write(write_month,0x01);//初始化月为01
ds1302_Write(write_year,0x12);//初始化年为(20)12
ds1302_Write(write_day,0x07);//周日
ds1302_Write(write_power,0x0a5);//一个二极管压降,电阻4K
ds1302_Write(write_protect,0x80);//打开写保护
}
//DS1302数据处理函数,此函数将个位、十位分别用char表示,方便用数码管显示
voiddata_pro(void)
{
ds1302_Write(write_protect,0x00);//关闭写保护
date=ds1302_Read(read_date);//读取日
if(date>0x29&&month==0x02)//如果调时时2月超过29
{ds1302_Write(write_date,0x01);
date=ds1302_Read(read_date);
ds1302_Write(write_month,month+1);
}
month=ds1302_Read(read_month);//读取月
year=ds1302_Read(read_year);//读取年
hour=ds1302_Read(read_hour);//读取时
hour=hour&0x3f;//屏蔽掉前两位
minute=ds1302_Read(read_minute);//读取分
second=ds1302_Read(read_second);//读取秒
n=ds1302_Read(read_day);//读取星期
ds1302_Write(write_protect,0x80);//打开写保护
}
//按键中断处理程序(使用grace配置)
voidkey_pro(void)
{
charj;//用于复制自定义的显示计数(16个)
__delay_cycles(8000);//延时去抖动
if(!
(P2IN&BIT6))//判断是否有按键按下
{
i++;
switch(i)
{
case1:
write_command(0x83);//显示光标到年
write_command(0x0f);
break;
case2:
write_command(0x86);//显示光标到月
write_command(0x0f);
break;
case3:
write_command(0x89);//显示光标到日
write_command(0x0f);
break;
case4:
write_command(0x8f);//显示光标到周
write_command(0x0f);
break;
case5:
write_command(0xc9);//显示光标到时
write_command(0x0f);
break;
case6:
write_command(0xcc);//显示光标到分
write_command(0x0f);
break;
case7:
write_command(0xcf);//显示光标到秒
write_command(0x0f);
break;
default:
break;
}
}
if(i>7)
{
i=0;
write_command(0x0c);//关闭光标显示
}
P2IFG=0;//软件复位标志
while(!
(P2IN&BIT6))
{
ds1302_Write(write_protect,0x00);//关闭写保护
while(!
(P2IN&BIT7))//如果按键2被按下
{
switch(i)//根据i的值来确定某变量进行加1
{case0:
//显示自定义的语句
for(j=0;j<16;j++)
{
dis_buf1[j]=weiwei1[j];
dis_buf2[j]=weiwei2[j];
display();
}
break;
case1:
//此事处理全局变量year
year++;//year加1
if(year>0x99)//如果year大于99则置0
year=0;
if((year&0x0f)>0x09)//如果year低四位大于9(第四位BCD码表示个位),十位加1,个位置0
{year+=0x10;
year&=0xf0;
}
ds1302_Write(write_year,year);//将变化后的year写入DS1302
year=ds1302_Read(read_year);//读出来year显示(使调节year时同步变化,为了人性化)
update_disbuf();//更新显示字符
while(!
(P2IN&BIT7))
display();
break;
case2:
//此时处理全局变量month
month++;
if(month>0x12)
month=1;
if((month&0x0f)>0x09)
{month+=0x10;
month&=0xf0;
}
ds1302_Write(write_month,month);
month=ds1302_Read(read_month);
update_disbuf();//更新显示字符
while(!
(P2IN&BIT7))
display();
break;
case3:
//此时处理全局变量date
date++;
if((date>0x29&&month==0x02)
||(month==0x04||month==0x06||month==0x09||month==0x11)&&date>0x30
||date>0x31)
date=0x01;
if((date&0x0f)>0x09)
{date+=0x10;
date&=0xf0;
}
ds1302_Write(write_date,date);
date=ds1302_Read(read_date);
update_disbuf();//更新显示字符
while(!
(P2IN&BIT7))
display();
break;
case4:
//此时处理全局变量day
n++;
if(n>0x07)
n=1;
ds1302_Write(write_day,n);
n=ds1302_Read(read_day);
update_disbuf();//更新显示字符
while(!
(P2IN&BIT7))
display();
break;
case5:
//此时处理全局变量hour
hour++;
if(hour>0x23)
hour=0;
if((hour&0x0f)>0x09)
{hour+=0x10;
hour&=0xf0;
}
ds1302_Write(write_hour,hour);
hour=ds1302_R
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LETS GO DIY设计+ 基于Launchpad的爱情万年历 DIY 设计 基于 Launchpad 爱情 万年历