单片机C语言课程设计报告书.doc
. . . . 交通学院 基于单片机的电子钟设计 系 部:信息工程系 学生: 朱珂锋 指导教师:海 专 业:电子信息工程技术应用 班 级:电信二班学 号:0243 摘 要51系列单片机是各单片机中最为典型和最有代表性的一种。由RAM ,ROM,CPU构成,定时,计数和多种接口于一体的微控制器。本次设计的数字电子钟采用了AT89C51芯片进行,由8位8段数码管进行动态刷新显示,有四个独立按键。可以进行秒、分、时的调整,且操作简单,计时误差小,显示亮度高,具有良好的实用价值。这次课程设计通过对它的学习,应用,从而达到学习、设计、开发软、硬的能力。应用Proteus软件实现了单片机电子时钟系统的设计与仿真。该方法仿真效果真实、准确,节省了硬件资源。关键词 数字电子钟;单片机;C语言目 录1 设计课题题目、目的要求与总体方案介绍41.1 设计课题题目41.2 设计课题目的41.3 设计课题要求与工作原理说明42 数字电子钟硬件系统的设计52.1 硬件总体设计52.2 数字电子钟硬件系统主要模块功能简要介绍52.3 数字电子钟电路原理图、PCB图、元器件布局图62.4 数字电子钟元器件清单73 数字电子钟软件系统的设计83.1 数字电子钟软件系统主要模块功能简要介绍83.2 数字电子钟软件系统程序流程框图83.3 数字电子钟软件系统程序清单94 设计结论、仿真结果、误差分析124.1 数字电子钟的仿真结果124.2 数字电子钟的误差分析134.3 设计重点、难点,体会与不足之处13参考文献14致15附录161 设计课题题目、目的要求与总体方案介绍1.1 设计课题题目基于单片机的电子钟设计。1.2 设计课题目的巩固单片机技术课程所学的有关知识。通过硬件设计、软件设计,使学生掌握用单片机组成应用系统的方法,提高软件设计能力。掌握单片机的定时/计数器的编程和使用方法。进一步熟悉单片机功能部件的应用。1.3 设计课题要求与工作原理说明要求自己做出原理图设计。并且要扩展一片8255芯片作显示接口,分别输出段码和位码;用P1口中的两根口线作功能键。可利用四个LED分时显示当前时间和日历。两个按键的功能:A键用于调时,围023,0为 24点,每按一次时加1;B键用于调分,围059,0为60分,每按一次分加1。 单片机程序设计、调试。本课题采用单片机部定时器,用软件对其进行秒、分、时的计数,单片机无法产生1s的定时时间,但是可以用硬件定时和软件计数相结合的方法实现,采用中断方式,即通过中断服务程序进行计数器溢出次数的累计,把定时器/计数器设定为62.5ms,计数溢出16次就可以得到1s,计60次为1分,60分计60次则为1小时,然后通过数码管动态刷新显示出来,再设四个按键进行时间的调整,一个键用作启动/调整键,其余三个分别用于时、分、秒的调整。通过理论设计和实物制作解决相应的实际问题,巩固和运用在单片机C语言应用程序技术中所学的理论知识和实验技能,掌握单片机应用系统的一般设计方法,提高设计能力和实践动手能力,为以后从事电子电路设计、研发电子产品打下良好的基础。2 数字电子钟硬件系统的设计2.1 硬件总体设计硬件系统总体设计如图2.1所示。图2.1 硬件系统总体设计2.2 数字电子钟硬件系统主要模块功能简要介绍(1) 功能芯片:本次设计采用AT89C51芯片,低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。256字节RAM, 32 位I/O 口线,与工业80C51 产品指令和引脚完全兼容。价格较低,能满足本次设计的要求。(2) 电源和复位模块:AT89C51需5V电压,所以可以采用USB接口的5V电源对其供电,复位电路可采用上电复位、按键电平复位、按键脉冲复位3种,本次采用按键电平复位。如电路原理图中的电源和复位模块。(3) 显示模块:该模块由8位8段共阳极数码管组成,由8个PNP型三极管分别驱动其发光,从左至右位控分别接于单片机的P2.7-P2.0中上,段控a-dP接于单片机的P0.0-P0.7口上,使用动态显示从右向左循环点亮每一位数码管。如电路原理图中的数码管电路。(4) 键盘模块:键盘由8个独立式按键组成,S0-S7键分别接在单片机的P1.0-P1.7口,并由上拉电阻上拉使其成为电位为高。如电路原理图中的独立键盘模块。(5) 时钟模块:为了保证同步工作方式的思想,单片机必须有时钟信号,以使其系统在时钟信号的控制下按时序协调工作。如电路原理图中的晶振电路。2.3 数字电子钟电路原理图、PCB图、元器件布局图2.31数字电子钟电路原理图2.4 数字电子钟元器件清单元器件名称规格数量STC11F02 1DS1302 1晶振12MHz 2数码管 874HC5951三极管 90129蜂鸣器1小按键4下载口座子十芯118b20温度传感器1六脚开关1USB电源线加接口1电阻 2001电阻4.7K1电阻1K3电阻 47024电解电容220F1瓷片电容33pF2排阻10K2短路帽3杜邦线8p1PCB板子1底座3数字电子钟元器件清单3 数字电子钟软件系统的设计3.1 数字电子钟软件系统主要模块功能简要介绍(1) 主程序:主程序的主要功能是进行定时器/计数器,显示缓冲区的初始化,显示,以与判断是否有功能键按下,判断按下的键并调相应的键功能程序。(2) 键功能程序:键功能程序的主要功能是执行对应的功能,Menu键为启动/调整键,第一次按下则由待机状态进入运行状态启动时钟,从00-00-00开始显示,然后按下为奇数则暂停,进入调时状态,按下Sec键则秒加1,按下Min键则分加1,按下Hour键则时加1;若按下为偶数则进入时钟运行状态。(3) 中断服务程序:中断服务程序的主要功能是进行计时操作,程序开始先判断计数溢出是否满了16次,若不满16次则表明没有达到最小计时单位秒,则中断返回;若满16次表明已达到最小计时单位秒,则程序断续向下执行,进行分和时的计时。(4) 显示子程序:显示程序的主要功能是将显示缓冲区的段控码正确的显示在数码管上,采用动态显示,从右向左循环点亮每一位数码管。(5) 键扫子程序:键扫子程序的主要功能是判断是否有键按下,是哪个键按下,并将键值保存在20H中。3.2 数字电子钟软件系统程序流程框图图3.1 计时1秒子程序流程框图 图3.2 显示子程序流程框图3.3 数字电子钟软件系统程序清单/#include<reg52.h>#include<stc89.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit sck=P10; /移位时钟信号输入端 sbit rck=P12; /锁存信号输入端sbit da=P11; /数据信号输入端uchar code tab=0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff;uchar code table=0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xbf;sbit DS1302_CLK=P35;sbit DS1302_IO=P36;sbit DS1302_RST=P37;sbit s1=P13;sbit s2=P14;sbit s3=P15;uchar second,minute,hour,num;/#/名称:wr595()向595 发送一个字节的数据/功能:向595 发送一个字节的数据(先发低位)/#void wr595(uchar wrdat)uchar i;sck=rck=0;for(i=8;i>0;i-)/循环八次,写一个字节da=wrdat&0x80; /发送BIT0 位sck=1;_nop_();sck=0;wrdat<<=1; /要发送的数据右移,准备发送下一位/*-并行数据输出-*/*void wrr595(void)sck1=sck2 = 1; /先将存储寄存器引脚置为低 _nop_();sck1=sck2 =0; /再置为高,产生移位时钟上升沿,上升沿时移位寄存器的数据进入数据存储寄存器,更新显示数据。*/void delayms(uint xms) uint i,j; for(i=xms;i>0;i-) for(j=110;j>0;j-);/*void wr5951(uchar wrdat)uchar i;for(i=8;i>0;i-)/循环八次,写一个字节lck1=lck2=0;da=wrdat&0x80; /发送BIT0 位wrdat<<=1; /要发送的数据右移,准备发送下一位lck1=lck2=1; */DS1302程序/void writeshuju(uchar byte1) /写字节 uchar i; for(i=8;i>0;i-) DS1302_IO=(bit)(byte1&0x01); DS1302_CLK=1; _nop_(); DS1302_CLK=0; byte1>>=1; uchar readshuju() uchar i,ucdat=0; for(i=8;i>0;i-) DS1302_IO=1; ucdat>>=1; if(DS1302_IO)ucdat|=0x80; DS1302_CLK=1; _nop_(); DS1302_CLK=0; return(ucdat);void write_ds1302(uchar addr,uchar dat) /给DS1302写指令 DS1302_RST=0; _nop_(); DS1302_CLK=0; _nop_(); DS1302_RST=1; writeshuju(addr); _nop_(); writeshuju(dat); DS1302_CLK=1; _nop_(); DS1302_RST=0;uchar read_ds1302(uchar addr) uchar time; DS1302_RST=0; _nop_(); DS1302_CLK=0; _nop_(); DS1302_RST=1; writeshuju(addr); time=readshuju(); DS1302_CLK=1; _nop_(); DS1302_RST=0; return(time);void chushi_ds1302() write_ds1302(0x84,0x12); /时 write_ds1302(0x82,0x00); /分 write_ds1302(0x80,0x00); /秒 write_ds1302(0x8e,0x80); / wp为1关闭写操作保存写的数据 void read_time() /读时间 second=read_ds1302(0x81); second=(second/16)*10+second%16); minute=read_ds1302(0x83); minute=(minute/16)*10+minute%16); hour=read_ds1302(0x85); hour=(hour/16)*10+hour%16);void display() /时间显示 uchar hour0,hour1,minute0,minute1,second0,second1; hour0=hour/10; hour1=hour%10; minute0=minute/10; minute1=minute%10; second0=second/10; second1=second%10; wr595(table0); wr595(tabhour0); rck=1; delayms(1); rck=0; wr595(table1); wr595(tabhour1); rck=1; delayms(1); rck=0; wr595(table2); wr595(table8); rck=1; delayms(1); rck=0; wr595(table3); wr595(tabminute0); rck=1; delayms(1); rck=0; wr595(table4); wr595(tabminute1); rck=1; delayms(1); rck=0; P0=0; wr595(table5); wr595(table8); rck=1; delayms(1); rck=0; wr595(table6); wr595(tabsecond0); rck=1; delayms(1); rck=0; wr595(table7); wr595(tabsecond1); rck=1; delayms(1); rck=0;void jiajia() /加加键if(s2=0)delayms(5);if(s2=0) while(s2=0) display(); if(num=1) hour+; if(hour=24) hour=0; write_ds1302(0x8e,0x00); /调时 write_ds1302(0x84,(hour/10)<<4|hour%10); write_ds1302(0x8e,0x80); if(num=2) minute+; if(minute=60) minute=0; write_ds1302(0x8e,0x00); /调分 write_ds1302(0x82,(minute/10)<<4|minute%10); write_ds1302(0x8e,0x80); if(num=3) second+; if(second=60) second=0; write_ds1302(0x8e,0x00); /调秒 write_ds1302(0x80,second); write_ds1302(0x8e,0x80); void jianjian()if(s3=0) delayms(5);if(s3=0) while(!s3)display();if(num=1) hour-; if(hour=-1) hour=23; write_ds1302(0x8e,0x00); /调时 write_ds1302(0x84,(hour/10)<<4|hour%10); write_ds1302(0x8e,0x80);if(num=2) minute-; if(minute=-1) minute=59; write_ds1302(0x8e,0x00); /调分 write_ds1302(0x82,(minute/10)<<4|minute%10); write_ds1302(0x8e,0x80);if(num=3) second-; if(second=-1) second=59; write_ds1302(0x8e,0x00); /调秒 write_ds1302(0x80,(second/10)<<4|second%10); write_ds1302(0x8e,0x80); void sheding()/设定键 if(s1=0) delayms(5); if(s1=0) while(!s1) display(); num+; if(num=4) num=0; /*void key() uchar i; if(s1=0) delayms(5); if(s1=0) while(!s1)display(); num+; while(num=1) for(i=0;i<30;i+) wr595(table0); wr595(tabhour/10); rck=1; delayms(1); rck=0; sheding(); wr595(table1); wr595(tabhour%10); rck=1; delayms(1); rck=0; wr595(table2); wr595(table8); rck=1; delayms(1); rck=0; wr595(table3); wr595(tabminute/10); rck=1; delayms(1); rck=0; jiajia(); wr595(table4); wr595(tabminute%10); rck=1; delayms(1); rck=0; wr595(table5); wr595(table8); rck=1; delayms(1); rck=0; wr595(table6); wr595(tabsecond/10); rck=1; delayms(1); rck=0; jianjian(); wr595(table7); wr595(tabsecond%10); rck=1; delayms(1); rck=0; for(i=0;i<30;i+) wr595(table0); wr595(tab10); rck=1; delayms(1); rck=0; wr595(table1); wr595(tab10); rck=1; delayms(1); rck=0; sheding(); wr595(table2); wr595(table8); rck=1; delayms(1); rck=0; wr595(table3); wr595(tabminute/10); rck=1; delayms(1); rck=0; wr595(table4); wr595(tabminute%10); rck=1; delayms(1); rck=0; wr595(table5); wr595(table8); rck=1; delayms(1); rck=0; jiajia(); wr595(table6); wr595(tabsecond/10); rck=1; delayms(1); rck=0; wr595(table7); wr595(tabsecond%10); rck=1; delayms(1); rck=0; jianjian(); /* while(num=2) for(i=0;i<30;i+) wr595(table0); wr595(tabhour/10); rck=1; delayms(1); rck=0; wr595(table1); wr595(tabhour%10); rck=1; delayms(1); rck=0; sheding(); wr595(table2); wr595(table8); rck=1; delayms(1); rck=0; wr595(table3); wr595(tabminute/10); rck=1; delayms(1); rck=0; wr595(table4); wr595(tabminute%10); rck=1; delayms(1); rck=0; jiajia(); wr595(table5); wr595(table8); rck=1; delayms(1); rck=0; wr595(table6); wr595(tabsecond/10); rck=1; delayms(1); rck=0; wr595(table7); wr595(tabsecond%10); rck=1; delayms(1); rck=0; jianjian(); for(i=0;i<30;i+) wr595(table0); wr595(tabhour/10); rck=1; delayms(1); rck=0; wr595(table1); wr595(tabhour%10); rck=1; delayms(1); rck=0; sheding(); wr595(table2); wr595(table8); rck=1; delayms(1); rck=0; wr595(table3); wr595(tab10); rck=1; delayms(1); rck=0; jiajia(); wr595(table4); wr595(tab10); rck=1; delayms(1); rck=0; wr595(table5); wr595(table8); rck=1; delayms(1); rck=0; wr595(table6); wr595(tabsecond/10); rck=1; delayms(1); rck=0; wr595(table7); wr595(tabsecond%10); rck=1; delayms(1); rck=0; jianjian(); /* while(num=3) for(i=0;i<30;i+) wr595(table0); wr595(tabhour/10); rck=1; delayms(1); rck=0; wr595(table1); wr595(tabhour%10); rck=1; delayms(1); rck=0; sheding(); wr595(table2); wr595(table8); rck=1; delayms(1); rck=0; wr595(table3); wr595(tabminute/10); rck=1; delayms(1); rck=0; wr595(table4); wr595(tabminute%10); rck=1; delayms(1); rck=0; jiajia(); wr595(table5); wr595(table8); rck=1; delayms(1); rck=0; wr595(table6); wr595(tabsecond/10); rck=1; delayms(1); rck=0; wr595(table7); wr595(tabsecond%10); rck=1; delayms(1); rck=0; jianjian(); for(i=0;i<30;i+) wr595(table0); wr595(tabhour/10); rck=1; delayms(1); rck=0; sheding(); wr595(table1); wr595(tabhour%10); rck=1; delayms(1); rck=0; wr595(table2); wr595(table8); rck=1; delayms(1); rck=0; wr595(table3); wr595(tabminute/10); rck=1; delayms(1); rck=0; wr595(table4); wr595(tabminute%10); rck=1; delayms(1); rck=0; jiajia(); wr595(table5); wr595(table8); rck=1; delayms(1); rck=0; wr595(table6); wr595(tab10); rck=1; delayms(1); rck=0; wr595(table7); wr595(tab10); rck=1; delayms(1); rck=0; jianjian(); write_ds1302(0x8e,0x00); write_ds1302(0x80,(second/10)<<4|second%10); write_ds1302(0x8e,0x80); /#/主函数/#void main(void) chushi_ds1302(); while(1) read_time(); display(); key();4 设计结论、仿真结果、误差分析4.1 数字电子钟的仿真结果本次设计的数字电子钟有三种状态:开始状态,时钟运行状态,时钟调整状态。它们分别如图4.1、图4.2、图4.3所示。图4.1 开始状态仿真结果图4.2时钟运行状态仿真结果图4.3 时钟调整状态仿真结果4.2 数字电子钟的误差分析虽说采用软件方式来产生1s的基本时间,然而定时器/计数器本身不能产生标准的1s定时,产生一个标准时间之后进行循环计数得到1s,但CPU执行代码需要1-2s的时间,因此产生的1s,1分,1小时,都会略大于标准的时间。此外,单片机也易受外界环境的影响,比如温度、湿度等干扰。故应该让单片机工作在适宜的环境下,同时采用实时时钟芯片,这样能将误差降低到最小。4.3 设计重点、难点,体会与不足之处重点:单片课程设计考察的是一个人理论与实践相结合的能力,要求设计者具有一定的理论知识与动手操作能力。比如用Proteus软件进行单片机系统电路的仿真设计、Protel软件的使用、PCB板的硬件制作,Keil软件编写和调试汇编程序。难点:硬件电路的故障检测和修复,原理电路图的仿真设计,汇编程序的编写和调试。体会:现在来回想单片机的课程设计,有许多感触,从最开始接触单片机和C语言,到现在能独立完成一个课程设计,我必须得感王老师的谆谆教导和辛勤付出,是老师给了我动力。在本学期初期做PCB板时因布局的不科学导致最后的制作使用出现了许多麻烦,还有焊接的经验不足导致了虚焊;在汇编编程时,书本上的很多知识又学的很不扎实,程序基本语句理解不够透彻,导致编一个简单程序都需要大量时间且过于复杂,真是耗时耗力耗单片机存。不足之处:数字电子钟的设计由于采用的是用硬件定时和软件计数的方式产生的1s,而忽略了CPU执行指令所需的时间,故时钟显示不是很精确。参考文献1 单片机的C语言应用程序设计华中科技大学C language program of single chip design. The central China university of science and technology press2 单片机基础航空航天大学SCM basis. Beijing aerospace university press3 模拟电子技术高等教育Analog electronic technology. Higher education press4 电路分析基础清华大学Circuit analysis. Tsinghua university press致 本次单片机的C语言应用程序课程设计能够顺利的完成,是小组各组员团结努力和廖代文老师的指导下完成的。