单片机课程设计my.docx

上传人:b****6 文档编号:6962439 上传时间:2023-01-13 格式:DOCX 页数:23 大小:61.11KB
下载 相关 举报
单片机课程设计my.docx_第1页
第1页 / 共23页
单片机课程设计my.docx_第2页
第2页 / 共23页
单片机课程设计my.docx_第3页
第3页 / 共23页
单片机课程设计my.docx_第4页
第4页 / 共23页
单片机课程设计my.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

单片机课程设计my.docx

《单片机课程设计my.docx》由会员分享,可在线阅读,更多相关《单片机课程设计my.docx(23页珍藏版)》请在冰豆网上搜索。

单片机课程设计my.docx

单片机课程设计my

湖南科技大学

信息与电气工程学院

 

单片机微机原理课程设计报告

课程:

单片机微机原理及接口技术

题目:

基于STC15F2K60S的电子万年历

专业:

通信工程

班级:

通信一班

姓名:

孟焱

学号:

1204040101

指导教师:

宋芳

 

任务书

题目

基于STC15F2K60S单片机的电子万年历

时间安排

2015年6月6——6月19日(第15、16周)

目的:

通过《单片机原理与应用》这门课的课程设计,学生应能对STC15F2K60S单片机有一个全面的认识,掌握以STC15F2K60S单片机为核心的电子电路的设计方法和应用技术。

1.进一步掌握矩阵键盘电路的编程方法。

2.进一步掌握定时器的使用和编程方法。

3.进一步掌握中断处理程序的编程方法。

总体方案实现:

1、利用STC15F2K60S作为主控器组成一个电子日历和电子钟。

2、利用LED分别显示当前时间和日历。

3、利用开发板上自带的24个按键作为输入按钮(实际用到13个),实现手动输入时间信息。

4、利用开关k1,k2作为两个外部中断触发装置,利用两个中断子程序分别实现被修改位的选择和进入修改模式。

5利用扫描法实现对键盘矩阵的扫描,确定被按下的按键。

要求:

1、利用STC15F2K60S作为主控器组成一个电子日历和电子钟

2、利用开发板上提供的矩阵键盘电路,数码显示电路,设计一个电子钟(日历),用矩阵键盘控制电子钟(日历)的模式转换及修改时间。

指导教师评语:

 

评分等级:

【】

指导教师签名:

一、引言

单片机因将其主要组成部分集成在一个芯片上而得名,就是把中央处理器、随机存储器、只读存储器、中断系统、定时器/计数器以及I/O接口电路等部件集成在一个芯片上。

基于单片机设计的数字钟精确度较高,因为在程序的执行过程中,任何指令都不影响定时器的正常计数,即便程序很长也不会影响中断的时间。

数字钟是采用数字电路实现对日期、时、分、秒,数字显示的计时装置,由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表的报时功能。

数字钟已成为人们日常生活中的必需品,广泛应用于家庭、车站、码头、剧院、办公室等场所,给人们的生活、学习、工作带来极大的方便。

不仅如此,在现代化的进程中,也离不开电子钟的相关功能和原理,比如机械手的控制、家务的自动化、定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等,所有这些,都是以钟表数字化为基础的。

而且是控制的核心部分。

因此,研究数字钟及扩大其应用,有着非常现实的意义。

二、设计任务和要求

1、利用STC15F2K60S作为主控器组成一个电子日历和电子钟

2、利用开发板上提供的矩阵键盘电路,数码显示电路,设计一个电子钟(日历),用矩阵键盘控制电子钟(日历)的模式转换及修改时间。

三、设计方案

1、利用STC15F2K60S作为主控器组成一个电子日历和电子钟。

2、利用LED分别显示当前时间和日历。

3、利用开发板上自带的24个按键作为输入按钮(实际用到13个),实现手动输入时间信息。

4、利用开关k1,k2作为两个外部中断触发装置,利用两个中断子程序分别实现被修改位的选择和进入修改模式。

5利用扫描法实现对键盘矩阵的扫描,确定被按下的按键。

注:

电子钟做成如下两种格式(按B键两种格式可以切换):

XX-XX-XX由左向右分别为:

时、分、秒

XX-XX-XX由左向右分别为:

年、月、日

(1)矩阵键盘上0~9键分别对应数字0~9用于时间的输入

(2)矩阵键盘上A键用于两种模式之间转换,两种模式下分别显示年月日和时分秒

(3)矩阵键盘上B键用于对输入数字进行确认

(4)矩阵键盘上C键用于进入闹钟时间设定模式

(5)独立按键k1用于对被修改位的选择

(6)独立按键k2用于进入日历修改模式

三、程序设计

#defineMAIN_Fosc22118400L//定义主时钟

#include"STC15Fxxxx.H"

/******************************用户定义宏***********************************/

#defineTimer0_Reload(65536UL-(MAIN_Fosc/1000))//Timer0中断频率,1000次/秒

#defineDIS_DOT0x20

#defineDIS_BLACK0x10

#defineDIS_0x11

/*************本地常量声明**************/

