单片机课程设计报告东北石油大学Word文档下载推荐.docx
《单片机课程设计报告东北石油大学Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《单片机课程设计报告东北石油大学Word文档下载推荐.docx(27页珍藏版)》请在冰豆网上搜索。
2、蔡美琴.MCS-51系列单片机系统及其应用.北京:
高等教育出版社,2004.
完成期限2013-7-7
指导教师
专业负责人
2013年6月28日
第1章绪论
1.1概述
随着电子技术的迅速发展,特别是随着大规模集成电路产生而出现的微型计算机,给人类生活带来了极大的方便。
走入家庭,从洗衣机、微波炉到音响、汽车,到处都可以见到单片机应用的踪影。
如果说微型计算机技术的出现使现代科学研究得到了质的飞跃,那么也可以毫不夸张的说:
“单片机技术的出现则是给现代工业测控领域带来了一次新的工业革命”。
目前,单片机以其可靠性高和智能性等特点被广泛应用到工业控制系统、数据采集系统、智能化仪器仪表、办公自动化等领域中,并已经进入家庭。
因此,单片机技术的开发和应用水平已经逐步成为一个国家自动化发展水平的标志之一。
1.2单片机的发展历程
单片机是微型计算机的一个重要分支,也是一种非常活跃和颇具生命力的机种,特别适用于工业控制领域。
1971年微处理器研制成功不久,就出现了单片机,但最早的单片机是1位的,处理能力有限。
单片机的发展共分四个阶段:
第一阶段是初级阶段,功能非常简单;
第二阶段是低性能阶段,以INTEL公司制造的MSC-48系列单片机为代表。
第三阶段为高性能单片机阶段,这个阶段推出的单片机普遍带有穿行接口,多级中断系统,16位定时器/计数器,片内ROM、RAM容量加大,直到现在仍被广泛应用,是目前应用数量较多的单片机。
第四阶段是8位单片机巩固发展以及16位单片机、32位单片机推出阶段,以满足不同的用户需要。
纵观单片机几十年的发展历程,单片机的今后发展方向将向多功能、高性能、高速度、低功耗、低价格、外围电路内装化以及内存储器容量增加和FLASH存储器化方向发展。
第2章系统结构及主要元器件
2.1系统结构
此次设计主要是应用单片机来设计电子日历,系统由主控制器AT89s51、时钟电路DS1302、显示电路、按键电路、和复位电路等部分构成,能实现时钟日历显示的功能,能进行时、分、秒的显示。
如图2-1系统总体结构图:
图2-1系统总体结构图
2.2主要元器件
本系统的主要元器件有AT89S51单片机,DS1302时钟芯片,LED数码管或LM1602液晶显示屏。
第3章硬件设计
3.1主控制模块
AT89S51系列单片机中有PDIP,PLCC,TQFP多种封装形式。
本设计采用的是PDIP封装40管脚的单片机。
如图3-1所示:
图3-1AT89S51引脚图
3.2复位电路
复位是单片机的初始化操作。
单片机启运运行时,都需要先复位,其作用是使CPU和系统中其他部件处于一个确定的初始状态,并从这个状态开始工作。
因而,复位是一个很重要的操作方式。
但单片机本身是不能自动进行复位的,必须配合相应的外部电路才能实现。
复位电路的基本功能是:
系统上电时提供复位信号,直至系统电源稳定后,撤销复位信号。
为可靠起见,电源稳定后还要经一定的延时才撤销复位信号,以防电源开关或电源插头分-合过程中引起的抖动而影响复位。
图3-2复位电路图
3.3晶振电路
晶体振荡器电路给数字钟提供一个频率稳定准确的32768Hz的方波信号,可保证数字钟的走时准确及稳定。
如图3-3所示:
图3-3晶振电路图
3.4DS1302时钟模块
3.4.1DS1302时钟模块
图3-4DS1302时钟模块图
3.4.2DS1302的引脚排列
图3-5所示出DS1302的引脚排列,其中Vcc1为后备电源,VCC2为主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
X1和X2是振荡源,外接32.768kHz晶振。
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送RST输入有两种功能:
首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;
其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc≥2.5V之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平。
I/O为串行数据输入输出端(双向),后面有详细说明。
SCLK始终是输入端。
数据输入输出
(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即从0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
图3-5DS1302的引脚图
3.5按键调节电路
本设计总的用了三个按扭开关作为键盘,其中两个是调整时间增加、减少的键,第三个是切换年、月、日及时、分、秒的显示状态并在所切换的显示状态下配合加减两个键调整时间。
如图3-6所示:
图3-6按键调节电路图
3.6显示模块
LCM1602采用标准的16脚接口,其中:
第1脚:
VSS为地电源第2脚:
VDD接5V正电源第3脚:
V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平选择指令寄存器。
第5脚:
RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RSRW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可读忙信号,当RS为高电平RW为低电平时可以写入数据.第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15~16脚:
空脚。
如图3-7所示:
图3-7显示模块图
第4章软件设计
4.1系统流程图
图4-1系统流程图
4.2程序设计
#include<
reg51.h>
#defineuintunsignedint
#defineucharunsignedchar
uchara,sec,hour,min,day,moon,year,week,flag,key1n,ZJL;
//ZJL为中间量
#defineyh0x80//LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)
#defineer0x80+0x40//LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)
//液晶屏的与C51之间的引脚连接定义(显示数据线接C51的P0口)
sbitrs=P3^5;
sbiten=P3^7;
sbitrw=P3^6;
//如果硬件上rw接地,就不用写这句和后面的rw=0了
//DS1302时钟芯片与C51之间的引脚连接定义
sbitIO=P2^2;
sbitSCLK=P2^1;
sbitRST=P2^0;
sbitACC0=ACC^0;
sbitACC7=ACC^7;
/************************************************************
ACC累加器=A
ACC.0=E0H
ACC.0就是ACC的第0位。
Acc可以位寻址。
**************************/
//校时按键与C51的引脚连接定义
sbitkey1=P2^5;
//设置键
sbitkey2=P2^6;
//加键
sbitkey3=P2^7;
//减键
/**************************************************************/
ucharcodetab1[]={"
20--"
};
//年显示的固定字符
ucharcodetab2[]={"
:
"
//时间显示的固定字符
//延时函数,后面经常调用
voiddelay(uintxms)//延时函数,有参函数
{uintx,y;
for(x=xms;
x>
0;
x--)
for(y=110;
y>
y--);
}
/********液晶写入指令函数与写入数据函数,以后可调用**************/
/*在这个程序中,液晶写入有关函数会在DS1302的函数中调用,所以液晶程序要放在前面*/
write_1602com(ucharcom)//****液晶写入指令函数****
{rs=0;
//数据/指令选择置为指令
rw=0;
//读写选择置为写
P1=com;
//送入数据
delay
(1);
en=1;
//拉高使能端,为制造有效的下降沿做准备
en=0;
//en由高变低,产生下降沿,液晶执行命令
}
write_1602dat(uchardat)//***液晶写入数据函数****
{rs=1;
//数据/指令选择置为数据
P1=dat;
//en置高电平,为制造下降沿做准备
//en由高变低,产生下降沿,液晶执行命令
lcd_init()//***液晶初始化函数****
{write_1602com(0x38);
//设置液晶工作模式,意思:
16*2行显示,5*7点阵,8位数据
write_1602com(0x0c);
//开显示不显示光标
write_1602com(0x06);
//整屏不移动,光标自动右移
write_1602com(0x01);
//清显示
write_1602com(yh+1);
//日历显示固定符号从第一行第1个位置之后开始显示
for(a=0;
a<
14;
a++)
{write_1602dat(tab1[a]);
//向液晶屏写日历显示的固定符号部分
//delay(3);
write_1602com(er+2);
//时间显示固定符号写入位置,从第2个位置后开始显示for(a=0;
8;
{write_1602dat(tab2[a]);
//写显示时间固定符号,两个冒号
/*********************over***********************/
/***************DS1302有关子函数********************/
voidwrite_byte(uchardat)//写一个字节
{ACC=dat;
RST=1;
for(a=8;
a>
a--)
{IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>
>
1;
ucharread_byte()//读一个字节
{RST=1;
{ACC7=IO;
ACC=ACC>
return(ACC);
//----------------------------------------
voidwrite_1302(ucharadd,uchardat)//向1302芯片写函数,指定写入地址,数据
{RST=0;
SCLK=0;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
ucharread_1302(ucharadd)//从1302读数据函数,指定读取数据来源地址
{ucharZJL;
ZJL=read_byte();
return(ZJL);
ucharBCD_Decimal(ucharbcd)//BCD码转十进制函数,输入BCD,返回十进制
{ucharDecimal;
Decimal=bcd>
4;
return(Decimal=Decimal*10+(bcd&
=0x0F));
//--------------------------------------
voidds1302_init()//1302芯片初始化子函数(2012-06-17,00:
00:
00,week7)
write_1302(0x8e,0x00);
//允许写,禁止写保护
//write_1302(0x80,0x12);
//向DS1302内写秒寄存器80H写入初始秒数据00
//write_1302(0x82,0x12);
//向DS1302内写分寄存器82H写入初始分数据00//write_1302(0x84,0x12);
//向DS1302内写小时寄存器84H写入初始小时数据00//write_1302(0x8a,0x04);
//向DS1302内写周寄存器8aH写入初始周数据7//write_1302(0x86,0x08);
//向DS1302内写日期寄存器86H写入初始日期数据17
//write_1302(0x88,0x08);
//向DS1302内写月份寄存器88H写入初始月份数据06//write_1302(0x8c,0x12);
//向DS1302内写年份寄存器8cH写入初始年份数据12
write_1302(0x8e,0x80);
//打开写保护
//------------------------------------//时分秒显示子函数
voidwrite_sfm(ucharadd,uchardat)//向LCD写时分秒,有显示位置加、现示数据,两个参数
{uchargw,sw;
gw=dat%10;
//取得个位数字
sw=dat/10;
//取得十位数字
write_1602com(er+add);
//er是头文件规定的值
0x80+0x40
write_1602dat(0x30+sw);
//数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw);
//-------------------------------------//年月日显示子函数
voidwrite_nyr(ucharadd,uchardat)//向LCD写年月日,有显示位置加数、显示数据,两个参数
write_1602com(yh+add);
//设定显示位置为第一个位置+add
//-------------------------------------------
voidwrite_week(ucharweek)//写星期函数
{write_1602com(yh+0x0c);
//星期字符的显示位置
switch(week)
{case1:
write_1602dat('
M'
);
//星期数为1时,显示
write_1602dat('
O'
N'
break;
case2:
T'
//星期数据为2时显示
U'
E'
break;
case3:
W'
//星期数据为3时显示
D'
case4:
//星期数据为4时显示
H'
case5:
F'
//星期数据为5时显示
R'
I'
case6:
S'
//星期数据为6时显示
A'
case7:
//星期数据为7时显示
//****************键盘扫描有关函数**********************
voidkeyscan()
{if(key1==0)//---------------key1为功能键(设置键)--------------------
{delay(9);
//延时,用于消抖动
if(key1==0)//延时后再次确认按键按下
delay(20);
while(!
key1);
key1n++;
if(key1n==9)
key1n=1;
//设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环
switch(key1n)
{case1:
TR0=0;
//关闭定时器
//TR1=0;
write_1602com(er+0x09);
//设置按键按动一次,秒位置显示光标
write_1602com(0x0f);
//设置光标为闪烁
ZJL=(sec)/10*16+(sec)%10;
//秒数据写入DS1302
write_1302(0x80,0x80|ZJL);
//sec
break;
case2:
write_1602com(er+6);
//按2次min位置显示光标
case3:
write_1602com(er+3);
//按动3次,hour位置显示光标
case4:
write_1602com(yh+0x0e);
//按动4次,week
//write_1602com(0x0f);
case5:
write_1602com(yh+0x0a);
//按动5次,day
case6:
write_1602com(yh+0x07);
//按动6次,moon
case7:
write_1602com(yh+0x04);
//按动7次,year
case8:
write_1602com(0x0c);
//按动到第8次,设置光标不闪烁
TR0=1;
//打开定时器
write_1302(0x80,0x00|ZJL);
//sec数据写入DS1302
//-----------------------------加键key2----------------------------
if(key1n!
=0)//当key1按下以下。
再按以下键才有效(按键次数不等于零)
{if(key2==0)//上调键
{delay(10);
if(key2==0)
{delay(20);
key2);
sec++;
//设置键按动1次,调秒
if(sec==60)
sec=0;
//秒超过59,再加1,就归零
write_sfm(0x08,sec);
//令LCD在正确位置显示"
加"
设定好的秒数
//十进制转换成DS1302要求的DCB码
write_1302(0x80,ZJL);
//向DS1302内写秒寄存器80H写入调整后的秒数据BCD码write_1302(0x8e,0x80);
//因为设置液晶的模式是写入数据后,光标自动右移,所以要指定返回
//write_1602com(0x0b);
min++;
if(min==60)
min=0;
write_sfm(0x05,min);
设定好的分数据
ZJL=(min)/10*16+(min)%10;
//允许写,禁止写保护
write_1302(0x82,ZJL);
//向DS1302内写分寄存器82H写入调整后的分数据BCD