51单片机实验报告.docx
《51单片机实验报告.docx》由会员分享,可在线阅读,更多相关《51单片机实验报告.docx(12页珍藏版)》请在冰豆网上搜索。
![51单片机实验报告.docx](https://file1.bdocx.com/fileroot1/2023-5/15/e744d233-3a7e-4209-a3b6-54b4a3caec72/e744d233-3a7e-4209-a3b6-54b4a3caec721.gif)
51单片机实验报告
51单片机实验报告
姓名:
刘贤莺 班级:
电信硕91 学号:
日期:
20XX年4月19日
目录
1实验要求..............................................................................................32硬件环境与工作原理...........................................................................4硬件环境........................................................................................4工作原理........................................................................................63资源使用..............................................................................................9 RAM的使用情况.........................................................................9 系统堆栈使用情况......................................................................10 寄存器使用情况..........................................................................11 定时器/计数器使用情况.............................................................114程序原理与框图.................................................................................12 主函数..........................................................................................12 主函数框图.............................................................................12
主函数代码...........................................................................12 主时钟设置模块..........................................................................22 闹钟功能模块..............................................................................24 倒计时模块..................................................................................27 秒表模块......................................................................................32 日期滚动模块...............................................................................34 日期设置模块...............................................................................38 串口控制模块...............................................................................42 键盘扫描读取子程序...................................................................48 蜂鸣器控制子程序.....................................................................51 LED扫描显示子程序.................................................................565操作说明............................................................................................606调试与实际运行结果........................................................................637总结与体会........................................................................................63
1实验要求
在实验板上编程实现20XX年日历和实时时钟:
1.时-分-秒显示
可通过键盘置入时间值(参照电子表设置时间工作模式)。
2.可通过按键控制在LED上从右向左滚动显示年_月_日3次,如:
20XX_01_20空空20XX_01_20
3.实现每日闹铃提醒功能,闹铃时间可用按键设置。
闹铃采用提示音表示。
4.实现秒表功能。
5.实现定时器功能。
选通信号产生电路图:
图
数码管位选择原理:
1.输出位选信号指令:
MOVA,#SELECT;SELECT为位选信号对应的数值 MOVDPTR,#8000H MOV@DPTR,A2.电路实现原理:
在指令“MOVDPTR,#8000H”中,8000H代表外部存
储器的地址,对应于A15=1,Ai=0(i=0~14)。
图可知,此时74138译码器有效,A=B=C=0,得:
AJ00=0,AJ0i=1
。
有于执行指令“MOV@DPTR,A”时,/WR=0,因此,图可知74HC573有效,它将D0~D7信号保持并输入ULN2803,信号经过放大后,作为位选信号驱动8位数码管。
数码管段选择原理:
1.输出段选信号指令:
MOVA,#SELECT ;SELECT为段选信号对应的数值 MOVDPTR,#9000H MOV@DPTR,A2.电路实现原理:
在指令“MOVDPTR,#9000H”中,9000H代表外部存储器的地址,
对应于A15=1,A12=1,Ai=0(i=0~11,13,14)。
图可知,此时74138译码器有效,A=C=0,B=1,得:
AJ01=0,AJ0i=1。
有于执行指令“MOV@DPTR,A”时,/WR=0,因此,图可知74HC573有效,它将D0~D7信号保持并作为位选信号输入8位数码管。
4x4键盘控制原理:
图可知,AJ00=0时,可通过P00~P03向键盘发出扫描信号
或读取键盘信号。
具体原理见后续代码。
3.资源使用
RAM的使用情况
ALARMEQU;闹钟设置标志
TIME_UPEQU;倒计时时间到标志SOUND_ONEQU;声音开关标志UART_ENEQU;处于串口通信状态标志IS_HOSTEQUHOUR_TP
;是否作为串口通信的主机标志
EQU2AH
MIN_TPEQU2BHSEC_TPEQU2CHMUSIC_SELECTEQU2DH
TIME_BUFEQU2EH;30~35H连续存放led显示数据HOUREQU36H;小时MINEQU37HSECEQU38H
;分钟;秒
COUNTEQU39H;每加1HOUR_ALARMEQU3AHMIN_ALARMEQU3BHSEC_ALARMEQU4BH
SEC_OLDEQU3CH;存放旧的秒数HOUR_DOWNEQU3DH
MIN_DOWNEQU3EH;倒数时分钟数SEC_DOWNEQU3FH;倒数时间秒钟数VAR_HOUREQU40HVAR_MINEQU41H
VAR_SECEQU42H
MSEQU43H;作用同SEC_OLDYEAR0EQU44HYEAR1EQU45HMONTHEQU46HDAYEQU47HMUSIC1EQU48HMUSIC2EQU49HMUSIC3EQU4AH
DATE_BUFEQU60H;以下连续12字节为日期显示数据
系统堆栈使用情况
主程序将SP设置为50H,在50H到60H之间的16字节为堆栈区,于此工程设计的函数调用层次最多不超过3层且参数主要通过内存变量传递,因此,不会出现堆栈溢出的情况。
此处,更好的方案应该是把DATE_BUF前移并把堆栈放在
DATE_BUF之后。
但是,实际操作时发现如果堆栈区包含62H以后的区域,就会出现一个严重的bug,于这个bug一直没法解释和解决,我只好采用了现在这个方案。
寄存器使用情况:
1.累加器A
2.寄存器B
3.00区的R0~R7寄存器,01~03区的寄存器不曾使用。
定时器/计数器使用情况
整个工程用到了定时器T0和T1。
其中T0用于主时钟的计时,优先级最高,不可被软中断中断。
且不可被软中断屏蔽。
T1用于控制播放音乐时音调的频率和控制串口通信时的波特率。
4程序原理与框图
主函数
主函数框图T0中断服务:
主函数代码:
;*************************************主函数***********************************************;;***刘贤莺;***日期:
20XX/2/26NAMEMAIN_FUNC
EXTRNCODE(GET_KEY,BEEP,SET_DOWN_TIMER,CONVERT,DISP,SET_TIME,SET_ALARM_TIME)EXTRN
(COUNTER,DATE_ROLLER,MUSIC,INT_T1,UART_INT,UART_HOST,UART_SLAVE,SET_DATE)ALARMEQU;闹钟设置标志TIME_UPEQU;倒计时时间到标志SOUND_ONEQU;声音开关标志UART_ENEQU;处于串口通信状态标志IS_HOSTEQU;是否作为串口通信的主机标志HOUR_TPEQU2AHMIN_TPEQU2BHSEC_TPEQU2CHMUSIC_SELECTEQU2DH
TIME_BUFEQU2EH;30~35H连续存放led显示数据HOUREQU36H;小时MINEQU37H;分钟SECEQU38H;秒
COUNTEQU39H;每加1HOUR_ALARMEQU3AH
CODE
MIN_ALARMEQU3BHSEC_ALARMEQU4BH
SEC_OLDEQU3CH;存放旧的秒数HOUR_DOWNEQU3DHMIN_DOWNEQU3EHSEC_DOWNEQU3FHVAR_HOUREQU40HVAR_MINEQU41HVAR_SECEQU42H
MSEQU43H;作用同SEC_OLDYEAR0EQU44HYEAR1EQU45HMONTHEQU46HDAYEQU47HMUSIC1EQU48HMUSIC2EQU49HMUSIC3EQU4AH
DATE_BUFEQU60H;以下连续12字节为日期显示数据;蜂鸣器引脚定义BUZZEREQUPROGSEGMENTCODECSEGAT0ORG0HJMPMAINORG0BHJMPINT_T0ORG001BH
JMPINT_T1;跳转至T1中断服务程序ORG23HJMPUART_INTCSEGAT0050HRSEGPROG;主程序;MAIN:
MOVSP,#50H
LCALLINIT;初始化变量LCALLINIT_TIMER;设置定时器LCALLINIT_SHOW
;倒数时分钟数;倒数时间秒钟数
;无穷循环LOOP:
MOVVAR_HOUR,HOURMOVVAR_MIN,MINMOVVAR_SEC,SEC
LCALLCONVERT;先传递参数再调用
;
LCALLTIME_TEST;检查闹钟时间LCALLDISPLCALLGET_KEYMOVA,#15
CJNEA,#9,LOOP_TO_10LCALLBEEPLCALLSET_TIMELJMPLOOP
CJNEA,#10,LOOP_TO_11LCALLBEEP
LCALLSET_ALARM_TIMEJMPLOOP
CJNEA,#11,LOOP_TO_12LCALLBEEP
LCALLSET_DOWN_TIMER;设置倒计时间JMPLOOP
CJNEA,#12,LOOP_TO_13LCALLBEEPLCALLCOUNTERJMPLOOP
CJNEA,#13,LOOP_TO_14LCALLBEEP
LCALLDATE_ROLLERLJMPLOOP
CJNEA,#14,LOOP_TO_2LCALLSET_DATELJMPLOOP
CJNEA,#2,LOOP_TO_15JBALARM,ALARM_OFFLCALLBEEPLCALLBEEPSETBALARMJMPLOOPLCALLBEEPCLRALARMLJMPLOOP
LOOP_TO_10:
LOOP_TO_11:
LOOP_TO_12:
LOOP_TO_13:
LOOP_TO_14:
LOOP_TO_2:
ALARM_OFF:
NO_KEY:
LJMPLOOP
CJNEA,#1,NO_KEYJNBSOUND_ON,L1CLRSOUND_ONLJMPL11LCALLBEEP
LOOP_TO_1:
L1:
SETBSOUND_ONL11:
LJMPLOOPLOOP_TO_15:
CJNEA,#15,LOOP_TO_16LCALLBEEPLCALLUART_HOSTLJMPLOOP
CJNEA,#16,LOOP_TO_1LCALLBEEPLCALLUART_SLAVELJMPLOOP
LOOP_TO_16:
;;;检查是否启动闹钟TIME_TEST:
JBALARM,TI3RET
;检查闹钟时间是否到了TI3:
MOVA,HOUR
MOVB,HOUR_ALARMCJNEA,B,BKMOVA,MIN
MOVB,MIN_ALARMCJNEA,B,BK
LCALLTIME_OUT;闹钟时间到了,开始提示RET
MOVR0,#1;#256;MOVSEC_OLD,#100
MOVMUSIC_SELECT,#1;选择第一首歌曲LCALLMUSIC;LCALLGET_KEY
;CJNEA,#4,AL1;响铃次数没到,但是用户按K4停止闹钟
BK:
TIME_OUT:
ALARMING:
;LJMPAL2
;响铃的次数到了就停
;AL1:
DJNZR0,ALARMING;AL2:
;;;
;;;显示时钟初始值000000INIT_SHOW:
;;;
;;;中断服务程序INT_T0:
PUSHPSWPUSHACC
CLREA ;关中断CLRTR0
MOVDPTR,#8000HMOVA,#BMOVX@DPTR,AMOVDPTR,#9000HMOVA,#BMOVX@DPTR,ARETRET
CLRALARM
MOVA,#7;加上执行到SETTR0处需要的时间ADDA,TL0MOVTL0,AMOVA,#0DCHADDCA,TH0MOVTH0,ASETBTR0
INCCOUNT;秒输出MOVA,COUNT
CJNEA,#100,TT1;是否一秒到了MOVCOUNT,#0INCSECMOVA,SECCJNEA,#60,TT1;分输出INCMINMOVSEC,#0MOVA,MINCJNEA,#60,TT1
;是否一小时到了;是否一分钟到了
;时输出INCHOURMOVMIN,#0MOVA,HOURCJNEA,#24,TT1MOVSEC,#0MOVMIN,#0MOVHOUR,#0
MOVA,MONTHCJNEA,#2,NOT_2MOVA,YEAR1CJNEA,#0,NOT_100MOVA,YEAR0MOVB,#4DIVABMOVA,BCJNEA,#0,NOT_2MOVR0,#28LJMPDAY_TESTMOVA,YEAR1MOVB,#4DIVABMOVA,BCJNEA,#0,NOT_2MOVR0,#29LJMPNO1
MOVDPTR,#(MONTHS-1)MOVA,MONTHMOVC+DPTRMOVR0,ALJMPDAY_TEST
;如果放在最后会出现OUTOFRANGE错误!
POPACCPOPPSW
SETBEA;开中断RETIINCDAYMOVA,DAYINCR0
NOT_100:
NOT_2:
NO1:
TT1:
DAY_TEST:
MOVB,R0CJNEA,B,TT1MOVDAY,#1INCMONTHMOVA,MONTHCJNEA,#13,TT1MOVMONTH,#1INCYEAR1MOVA,YEAR1CJNEA,#100,TT1MOVYEAR1,#0INCYEAR0MOVA,YEAR0CJNEA,#100,TT1MOVYEAR0,#0JMPTT1
;;;使用定时器T0模式0计时INIT_TIMER:
;;;
;;;初始化:
计时单元清零INIT:
CLRALARM;关闭闹钟功能MOVCOUNT,#0MOVSEC,#0MOVMIN,#0MOVHOUR,#0
MOVHOUR_ALARM,#0MOVMIN_ALARM,#0MOVSEC_ALARM,#0
MOVSEC_OLD,#0;保存的秒值以便对比判断是否过了一秒MOVHOUR_DOWN,#0MOVMIN_DOWN,#0MOVSEC_DOWN,#0
MOVTIME_BUF+2,#B;显示时分秒之间的分隔符MOVTIME_BUF+5,#B;显示时分秒之间的分隔符MOVYEAR0,#20MOVYEAR1,#12MOVTMOD,#01HMOVIE,#BMOVTL0,#00HMOVTH0,#0DCHSETBTR0;启动定时器T0RET
;;;
//平年的每月天数表MONTHS:
END
DB31D,28D,31D,30D,31D,30D,31D,31D,30D,31D,30D,31D
MOVMONTH,#2MOVDAY,#14
SETBSOUND_ON;开声音RET
主时钟设置模块:
主时钟设置模块代码:
;*********************************主时钟设置模块*******************************************;;***外部接口:
SET_TIME;*** 参数:
无;***日期:
20XX/2/20NAMESETTING_CLOCK
EXTRNCODE(DISP,GET_KEY,CONVERT,BEEP)PUBLICSET_TIME
SETTING_CLOCK_SEGSEGMENTCODERSEGSETTING_CLOCK_SEG
HOUR_TPEQU2AHMIN_TPEQU2BHSEC_TPEQU2CHHOUREQU36H;小时MINEQU37H;分钟SECEQU38H;秒VAR_HOUREQU40HVAR_MINEQU41HVAR_SECEQU42H;;;设置时间SET_TIME:
;CLRTR0;时间停止MOVHOUR_TP,HOURMOVMIN_TP,MINMOVSEC_TP,SECCJNEA,#0,TO_9LJMPNO_KEY
L0:
LCALLGET_KEY
TO_9:
CJNEA,#9,TO_13LCALLBEEP;SETBTR0RET
CJNEA,#13,TO_10CLRTR0
MOVHOUR,HOUR_TPMOVMIN,MIN_TPMOVSEC,SEC_TPLCALLBEEPSETBTR0RET
CJNEA,#10,TO_14INCHOUR_TPMOVA,HOUR_TP
CJNEA,#24,SHOW_SET_TIMEMOVHOUR_TP,#0LCALLBEEP
MOVVAR_HOUR,HOUR_TPMOVVAR_MIN,MIN_TPMOVVAR_SEC,SEC_TPLCALLCONVERTLCALLDISPJMPL0
CJNEA,#14,TO_11DECHOUR_TPMOVA,HOUR_TP
CJNEA,#-1,SHOW_SET_TIMEMOVHOUR_TP,#23JMPSHOW_SET_TIMECJNEA,#11,TO_15INCMIN_TPMOV