u8codet_display[]={//标准字库

//0123456789ABCDEF

0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,

//black-HJKLNoPUtGQrMy

0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,

0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};//0.1.2.3.4.5.6.7.8.9.-1

u8codeT_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位码

/*************IO口定义**************/

sbitP_HC595_SER=P4^0;//pin14SERdatainput

sbitP_HC595_RCLK=P5^4;//pin12RCLkstore(latch)clock

sbitP_HC595_SRCLK=P4^3;//pin11SRCLKShiftdataclock

sbitled7=p1^7;

/*************本地变量声明**************/

u8LED8[8];//显示缓冲

u8display_index;//显示位索引

bitB_1ms;//1ms标志

u8ch;

u8mod;

u8hour,minute,second,day,month,year,one,two,three;//时间变量

u16msecond;

u8ahour,aminute,aa,ab,ach,atem;//闹钟时间变量

//----键盘相关变量------

u8IO_KeyState,IO_KeyState1,IO_KeyHoldCnt;//行列键盘变量

u8KeyHoldCnt;//键按下计时

u8KeyCode;//给用户使用的键码,1~16有效

u8cnt50ms;

u8a;

u8b;

u8tem;

u8codeT_KeyTable[16]={0,1,2,0,3,0,0,0,4,0,0,0,0,0,0,0};

/*************本地函数声明**************/

voidIO_KeyScan(void);//50mscall

voidIO_KeyDelay(void);

voidplay(u8ch,u8a,u8b);

voidalarm();

//-----延时子程序-----

voiddelay(unsignedintt)

{

unsignedintk,j;

for(k=0;k

{

for(j=0;j<10000;j++);

if(0==0)

{

for(j=0;j<10000;j++);

for(j=0;j<10000;j++);

}

}

}

/******************************************

1、显示时钟函数************************/

voidDisplayRTC(void)

{

if(minute>=60)

{

minute=0;

}

if(hour>=24)

{

hour=0;

}

if(day>=30)

{

day=0;

}

if(month>=12)

{

month=0;

}

if(year>=99)

{

year=0;

}

if(mod==0)

{

one=hour;

two=minute;

three=second;

}

else

{

one=year;

two=month;

three=day;

}

LED8[0]=one/10;

LED8[1]=one%10;

LED8[2]=DIS_;

LED8[3]=two/10;

LED8[4]=two%10;

LED8[5]=DIS_;

LED8[6]=three/10;

LED8[7]=three%10;

}

/**********************

2、RTC演示函数************************/

voidRTC(void)

{

if(++second>=60)

{

second=0;

if(++minute>=60)

{

minute=0;

if(++hour>=24)

{

hour=0;

if(++day>30)

{

day=0;

if(++month>12)

{

month=0;

if(++year>=99)

{

year=0;

}

}

}

}

}

}

}

/*****************

3、外部中断0子程序**************/

voidint0()interrupt0

{

ch++;

if(ch>=6)

{

ch=0;

}

delay(8);

IE0=0;

}

/****************

4、外部中断1子程序******************/

voidint1()interrupt2

{

a=0;

b=0;

KeyCode=0;

while(KeyCode!

=28)//输入被修改位的高位,按下B键确认

{

if(++cnt50ms>=50)//50ms扫描一次行列键盘

{

cnt50ms=0;

IO_KeyScan();

}

if(KeyCode!

=28)

{

a=KeyCode-17;

play(ch,a,0);

}

}

RTC();

DisplayRTC();

KeyCode=0;

delay(8);

while(KeyCode!

=28)//输入被修改位的低位,按下B键确认

{

if(++cnt50ms>=50)//50ms扫描一次行列键盘

{

cnt50ms=0;

IO_KeyScan();

}

if(KeyCode!

=28)

{

b=KeyCode-17;

play(ch,a,b);

}

}

tem=a*10+b;//被修改后数据寄存在tem变量中

if(ch==0)//判断被修改的是哪一位,并赋予修改后值

{

hour=tem;

}

elseif(ch==1)

{

minute=tem;

}

elseif(ch==2)

{

second=tem;

}

elseif(ch==3)

{

year=tem;

}

elseif(ch==4)

{

month=tem;

}

elseif(ch==5)

{

day=tem;

}

else

{

alarm();

}

KeyCode=0;

DisplayRTC();

delay(8);

IE1=0;

}

/**********************

5、主函数************************/

voidmain(void)

{

u8i,k;

ch=0;

IP=0x03;//将定时器0中断赋予高优先级,使修改模式下能够正常显示修改结果

P0M1=0;P0M0=0;//设置为准双向口

P1M1=0;P1M0=0;//设置为准双向口

P2M1=0;P2M0=0;//设置为准双向口

P3M1=0;P3M0=0;//设置为准双向口

P4M1=0;P4M0=0;//设置为准双向口

P5M1=0;P5M0=0;//设置为准双向口

P6M1=0;P6M0=0;//设置为准双向口

P7M1=0;P7M0=0;//设置为准双向口

AUXR=0x80;//Timer0setas1T,16bitstimerauto-reload,

TH0=(u8)(Timer0_Reload/256);

TL0=(u8)(Timer0_Reload%256);

ET0=1;//Timer0interruptenable

TR0=1;//Tiner0run

EA=1;//打开总中断

EA=1;

EX0=1;

IT0=1;

EX1=1;

IT1=1;

display_index=0;

year=90;

month=01;

day=01;

hour=11;//初始化时间值

minute=59;

second=59;

KeyCode=0;

a=0;

b=0;

mod=0;

//for(i=0;i<8;i++)LED8[i]=DIS_BLACK;//上电消隐

for(i=0;i<8;i++)LED8[i]=i;//显示01234567

k=0;

while

(1)

{

if(++cnt50ms>=50)//50ms扫描一次行列键盘

{

cnt50ms=0;

IO_KeyScan();

}

if(KeyCode==27)//改变显示模式

{

if(mod==0)

{

mod=1;

}

else

{

mod=0;

}

RTC();

DisplayRTC();

delay(8);

KeyCode=0;

}

if(ahour==hour||aminute==minute)//判断是否到闹钟时间决定是否响铃

{

led7=0;//使用led7代替蜂鸣器,灯亮表示蜂鸣器响

}

else

{

led7=1;

}

if(KeyCode==29)

{

alarm();

KeyCode=0;

}

if(B_1ms)//1ms到

{

B_1ms=0;

if(++msecond>=500)//1秒到

{

msecond=0;

RTC();

DisplayRTC();

}

}

}

}

/****************

6、向HC595发送一个字节函数******************/

voidSend_595(u8dat)

{

u8i;

for(i=0;i<8;i++)

{

dat<<=1;

P_HC595_SER=CY;

P_HC595_SRCLK=1;

P_HC595_SRCLK=0;

}

}

/**********************

7、显示扫描函数************************/

voidDisplayScan(void)

{

Send_595(~T_COM[display_index]);//输出位码

Send_595(t_display[LED8[display_index]]);//输出段码

P_HC595_RCLK=1;

P_HC595_RCLK=0;//锁存输出数据

if(++display_index>=8)display_index=0;//8位结束回0

}

/**********************

8、Timer01ms中断函数************************/

voidtimer0(void)interruptTIMER0_VECTOR

{

DisplayScan();//1ms扫描显示一位

B_1ms=1;//1ms标志

}

voidIO_KeyDelay(void)

{

u8i;

i=60;

while(--i);

}

voidIO_KeyScan(void)//50mscall

{

u8j;

j=IO_KeyState1;//保存上一次状态

P0=0xf0;//X低,读Y

IO_KeyDelay();

IO_KeyState1=P0&0xf0;

P0=0x0f;//Y低,读X

IO_KeyDelay();

IO_KeyState1|=(P0&0x0f);

IO_KeyState1^=0xff;//取反

if(j==IO_KeyState1)//连续两次读相等

{

j=IO_KeyState;

IO_KeyState=IO_KeyState1;

if(IO_KeyState!

=0)//有键按下

{

F0=0;

if(j==0)F0=1;//第一次按下

elseif(j==IO_KeyState)

{

if(++IO_KeyHoldCnt>=20)//1秒后重键

{

IO_KeyHoldCnt=18;

F0=1;

}

}

if(F0)

{

j=T_KeyTable[IO_KeyState>>4];

if((j!

=0)&&(T_KeyTable[IO_KeyState&0x0f]!

=0))

KeyCode=(j-1)*4+T_KeyTable[IO_KeyState&0x0f]+16;//计算键码

}

}

elseIO_KeyHoldCnt=0;

}

P0=0xff;

}

/*************

9、修改模式下显示函数********************/

voidplay(u8ch,u8a,u8b)

{

u8tea,teb;

tea=a;

teb=b;

if(a>9)

{

tea=0;

}

if(b>9)

{

teb=0;

}

if(ch==0||ch==3)

{

LED8[0]=tea;

LED8[1]=teb;

if(ch==0)

{

LED8[2]=DIS_;

}

else

{

LED8[2]=DIS_BLACK;

}

LED8[3]=DIS_BLACK;

LED8[4]=DIS_BLACK;

if(ch==0)

{

LED8[5]=DIS_;

}

else

{

LED8[5]=DIS_BLACK;

}

LED8[6]=DIS_BLACK;

LED8[7]=DIS_BLACK;

}

elseif(ch==1||ch==4)

{

LED8[0]=DIS_BLACK;

LED8[1]=DIS_BLACK;

if(ch==1)

{

LED8[2]=DIS_;

}

else

{

LED8[2]=DIS_BLACK;

}

LED8[3]=tea;

LED8[4]=teb;

if(ch==1)

{

LED8[5]=DIS_;

}

else

{

LED8[5]=DIS_BLACK;

}

LED8[6]=DIS_BLACK;

LED8[7]=DIS_BLACK;

}

else

{

LED8[0]=DIS_BLACK;

LED8[1]=DIS_BLACK;

if(ch==2)

{

LED8[2]=DIS_;

}

else

{

LED8[2]=DIS_BLACK;

}

LED8[3]=DIS_BLACK;

LED8[4]=DIS_BLACK

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

当前位置:首页 > 总结汇报

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

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