单片机实习总结报告 本文简介:专业综合实习总结2010-2011(2)专业班级:电子信息工程0801学生学号:0414080123学生姓名:吴锦指导教师:张云、包长春、马崇霄、杜殿会实习时间:2011.6.20—2011.7.15机电工程学院一、实习目的和意义1、实习目的:(1)利用单片机小系统实习板,掌握电路原理图;(2)通过
单片机实习总结报告 本文内容:
专业综合实习总结
2010-2011(2)
专业班级:
电子信息工程0801
学生学号:
0414080123
学生姓名:
吴锦
指导教师:张云、包长春、马崇霄、杜殿会
实习时间:2011.6.20—2011.7.15
机
电
工
程
学
院
一、实习目的和意义
1、实习目的:
(1)利用单片机小系统实习板,掌握电路原理图;
(2)通过对系统板的测试,了解系统板的工作原理及性能,掌握元器件及系统故障的排除方法;
(3)通过单片机系统的调试、程序编制及运行,掌握单片机系统的工作原理、开发方法和操作方法。
2、实习意义:
通过本实习不但可以掌握单片机软、硬件的综合调试方法,而且可以熟练掌握电路原理图,激发对单片机智能性的探索精神,提高学生的综合素质,培养学生应用单片机实现对工业控制系统的设计、开发与调试的能力。在制作学习过程中,不但可以掌握软、硬件的综合调试方法,而且可以使学生对单片机智能性产生强烈的欲望。达到最大限度地掌握微机应用技术,软件及接口设计和数据采集与处理的技能,培养电综合实践素质的目的。
二、实习内容
1.熟悉“单片机课程实习”电路板,领会、掌握该电路板的设计原理及硬件布局。
2.掌握单片机技术应用平台keil软件的学习。
3.借助平台软件,学习开发板的使用,按照要求编制、调试出正确的汇编语言程序。
4.学习适合本开发平台软件STC-ISP的在线单片机烧录。
5.针对实习电路板的功能,编制、调试、编译汇编语言程序,下载烧录并在实验板上运行,或利用软件ISIS
7
Professional进行软件仿真。
实现的功能:
1.led显示模块:单向循环流水led显示、双向循环流水led显示、花样流水灯的显示,使用查表方法编制任意点亮历程的实现,使用软件延时;
2.数码管显示模块:一位静态数码管显示0到9和0到F、二位静态数码管显示0到99、三位静态数码管显示0到999、四位静态数码管显示0到9999;阴极和阳极四位动态数码管显示;74LS驱动4位静态数码管显示;利用74HC595四位静态数码管显示;使用串行静态显示和动态扫描显示两种方式;
3.键盘模块:利用4×4矩阵键盘按键对应置数显示“0~F”;使用键盘的行列扫描方式;
三、硬件介绍
(一)LED显示模块:
图1
流水灯显示
图2
键盘控制循环灯
(二)数码管显示模块:
图3
1位静态数码管显示
图4
4位静态数码管显示
图5
4位动态数码管显示
图6
独立键盘加减清零数码管显示
图7
4位74LS驱动静态数码管显示
图8
4位74HC595静态显示
图9
0到F矩阵键盘
四、软件程序流程图
1、流水灯循环左移右移程序框图:
结束
A循环右移,并在P1口输出
调用延时程序
判别A与01H是否相等
开始
运行主程序
给P1口赋初值80H
A循环左移,并在P1口输出
调用延时程序
判别A与80H是否相等
否
是
是
否
2、0到F一位静态显示程序框图:
开始
1.建0—F的字形码表
2.用累加器A控制P0口并传递参数
3.R0记录目前显示的字型码
R0=0
A=R0
查字型码表,显示0
延时
INC
R0
R0=16?
继续查表,显示下一个字型
延时
否
是
3、0到9一位静态显示程序框图:
开始
(P0)=0
A=P0
查字型码表,取得段驱动码
取得
段驱动码送P0口口
延时
(R0)+1
R0=10?
R0=0
N
Y
4、动态数码显示程序框图:
显示完
置使能位处值
返回
开始
P0口,P2口初始化
置相应的使能位
查表显示
延时
N
Y
5、4×4矩阵矩阵键盘数码显示程序框图:
主程序图:
开始
扫描
是否有键按下
Y
识别是哪一个键按下
通过P0口查询显示该序号
N
Y
判别是否有键按下程序:
开始
P1=FFH,P1.0=0
有键按下吗?
延时去抖动
真的有键按下?
根据当前状态识别按键
P1=FFH,P1.1=0
有键按下吗?
延时10ms
真的有键按下吗?
根据当前状态识别按键
P1=FFH,P1.2=0
有键按下吗?
延时10ms
真的有键按下?
根据当前状态识别按键
有键按下吗?
P1=FFH,P1.3=0
延时10ms
真的有键按下吗?
根据当前状态识别按键
五、
实习的心得体会
回顾起此次课程设计,感觉受益匪浅,从拿到题目到完成整个编程,从理论到实践,学到很多很多的课堂理论中没学到过的东西,不仅对键盘的识别技术这一章节的知识点有了深刻的认识,而且对这学期开设的单片机这门课程有了更全面的了解,尤其是在学习使用proteus软件片编程和仿真时收获良多。通过这次单片机课程设计,还使我懂得了实践的重要性。同时在程序调试的过程中提高自己的发现问题、解决问题、实际动手和独立思考的能力。
本次单片机实习我们一共完成了三个模块的程序设计,包括:led显示模块、数码管显示模块和键盘模块。分别实现了流水灯的循环点亮控制、数码管的静态和动态计数显示,还有矩阵键盘按键控制数码管显示的程序设计。然后我们分别用protues系统仿真软件对各个模块进行了模拟仿真,用keil软件编制了汇编语言程序,验证了我们所设计的程序。
当然,这其中也有很多问题,第一、不够细心比如由于粗心大意焊错了线,由于对课本理论的不熟悉导致编程出现错误。第二,是在学习态度上,这次课设是对我的学习态度的一次检验。对于这次单片机综合课程实习,我的第一大心得体会就是作为一名工程技术人员,要求具备的首要素质绝对应该是严谨。我们这次实习所遇到的多半问题多数都是由于我们不够严谨。第三,在做人上,我认识到,无论做什么事情,只要你足够坚强,有足够的毅力与决心,有足够的挑战困难的勇气,就没有什么办不到的。
通过这次单片机实习,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。
这次课程设计能顺利的完成,除了我们的努力外,当然也离不开指导老师申老师的辛勤指导,致使我在设计的过程中学到了很多实用性的知识。同时,对给过我帮助的所有同学和各位指导老师表示忠心的感谢!
附录:程序清单
P1口闪亮:ORG
0000H
LOOP:MOV
P1,#01H
ACALL
DELAY
MOV
P1,#00H
ACALL
DELAY
SJMP
LOOP
DELAY:MOV
R7,#250
DEL1:MOV
R6,#250
DJNZ
R6,$
DJNZ
R7,DEL1
RET
END
流水灯循环左移右移:
方法一:ORG
0000H
MOV
A,#01H
LOOP:
MOV
P1,A
MOV
R5,#10
LOOP1:ACALL
DELAY
DJNZ
R5,LOOP1
RL
A
JB
ACC.7,LOOP2
SJMP
LOOP
LOOP2:MOV
P1,A
MOV
R5,#10
LOOP3:ACALL
DELAY
DJNZ
R5,LOOP3
RR
A
JB
ACC.0,LOOP
SJMP
LOOP2
DELAY:MOV
R7,#250
DEL1:MOV
R6,#250
DJNZ
R6,$
DJNZ
R7,DEL1
RET
END
方法二:ORG
0000H
MOV
A,#80H
LOOP:RL
A
MOV
P1,A
ACALL
DELAY
CJNE
A,#80H,LOOP
LOOP1:RR
A
MOV
P1,A
ACALL
DELAY
CJNE
A,#01H,LOOP1
SJMP
LOOP
DELAY:MOV
R7,#0FFH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
方法三:ORG
0000H
MOV
A,#80H
MOV
R0,#08H
LOOP:RL
A
MOV
P1,A
ACALL
DELAY
DJNZ
R0,LOOP
MOV
R0,#07H
LOOP1:RR
A
MOV
P1,A
ACALL
DELAY
DJNZ
R0,LOOP1
MOV
R0,#07H
SJMP
LOOP
DELAY:MOV
R7,#0FFH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
方法四:ORG
0000H
MOV
A,#00H
SETB
CY
LOOP:RLC
A
JC
LOOP1
MOV
P1,A
ACALL
DELAY
SJMP
LOOP
LOOP1:RRC
A
JC
LOOP
MOV
P1,A
ACALL
DELAY
SJMP
LOOP1
DELAY:MOV
R7,#0FFH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
从中间向两边,再从两边向中间循环点亮:
ORG
0000H
STAR:MOV
R0,#00H
MOV
R1,#07
MOV
A,R0
MOV
DPTR,#TAB
LOOP:
MOVC
A,@A+DPTR
MOV
P1,A
MOV
R5,#10
LOOP1:ACALL
DEL
DJNZ
R5,LOOP1
INC
R0
MOV
A,R0
DJNZ
R1,LOOP
SJMP
STAR
DEL:MOV
R7,#200
DEL1:MOV
R6,#250
DJNZ
R6,$
DJNZ
R7,DEL1
RET
TAB:DB
18H,24H,42H,81H,42H,24H,18H
END
键盘控制流水灯循环点亮:
ORG
0000H
AJMP
MAIN
ORG
0003H
AJMP
ET
ORG
0030H
MAIN:MOV
SP,#60H
SETB
EA
SETB
IT0
SETB
EX0
CLR
C
MOV
A,#0FFH
MOV
P2,A
LCALL
DEL
LOOP:JNB
21H.1,L
;检测标志
RRC
A
;右移动
MOV
P2,A
AJMP
DEE
L:
RLC
A
;左移动
MOV
P2,A
DEE:
LCALL
DEL
AJMP
LOOP
ET:
CLR
EA
PUSH
ACC
PUSH
PSW
LCALL
DELAY
MOV
A,#0FFH
MOV
P1,A
NOP
NOP
MOV
A,P1
;读键值
ANL
A,#0F0H
CJNE
A,#0F0H,NEXT1
AJMP
NEXT
NEXT1:JB
ACC.5,NEXT2
CLR
21H.1
;按键后产生标志
AJMP
NEXT
NEXT2:JB
ACC.6,NEXT
SETB
21H.1
;按键后产生标志
NEXT:
SETB
EA
POP
PSW
POP
ACC
HHH:
RETI
DEL:MOV
R6,#250
DEL11:MOV
R5,#250
DJNZ
R5,$
DJNZ
R6,DEL11
RET
DELAY:MOV
R6,#10
DEL1:
MOV
R5,#200
DEL2:
DJNZ
R5,$
DJNZ
R6,DEL1
RET
END
花样流水灯:
ORG
0000H
START:MOV
R0,#00H
MOV
P1,#00H
LOOP:MOV
A,R0
ADD
A,#0CH
MOVC
A,@A+PC
CJNE
A,#01H,XSH
SJMP
START
XSH:MOV
P1,A
ACALL
DELAY
INC
R0
SJMP
LOOP
DB0FFH,00H,0FFH,00H,0FFH,00H,0FFH,00H,0FH,0F0H,0FH,0F0H,0FH,0F0H,0FH
DB0F0H,0FH,0F0H,0AAH,55H,0AAH,55H,0AAH,55H,0AAH,55H,0AAH,55H,81H,42H
DB24H,18H,24H,42H,81H,42H,24H,18H,24H,42H,81H,42H,24H,18H,24H,42H,81H
DB42H,24H,18H,24H,42H,81H,03H,06H,0CH,18H,30H,60H,0C0H,60H,30H,18H,0CH
DB06H,03H,06H,0CH,18H,30H,60H,0C0H,60H,30H,18H,0CH,06H,03H,01H
DELAY:MOV
R7,#0FFH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
1位静态数码显示:
ORG
0000H
MOV
R0,#0FFH
DISPLY:
INC
R0
CJNE
R0,#0AH,DISPLY1
MOV
R0,#0FFH
SJMP
DISPLY
DISPLY1:MOV
A,R0
ADD
A,#06H
MOVC
A,@A+PC
MOV
P0,A
ACALL
DELAY
SJMP
DISPLY
DTAB:DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
DB88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,7FH,0BFH
DELAY:MOV
R7,#0FFH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
2位静态数码显示:
ORG
0000H
MOV
R0,#0FFH
MOV
R1,#00H
DISPLY:
INC
R0
CJNE
R0,#0AH,DISPLY1
INC
R1
CJNE
R1,#0AH,DISPLY2
MOV
R0,#0FFH
MOV
R1,#00H
MOV
P0,#0FFH
AJMP
DISPLY
DISPLY2:MOV
A,R1
ADD
A,#10H
MOVC
A,@A+PC
MOV
P0,A
MOV
R0,#0FFH
AJMP
DISPLY
DISPLY1:MOV
A,R0
ADD
A,#06H
MOVC
A,@A+PC
MOV
P2,A
ACALL
DELAY
AJMP
DISPLY
DTAB:DB
0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
DB
88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,7FH,0BFH
DELAY:MOV
R7,#0FFH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
3位静态数码显示:
ORG
0000H
START:
MOV
R0,#0FFH
MOV
R1,#00H
MOV
R2,#00H
MOV
P3,#0FFH
MOV
P2,#0FFH
MOV
P0,#0FFH
DISPLY:
INC
R0
CJNE
R0,#0AH,DISPLY1
MOV
R0,#0FFH
INC
R1
CJNE
R1,#0AH,DISPLY2
MOV
R1,#00H
MOV
P2,#0C0H
INC
R2
CJNE
R2,#0AH,DISPLY3
SJMP
START
DISPLY3:MOV
A,R2
ADD
A,#16H
MOVC
A,@A+PC
MOV
P0,A
SJMP
DISPLY
DISPLY2:MOV
A,R1
ADD
A,#0EH
MOVC
A,@A+PC
MOV
P2,A
SJMP
DISPLY
DISPLY1:MOV
A,R0
ADD
A,#06H
MOVC
A,@A+PC
MOV
P3,A
ACALL
DELAY
SJMP
DISPLY
DTAB:DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
DB88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,7FH,0BFH
DELAY:
MOV
R7,#0FFH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
4位静态数码显示:
ORG
0000H
START:
MOV
R0,#0FFH
MOV
R1,#00H
MOV
R2,#00H
MOV
R3,#00H
MOV
P1,#0FFH
MOV
P3,#0FFH
MOV
P2,#0FFH
MOV
P0,#0FFH
DISPLY:
INC
R0
CJNE
R0,#0AH,DISPLY1
MOV
R0,#0FFH
INC
R1
CJNE
R1,#0AH,DISPLY2
MOV
R1,#00H
MOV
P3,#0C0H
INC
R2
CJNE
R2,#0AH,DISPLY3
MOV
R2,#00H
MOV
P2,#0C0H
INC
R3
CJNE
R3,#0AH,DISPLY4
SJMP
START
DISPLY4:MOV
A,R3
ADD
A,#1EH
MOVC
A,@A+PC
MOV
P0,A
SJMP
DISPLY
DISPLY3:MOV
A,R2
ADD
A,#16H
MOVC
A,@A+PC
MOV
P2,A
SJMP
DISPLY
DISPLY2:MOV
A,R1
ADD
A,#0EH
MOVC
A,@A+PC
MOV
P3,A
SJMP
DISPLY
DISPLY1:MOV
A,R0
ADD
A,#06H
MOVC
A,@A+PC
MOV
P1,A
ACALL
DELAY
SJMP
DISPLY
DTAB:DB
0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
DB
88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,7FH,0BFH
DELAY:
MOV
R7,#0AH
DELAY1:MOV
R6,#0FFH
DELAY2:MOV
R5,#03H
DELAY3:DJNZ
R5,DELAY3
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
74HC595四位稳定显示:
1)最大数为9999的计数器
ORG
0000H
AJMP
MAIN
ORG
000BH
AJMP
CRT0
ORG
0020H
MAIN:MOV
R1,#33H
MOV
R2,#04H
CLEAR:MOV
@R1,#33H
DEC
R1
DJNZ
R2,CLEAR
MOV
SP,#60H
MOV
TMOD,#01H
MOV
TH0,#3CH
MOV
TL0,#0B0H
SETB
EA
SETB
ET0
SETB
TR0
MOV
R7,#1
MOV
DPTR,#DTAB
LOOP:
MOV
R1,#33H
MOV
R2,#04H
MOV
R3,#08H
MOV
R4,#01H
LOOP1:MOV
A,R3
MOV
P2,A
RR
A
MOV
R3,A
MOV
A,@R1
CJNE
R4,#00H,MODE
XSH:
LCALL
DIS
LCALL
DEL
DEC
R1
DJNZ
R2,LOOP1
AJMP
LOOP
MODE:
CJNE
A,#00H,FH
MOV
R4,#01H
MOV
A,#0AH
SJMP
XSH
FH:
MOV
R4,#00H
SJMP
XSH
CRT0:
DJNZ
R7,RRR
MOV
R7,#1
INC
30H
MOV
R0,30H
CJNE
R0,#0AH,RRR
MOV
30H,#00H
INC
31H
MOV
R0,31H
CJNE
R0,#0AH,RRR
MOV
31H,#00H
INC
32H
MOV
R0,32H
CJNE
R0,#0AH,RRR
MOV
32H,#00H
INC
33H
MOV
R0,33H
CJNE
R0,#0AH,RRR
MOV
33H,#00H
RRR:
MOV
TH0,#3CH
MOV
TL0,#0B0H
RETI
DIS:
MOVC
A,@A+DPTR
MOV
P0,A
RET
DEL:
MOV
R6,#20
DEL1:
MOV
R5,#150
DEL2:
DJNZ
R5,$
DJNZ
R6,DEL1
RET
DTAB:DB
0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
DB
88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,7FH,0BFH
END
2)最高位为零时,最高位不显示
ORG
0000H
AJMP
MAIN
ORG
000BH
AJMP
CRT0
ORG
0020H
MAIN:
MOV
R1,#33H
MOV
R2,#04H
CLEAR:
MOV
@R1,#00H
DEC
R1
DJNZ
R2,CLEAR
MOV
SP,#60H
MOV
TMOD,#01H
MOV
TH0,#3CH
MOV
TL0,#0B0H
SETB
EA
SETB
ET0
SETB
TR0
MOV
R7,#1
MOV
DPTR,#DTAB
LOOP:
MOV
R1,#33H
MOV
R2,#04H
MOV
R3,#08H
LOOP1:
MOV
A,R3
MOV
P2,A
RR
A
MOV
R3,A
MOV
A,@R1
LCALL
DIS
LCALL
DEL
DEC
R1
DJNZ
R2,LOOP1
AJMP
LOOP
CRT0:
DJNZ
R7,RRR
MOV
R7,#1
MOV
R0,#30H
MOV
R4,04H
CON:
INC
@R0
CJNE
@R0,#0AH,RRR
MOV
@R0,#00H
INC
R0
DJNZ
R4,CON
RRR:
MOV
TH0,#3CH
MOV
TL0,#0B0H
RETI
DIS:
MOVC
A,@A+DPTR
MOV
P0,A
RET
DEL:
MOV
R6,#20
DEL1:
MOV
R5,#150
DEL2:
DJNZ
R5,$
DJNZ
R6,DEL1
RET
DTAB:DB
0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
DB
88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,7FH,0BFH
END
3)最大数为256的计数器
DAT
DATA
30H
BW
DATA
31H
SHW
DATA
32H
GW
DATA
33H
ORG
0000H
AJMP
MAIN
ORG
000BH
AJMP
COUNT
ORG
0030H
MAIN:
MOV
SP,#60H
MOV
TMOD,#01H
MOV
TH0,#3CH
MOV
TL0,#0B0H
SETB
EA
SETB
ET0
SETB
TR0
MOV
R7,#2
MOV
DAT,#00H
LOOP:
LCALL
CHANGE
MOV
P2,#01H
MOV
A,GW
LCALL
DIS
LCALL
DEL
MOV
P2,#02H
MOV
A,SHW
LCALL
DIS
LCALL
DEL
MOV
P2,#04H
MOV
A,BW
LCALL
DIS
LCALL
DEL
MOV
P2,#08H
MOV
A,#0AH
LCALL
DIS
LCALL
DEL
AJMP
LOOP
COUNT:
DJNZ
R7,RRR
MOV
R7,#2
INC
DAT
RRR:
MOV
TH0,#3CH
MOV
TL0,#0B0H
RETI
CHANGE:
MOV
A,DAT
MOV
B,#100
DIV
AB
MOV
BW,A
MOV
A,#10
XCH
A,B
DIV
AB
MOV
SHW,A
MOV
GW,B
RET
DIS:
MOV
DPTR,#TAB
MOVC
A,@A+DPTR
MOV
P0,A
RET
DEL:
MOV
R6,#20
DEL1:
MOV
R5,#150
DEL2:
DJNZ
R5,$
DJNZ
R6,DEL1
RET
TAB:DB
0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
END
74LS4位静态数码显示:
方法一:ORG
0000H
MOV
R3,#04H
MOV
R0,#20H
START:LCALL
DISPLAY
LCALL
COUNT
LCALL
DELAY
SJMP
START
COUNT:INC
@R0
CJNE
@R0,#0AH,DON
MOV
@R0,#00H
SHW:
INC
R0
INC
@R0
CJNE
@R0,#0AH,DE1
MOV
@R0,#00HBW:
INC
R0
INC
@R0
CJNE
@R0,#0AH,DE2
MOV
@R0,#00H
QW:
INC
R0
INC
@R0
CJNE
@R0,#0AH,DE3
MOV
@R0,#00H
DE3:
DEC
R0
DE2:
DEC
R0
DE1:
DEC
R0
DON:
RET
DISPLAY:MOV
SCON,#00H
LOOP:MOV
A,@R0
ADD
A,#0FH
MOVC
A,@A+PC
MOV
SBUF,A
JNB
TI,$
CLR
TI
INC
R0
DJNZ
R3,LOOP
MOV
R3,#04H
MOV
R0,#20H
DON1:RET
DTAB:DB
3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
DB77H,7CH,39H,5EH,79H,71H,00H,0F3H,76H,80H,40H
DELAY:MOV
R7,#50
DELAY1:MOV
R6,#100
DELAY2:MOV
R5,#20
DJNZ
R5,$
DJNZ
R6,DELAY2
DJNZ
R7,DELAY1
RET
END
方法二:ORG
0000H
AJMP
MAIN
ORG
000BH
AJMP
COUNT
ORG
0020H
MAIN:
MOV
R1,#30H
MOV
R2,#04H
CLEAR:MOV
@R1,#00H
INC
R1
DJNZ
R2,CLEAR
MOV
SP,#60H
MOV
TMOD,#01H
MOV
TH0,#0B0H
SETB
EA
SETB
ET0
SETB
TR0
MOV
R3,#3
MOV
DPTR,#DTAB
MOV
SCON,#00H
DISPLY:MOV
R1,#30H
MOV
R2,#04H
LOOP:MOV
A,@R1
MOVC
A,@A+DPTR
MOV
SBUF,A
JNB
TI,$
CLR
TI
INC
R1
DJNZ
R2,LOOP
ACALL
DEL
SJMP
LOOP
COUNT:DJNZ
R3,RRR
MOV
R3,#3
MOV
R0,#30H
MOV
R4,#04H
CON:INC
@R0
CJNE
@R0,#0AH,RRR
MOV
@R0,#00H
INC
R0
DJNZ
R4,CON
RRR:MOV
TH0,#3CH
MOV
TL0,#0B0H
RETI
DEL:MOV
R6,#250
DEL1:MOV
R5,#250
DEL2:DJNZ
R5,$
DJNZ
R6,DEL1
RET
DTAB:DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
DB77H,7CH,39H,5EH,79H,71H,00H,0F3H,76H,80H,40H
END
动态数码显示:ORG
0000H
ACALL
START
START1:
MOV
@R0,#00H
INC
R0
DJNZ
R2,START1
ACALL
START2
COUNT:
CJNE
@R0,#0AH,ACALLDIS
MOV
@R0,#00H
INC
R0
INC
@R0
CJNE
R0,#34H,COUNT
ACALL
START
AJMP
START1
ACALLDIS:ACALL
DISPLAY
INC
@R0
AJMP
COUNT
DISPLAY:
ACALL
START
MOV
R4,#01H
DISPLAY1:MOV
A,@R0
MOV
DPTR,#DTAB
MOVC
A,@A+DPTR
MOV
P0,A
INC
R0
MOV
A,R3
MOV
P2,A
RL
A
MOV
R3,A
ACALL
DELAY
DJNZ
R2,DISPLAY1
ACALL
START
DJNZ
R4,DISPLAY1
RET
DTAB:DB
3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
DB77H,7CH,39H,5EH,79H,71H,00H,0F3H,76H,80H,40H
START:MOV
R3,#0FEH
START2:MOV
R0,#34H
MOV
R2,#04H
RET
DELAY:MOV
R7,#088H
DEL1:MOV
R6,#88H
DEL2:MOV
R5,#01H
DEL3:DJNZ
R5,DEL3
DJNZ
R6,DEL2
DJNZ
R7,DEL1
RET
END
独立键盘加减清零数码显示:
#include
#define
uchar
unsigned
char
#define
uint
unsigned
int
sbit
key1=P3^4;
sbit
key2=P3^5;
sbit
key3=P3^6;
sbit
key4=P3^7;
sbit
dula=P2^6;
sbit
wela=P2^7;
uchar
code
table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void
delayms(uint);
uchar
numt0,num;
void
display(numdis)
{uchar
shi,ge;
shi=numdis/10;
ge=numdis%10;
wela=1;
P0=0xfe;
wela=0;
dula=1;
P0=table[shi];
dula=0;
P0=0xff;
delayms(5);
wela=1;
P0=0xfd;
wela=0;
dula=1;
P0=table[ge];
dula=0;
P0=0xff;
delayms(5);}
void
delayms(uint
x)
{uint
i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);}
void
init()
{TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;}
void
keyscan()
{if(key1==0)
{delayms(10);
if(key1==0)
{num++;
if(num==60)
num=0;
while(!key1);}}
if(key2==0)
{delayms(10);
if(key2==0)
{
if(num==0)
num=60;
num--;
while(!key2);
}}
if(key3==0)
{delayms(10);
if(key3==0)
{num=0;
while(!key2);}}
if(key4==0)
{delayms(10);
if(key4==0)
{
while(!key4);
TR0=~TR0;}}}
void
main()
{init();
while(1)
{keyscan();
display(num);}}
void
T0_time()
interrupt
1
{TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
numt0++;
if(numt0==20)
{numt0=0;
num++;
if(num==60)
num=0;}}
矩阵键盘0到F显示:
KEY_DATA
DATA
30H
ORG
0000H
MOV
KEY_DATA,#10H
AJMP
MAIN
ORG
0030H
MAIN:MOV
SP,#60H
LOOP:LCALL
SCAN
MOV
A,KEY_DATA
MOV
DPTR,#TAB
MOVC
A,@A+DPTR
MOV
P0,A
LCALL
DEL
AJMP
LOOP
SCAN:MOV
A,#0FH
MOV
P1,A
MOV
A,P1
CJNE
A,#0FH,KEYSCAN
RET
KEYSCAN:LCALL
DEL
MOV
R2,#7FH
MOV
R3,#4
MOV
R0,#00H
KEYSM1:MOV
A,R2
MOV
P1,A
RR
A
MOV
R2,A
MOV
A,P1
ANL
A,#0FH
CJNE
A,#0FH,JSADD
INC
R0
DJNZ
R3,KEYSM1
RET
JSADD:
JB
ACC.0,JSADD1
MOV
A,#0
AJMP
JSADD4
JSADD1:JB
ACC.1,JSADD2
MOV
A,#4
AJMP
JSADD4
JSADD2:JB
ACC.2,JSADD3
MOV
A,#8
AJMP
JSADD4
JSADD3:JB
ACC.3,JSADD4
MOV
A,#12
JSADD4:ADD
A,R0
MOV
KEY_DATA,A
DEL:
MOV
R6,#50
DEL1:
MOV
R5,#200
DJNZ
R5,$
DJNZ
R6,DEL1
RET
TAB:DB
0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
DB88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,7FH,0BFH
END
篇2:基于16F887单片机数字钟课设设计报告
基于16F887单片机数字钟课设设计报告word格式 本文关键词:单片机,格式,报告,设计,数字钟
基于16F887单片机数字钟课设设计报告word格式 本文简介:第44页共44页xxxxxx《基于PIC16F887单片机的数字钟》课程设计报告学生姓名:_学号:_____专业班级:____________指导教师:___________*年*月*日目录1.功能介绍31.1PIC16F887介绍31.2DS1307介绍31.3TC74介绍31.4LM1602L介
基于16F887单片机数字钟课设设计报告word格式 本文内容:
第
44
页
共
44
页
xxxxxx
《基于PIC16F887单片机的数字钟》
课程设计报告
学生姓名:
_
学
号:
_____
专业班级:
__________
__
指导教师:
___
________*年*月*日
目
录
1.功能介绍3
1.1
PIC16F887介绍3
1.2
DS1307介绍3
1.3
TC74介绍3
1.4
LM1602L介绍3
1.5蜂鸣器介绍3
2.硬件原理框图4
3.模块介绍4
3.1
单片机最小系统模块4
3.2时间和温度通讯模块5
3.3
按键模块5
3.4
蜂鸣器和液晶显示器模块5
4.软件框图7
5.软件功能介绍7
5.1
端口﹑LCD和IIC初始化及端口若上拉7
5.2
显示预显示的数字和字母8
5.3
根据闹钟按键判断9
5.4
写入初值到时钟芯片9
5.5
时间加减设置10
5.6
显示时间﹑读和显示温度﹑显示字母星期11
6.个人心得体会12
6.1
关于PIC课设12
6.2
课设过程遇到的问题及解决措施12
6.3
我的建议14
附录1:数字钟的全部C程序15
附录2:Proteus完整仿真图44
1.功能介绍
1.1
PIC16F887介绍
PIC16F887单片机共有40个引脚,其中有33个端口引脚,7个电源﹑地和复位引脚。外部晶振设为4MHz,引脚1接复位按键。此数字钟用到单片机的B端口中断功能,端口若上拉,电平变化下降沿中断。
1.2
DS1307介绍
DS1307时钟芯片是实时时钟芯片,它提供秒﹑分﹑时﹑日﹑月﹑年和星期等数据,有备用电源,主电源掉电备用,时钟晶振是32.768kHz。其控制寄存器的地址为07,其值0b11010000,代表允许其7脚输出每秒1Hz的方波。其秒﹑分﹑时﹑日﹑月﹑年和星期分别存在地址为00﹑01﹑02﹑04﹑05﹑06﹑03中。其与单片机的通讯为IIC通讯。
1.3
TC74介绍
温度传感器TC74是感测周围温度值。TC74芯片的默认值为0b1001101(实验板上芯片调试时的地址为0b1001000,此为仿真时用的地址)。单片机首先向TC74改善地址,地址在字节的高7位,最低位为0表示为写。接着单片机向TC74发送第二个数据,即读温度命令字RTR,即8位0;然后重新开始,单片机再向TC74发送地址,但此时的最低位为1,表示接下来是要读TC74的温度值。最后单片机接收TC74发出的温度值。TC74与单片机的通讯也为IIC通讯。
1.4
LM1602L介绍
字符型LM016L液晶显示器。要求用4位数据线通讯,传送命令也传送地址。其初始化的格式是固定的,不能更改的,初始化见后面所示。输入到液晶显示器的是所示字符的ASCII码,液晶才能正确显示。
1.5蜂鸣器介绍
蜂鸣器是用来设置闹钟用的。当设定闹钟的时间到时,蜂鸣器响,按键按下,停止响。按键模块是用来进行年月日﹑秒分时和星期加减及设定闹钟用的。采用的是电平变化的中断模式。
2.硬件原理框图
220V
变压器变压
CUP模块
液晶显示
按键输入
DS1307和TC74
市电220V电压经变压器变压供CPU使用的低压。DS1307和TC74经CPU显示在液晶上。按键控制DS1307的时间加减和闹钟设置,实现闹钟功能。先在液晶上定位要显示数据的位置,然后将要显示的字符的ASCII码输入到液晶,即可正确数据。
3.模块介绍
3.1
单片机最小系统模块
此单片机的外部晶振为4MHz,引脚1接有高电平和复位按钮。端口B口用来进行电平变化中断,端口RC3和RC4用来进行IIC通讯,RC1用来输出高电平给蜂鸣器。端口D端口用来输出命令和数据给液晶显示器。
3.2时间和温度通讯模块
DS1307时间芯片可根据输入的数据自动走时。单片机不断地访问DS1307芯片,将访问得到的数据显示在液晶显示器上。其中芯片上读出来的星期是数字星期(01即代表星期一),软件部分将数字星期转换成字母星期(如Wed为星期三)。单片机也访问TC74温度传感器,要得到的数据显示在液晶上。温度传感器小数后面有一位,但是设计时只显示到个位,不显示小数点后面的数字。
3.3
按键模块
按键S1是用来定位时间加减用的,来回按7下,分别对秒分时,星期和日月年。S2可以对时间进行加运算即每按一下,相应的时间加1;S3可以时间进行减运算即每按一下,相应的时间减1;S4是闹钟按键,按第一下,进入闹钟设置模式,此时再按S2或S3可以对时间进行设定。按第二下时,CPU进入比较模式,即把DS1307的时间和设定保存好的时间进行比较,等待设定的时间到时,蜂鸣器开始响。当按第三下时,蜂鸣器停止响,相应的变量清零,从重新开始。
3.4
蜂鸣器和液晶显示器模块
当定时时间到,RC1输出高电平,二极管导通,蜂鸣器开始响。当RC1输出低电平时,二极管截止,蜂鸣器停止响。液晶显示器用来显示时间,星期和温度,首先要进行显示时间定位,即写入命令。然后进行显示数据输入,即定稿数据。VEE和VSS都拉低,VDD拉高电平。RS为0时,写命令,为1时写数据;R/为1时表示读,0时表示写;E数据使能端,下降沿送入有效。RD0~RD3,数据输入端,使用液晶显示器端口的高4位。
4.软件框图
端口﹑LCD和IIC初始化及端口若上拉
显示预显示的数字和字母
延迟2秒
写入初值到时钟芯片
显示时间﹑读和显示温度﹑显示字母星期
时间加减设置
闹钟设置和进行比较
蜂鸣器响
C=0或2
C=1
C=2
S4第三次按下
蜂鸣器不响
C=3
根据闹钟按键判断
该功能在中断程序段中
5.软件功能介绍
5.1
端口﹑LCD和IIC初始化及端口若上拉
//初始化端口
void
CSH(void)
{TRISB=0b11111111;
//端口B全为输入
TRISC=0b00011000;
//端口C中RC3和RC4为输入,其余为输出
ANSELH=0b00000000;
//选择I/O口
ANSEL=0;
//选择I/O口
OPTION=0b00000000;
//允许若上拉,下降沿中断
WPUB=0b11111111;
//B口若上拉
TRISA4=1;
//A口第5引脚为输入
TRISD=0b00000000;//控制LCD1604,全为输出
IOCB=0b00001111;
//允许电平变化中断
INTCON=0b11001000;
//允许全局中断,B口电平变化中断
FMQ=0;
//蜂鸣器不响
LCD_CSH();
//LCD初始化
IIC_CSH();
//IIC初始化
}
此为对端口﹑LCD和IIC的初始化,上面均有详细的说明,在此不做过多的重复。
LCD的初始化,上电时需要延时15ms及以上,此为延时20ms,其C程序见附录。
IIC的初始化,初始化过程实际上是对几个相关的寄存器设置的过程,其C程序见附录。
5.2
显示预显示的数字和字母
const
char
MENU0[2][17]={
{“010900628
“},{“linyixing
“}};
//完全按照数组中的字符显示整屏
void
DISP_MENU(const
charA)
{
char
i,j;
for
(i=0;i>4;//取高4位
LCD_WRITE_4(R2,FLAG);//先写高4位
R2=R1
//高4位清0,取低4位
LCD_WRITE_4(R2,FLAG);//再送低4位
DELAY_US(10);//延时100us
}
//写R1的低4位,FLAG为寄存器选择,1为命令,0为数据
void
LCD_WRITE_4(char
R1,char
FLAG)
{LCD_RW=0;NOP();//写模式
LCD_RS=FLAG;NOP();
//寄存器选择
PORTD
NOP();//RD高4位先清0
LCD_E=1;NOP();//使能
PORTD
|=R1;NOP();//送4位
LCD_E=0;NOP();//数据送入有效
LCD_RS=0;NOP();
PORTD
//RD高4位清0
}
此程序的功能的把给定的字符显示到LCD液晶显示器上,字符串有两行,分行显示。先是对要显示的位置进行定位,如第一行第0位。然后将一个字符的高低4位分别送入显示,显示时送入的是ASCII码。
5.3
根据闹钟按键判断
此为根据c=0,1,2来判断的。为0或2时,显示的是时钟芯片的时间,其中为2时,时钟有在比较时间;为1时显示的时闹钟设定的时间。c为3
时蜂鸣器不响。其C程序详见附录。
5.4
写入初值到时钟芯片
LCD_WRITE(0b00000001,COM);
//清屏
WRITE_DS1307(0x07,0x10);//写控制字到LCD
WRITE_DS1307(0x00,0x00);//0秒
WRITE_DS1307(0x01,0x00);//00分
WRITE_DS1307(0x02,0x11);
//11h
WRITE_DS1307(0x03,0x03);//星期3
WRITE_DS1307(0x04,0x08);//8日
WRITE_DS1307(0x05,0x05);//5月
WRITE_DS1307(0x06,0x12);//12年
//写ds1307,地址为address,数为data
void
WRITE_DS1307(char
ADDRESS,char
da)
{
START_BIT;
IIC_SEND(ADDR);
IIC_SEND(ADDRESS);
IIC_SEND(da);
STOP_BIT;
}
//发送数R并等待发送完成,收到从机的应答信号,中断用
void
IIC_SEND_interrupt(char
R)
{SSPBUF=R;//发送
SSPIF=0;
while
(RW==1);//在主动模式下,判断发送是否完成
while
(SSPIF==0);//等待发送完成
while
(ACKSTAT==1);//等待从机发送应答信号
NOP();
NOP();
}
写入初值到时钟芯片时,要用到IIC通讯,即IIC发送。先送时钟地址,再送要写入数据的地址,再送入数据。此可对时钟芯片的年月日,秒分时和星期进行设定初值。
5.5
时间加减设置
//校正时候实现“加”功能子程序
void
INC(void)
{
if(a==7)
//年部分校正
{
AAAA[6]+=1;
//如果a==7,则数组[6]自动加1
if((AAAA[6]
AAAA[6]=AAAA[6]+0x10;
//数组[6]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[6]>0x99)
AAAA[6]=AAAA[6]//如果数组[6]元素值大于0x99,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x06,AAAA[6]);//将经过修改的数组元素写入
if(c==1)
{
LCD_WRITE_interrupt(LINE1+4,COM);
DISP_HEX_interrupt(AAAA[6]);
}
}
}
此功能从DS1307中读出时间数据,然后对数据进行加减运算,再把修改后的时间写入到时钟芯片中,即可实现对时间的加减运算。由于程序篇幅较长,在此只列出部分加的C程序,其余加C程序及减C程序详见附录。
5.6
显示时间﹑读和显示温度﹑显示字母星期
READ_DS1307(0x00,0x07);
//读时钟芯片
(设置闹钟时间是没有这一行指令)
DISP_TIME(*AAAA);
//实时显示时间
(具体C程序见附录)
R1=READ_T();
//读温度传感器的值
DISP_T(R1);
//显示温度值
DISP_XINGQI(AAAA[3]);
//显示字母星期
//显示字母星期
void
DISP_XINGQI(char
b)
{
if(b==1)
//如果b=1,则显示Mon
{
LCD_WRITE(LINE1+13,COM);//第二行第13位
LCD_WRITE(
M,DAT);
LCD_WRITE(
o,DAT);
LCD_WRITE(
n,DAT);//13、14、15分别显示M、o、n
}
else
if(b==2)
//如果b=2,则显示Tue
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
T,DAT);
LCD_WRITE(
u,DAT);
LCD_WRITE(
e,DAT);//同上
}
}
其完整程序详见附录,在此只给出其中的一部分。
//读TC74的温度值
signed
char
READ_T(void)
{
signed
char
R2;
SEN=1;//开始条件
while
(SEN==1);//检测开始条件是否完成?
IIC_SEND(TC74_ADD
__CONFIG(0x20F1);//调试用
__CONFIG(0x3FFF);
#defineLCD_ERD6//LCD
E
读写使能控制
#defineLCD_RWRD5//LCD
读(1)/写(0)控制线
#define
LINE10b10000000
#define
LINE20b11000000
#defineLCD_RSRD4//LCD
寄存器选择
数据(1)指令(0)
//RD4-RD7分别接DB4-DB7,RD7为忙标志
#define
COM0//在LCD_WRITE()中的第2参数为0表示写命令
#define
DAT1//在LCD_WRITE()中的第2参数为1表示写数据
#define
TC74_ADD
0b1001101
//TC74的7位地址
#define
RTR0b00000000
//TC74的读温度命令
#define
ADDR
0b11010000
//时钟芯片的地址
#define
YEAR_P
LINE1+2
//年的显示位置
#define
HOUR_P
LINE2+2
//时的显示位置
#define
KEY_DEC
RB2
#define
KEY_INC
RB1
#define
FMQ
RC1
//产生起始位,检测完成起始位?
#define
START_BIT
/
SEN=1;/
while(SEN==1)
//停止位,检查至停止位结束
#define
STOP_BIT
/
PEN=1;
/
while(PEN==1)
//发送重复开始,确定重复开始已完成?
#define
RE_START_BIT
/
RSEN=1;/
while(RSEN==1)
//接收使能模式,确定接收使能?
#define
RECEIVE_ENABLE_BIT/
RCEN=1;/
while(RCEN==1)
//自动应答,检查是否完成应答?
#define
ACK_BIT/
ACKDT=0;/
ACKEN=1;/
while(ACKEN==1)
//不应答,检查是否完成无应答?
#define
NOT_ACK_BIT/
ACKDT=1;/
ACKEN=1;/
while(ACKEN==1)
bank1
char
DD[16];//一行LCD显示数据暂存
bank1
char
AAAA[7];
//存放时钟芯片读出来的数据
bank1
char
CCCC[7];
//存放闹钟设定的时间
void
CSH(void);//初始化
void
LCD_CSH(void);//LCD初始化
void
LCD_BUSY(void);//检测LCD是否忙
char
LCD_READ(void);//读LCD,忙检测用
void
LCD_WRITE(char,char);//LCD写1字节,命令或数据
void
LCD_WRITE_4(char,char);//LCD写半字节
void
DISP_C(char);//在指定行中显示字符,字符在数组DD中
void
DISP_MENU(const
char);//由常数数组显示整屏字符
signed
char
READ_T(void);
//读温度传感器的温度值
void
IIC_CSH(void);
//IIC的初始化
void
IIC_SEND(char);
//IIC的发送与接收
void
DISP_T(char);
//显示温度值
void
BCD(char);
//BCD码转换
void
DELAY_US(char);
//延迟程序,10uS级
void
DELAY(unsigned
int);
//延迟程序,mS级
void
DELAY_I(unsigned
int);
//中断用的延迟程序,mS级
void
DISP_TIME(char);
//显示时钟的时间
void
DISP_HEX(char);
//将一个字节分两个字节显示
void
READ_DS1307(char,char);
//读时钟芯片
void
WRITE_DS1307(char,char);
//向时钟芯片写入值
void
interrupt
ISR(void);
//按键中断程序
void
DISP_XINGQI(char);
//星期转换,显示字母星期
void
INC(void);
//按键加1
void
DEC(void);
//按键减1
void
IIC_SEND_interrupt(char);
//中断用IIC发送和接收
void
WRITE_DS1307_interrupt(char,char);
//中断用写时钟芯片
//void
READ_DS1307_interrupt(char,char);
void
LCD_WRITE_interrupt(char,char);
//中断用写LCD
void
DISP_HEX_interrupt(char);
//中断用将一个字节显示成两个字节
//整屏界面,每行16个字符,最后加一个结束符
const
char
MENU0[2][17]={
{“010900628
“},{“linyixing
“}};
//定义常数
const
char
LINE[2]={LINE1,LINE2};
//定义数组和变量
char
SW,GW,a=0,c=0,d,i;
//主程序
main(void)
{
signed
char
R1;
//DELAY(100);
CSH();
//端口,LCD和IIC初始化
DISP_MENU(*MENU0);//显示整屏
DELAY(2000);
//延迟2秒,看清显示是什么
LCD_WRITE(0b00000001,COM);
//清屏
WRITE_DS1307(0x07,0x10);//写控制字到LCD
WRITE_DS1307(0x00,0x00);//0秒
WRITE_DS1307(0x01,0x00);//00分
WRITE_DS1307(0x02,0x11);
//11h
WRITE_DS1307(0x03,0x03);//星期3
WRITE_DS1307(0x04,0x08);//8日
WRITE_DS1307(0x05,0x05);//5月
WRITE_DS1307(0x06,0x12);//12年
while(1)
{
if((c==0)||(c==2))
//当C=0或C=2时执行
{
READ_DS1307(0x00,0x07);
//读时钟芯片
DISP_TIME(*AAAA);
//实时显示时间
R1=READ_T();
//读温度传感器的的值
DISP_T(R1);
//显示温度值
DISP_XINGQI(AAAA[3]);
//显示字母星期
}
if(c==1)
//C=1时执行
{
DISP_TIME(*AAAA);
//显示闹钟修改的时间
R1=READ_T();
//同上
DISP_T(R1);
//同上
DISP_XINGQI(AAAA[3]);
//同上
}
if((CCCC[2]==AAAA[2])
//当设定的时间到时,蜂鸣器响
};
}
//显示字母星期
void
DISP_XINGQI(char
b)
{
if(b==1)
//如果b=1,则显示Mon
{
LCD_WRITE(LINE1+13,COM);//第二行第13位
LCD_WRITE(
M,DAT);
LCD_WRITE(
o,DAT);
LCD_WRITE(
n,DAT);//13、14、15分别显示M、o、n
}
else
if(b==2)
//如果b=2,则显示Tue
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
T,DAT);
LCD_WRITE(
u,DAT);
LCD_WRITE(
e,DAT);//同上
}
else
if(b==3)
//如果b=3,则显示Wed
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
W,DAT);
LCD_WRITE(
e,DAT);
LCD_WRITE(
d,DAT);//同上
}
else
if(b==4)
//如果b=4,则显示Thu
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
T,DAT);
LCD_WRITE(
h,DAT);
LCD_WRITE(
u,DAT);//同上
}
else
if(b==5)
//如果b=5,则显示Fri
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
F,DAT);
LCD_WRITE(
r,DAT);
LCD_WRITE(
i,DAT);//同上
}
else
if(b==6)
//如果b=6,则显示Sat
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
S,DAT);
LCD_WRITE(
a,DAT);
LCD_WRITE(
t,DAT);//同上
}
else
if(b==7)
//如果b=7,则显示Sun
{
LCD_WRITE(LINE1+13,COM);//同上
LCD_WRITE(
S,DAT);
LCD_WRITE(
u,DAT);
LCD_WRITE(
n,DAT);//同上
}
}
//中断子程序
void
interrupt
ISR(void)
{
DELAY_I(30);
//按键去抖
RBIF=0;
//标志位清零
if(RB3==0)
//闹钟键按下
{
a=0;c+=1;d+=1;
}
if(RB0==0
if(a==8)
a=1;
}
if(RB1==0}
if(RB2==0}
if(c==1)
//闹钟键按下
{
if(RB0==0)
//闹钟键按下的定位
{
a++;
if(a==8)
a=1;
}
if(RB1==0)
//同上
{INC();}
if(RB2==0)//同上
{DEC();}
for(i=0;i9)
{AAAA[6]=AAAA[6]
AAAA[6]=AAAA[6]+0x10;
//数组[6]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[6]>0x99)
AAAA[6]=AAAA[6]//如果数组[6]元素值大于0x99,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x06,AAAA[6]);//将经过修改的数组元素写入
if(c==1)
{
LCD_WRITE_interrupt(LINE1+4,COM);
DISP_HEX_interrupt(AAAA[6]);
}
}
//月部分校正
if(a==6)
{
AAAA[5]+=1;
if((AAAA[5]
AAAA[5]=AAAA[5]+0x10;
//数组[5]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[5]>0x12)
{
AAAA[5]=AAAA[5]
AAAA[5]=AAAA[5]+0x01;//如果数组[5]元素值大于0x12,则整个数都清零再加1
}
if(c==0)
WRITE_DS1307_interrupt(0x05,AAAA[5]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+7,COM);
DISP_HEX_interrupt(AAAA[5]);
}
}
//日部分校正
if(a==5)
{
AAAA[4]+=1;
if((AAAA[4]
AAAA[4]=AAAA[4]+0x10;//数组[4]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[4]>0x31)
{
AAAA[4]=AAAA[4]
AAAA[4]=AAAA[4]+0x01;//如果数组[4]元素值大于0x31,则整个数都清零再加1
}
if(c==0)
WRITE_DS1307_interrupt(0x04,AAAA[4]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+10,COM);
DISP_HEX_interrupt(AAAA[4]);
}
}
//星期部分校正
if(a==4)
{
AAAA[3]+=1;
if(AAAA[3]>7)
AAAA[3]=1;
//如果数组[3]的元素大于7时,则复位到1
if(c==0)
WRITE_DS1307_interrupt(0x03,AAAA[3]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+13,COM);
DISP_HEX_interrupt(AAAA[3]);
}
}
//时部分校正
if(a==3)
{
AAAA[2]+=1;
if((AAAA[2]
AAAA[2]=AAAA[2]+0x10;//数组[2]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[2]>0x23)
{
AAAA[2]=AAAA[2]//如果数组[2]元素值大于0x24,则整个数都清零
}
if(c==0)
WRITE_DS1307_interrupt(0x02,AAAA[2]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE2+2,COM);
DISP_HEX_interrupt(AAAA[2]);
}
}
//分部分校正
if(a==2)
{
AAAA[1]+=1;
if((AAAA[1]
AAAA[1]=AAAA[1]+0x10;//数组[1]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[1]>0x59)
AAAA[1]=AAAA[1]
//如果数组[1]元素值大于0x59,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x01,AAAA[1]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE2+5,COM);
DISP_HEX_interrupt(AAAA[1]);
}
}
//秒部分校正
if(a==1)
{
AAAA[0]+=1;
if((AAAA[0]
AAAA[0]=AAAA[0]+0x10;//数组[0]元素的低四位大于9时,则低四位清零而高四位进1位
}
if(AAAA[0]>0x59)
AAAA[0]=AAAA[0]
//如果数组[0]元素值大于0x59,则整个数都清零
if(c==0)
WRITE_DS1307_interrupt(0x00,AAAA[0]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE2+8,COM);
DISP_HEX_interrupt(AAAA[0]);
}
}
}
//校正时候实现“减”功能子程序
void
DEC(void)
{
if(a==7)
//年部分校正
{
AAAA[6]-=1;
//如果a==0,则数组[6]自动减1
if((AAAA[6]
AAAA[6]=AAAA[6]+0x09;//数组[6]元素的低四位大于9时,则低四位清零且改为0x09,而高四位则自动减1
}
if(((AAAA[6]
AAAA[6]=AAAA[6]+0x99;//如果数组[6]元素高四位大于9时,则整个数值清零再改为0x99
}
if(c==0)
WRITE_DS1307_interrupt(0x06,AAAA[6]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+4,COM);
DISP_HEX_interrupt(AAAA[6]);
}
}
//月部分校正
if(a==6)
{
AAAA[5]-=1;
if((AAAA[5]
AAAA[5]=AAAA[5]+0x09;
//数组[5]元素的低四位大于9时,则低四位清零且改为0x09,而高四位则自动减1
}
if(AAAA[5]==0x00)
AAAA[5]=AAAA[5]+0x12;//如果数组[5]元素等于0时,则整个数值改为0x12
if(c==0)
WRITE_DS1307_interrupt(0x05,AAAA[5]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+7,COM);
DISP_HEX_interrupt(AAAA[5]);
}
}
//日部分校正
if(a==5)
{
AAAA[4]-=1;
if((AAAA[4]
AAAA[4]=AAAA[4]+0x09;
//数组[4]元素的低四位大于9时,则低四位清零且改为0x09,而高四位则自动减1
}
if(AAAA[4]==0x00)
AAAA[4]=AAAA[4]+0x31;//如果数组[4]元素等于0时,则整个数值改为0x31
if(c==0)
WRITE_DS1307_interrupt(0x04,AAAA[4]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+10,COM);
DISP_HEX_interrupt(AAAA[4]);
}
}
//星期部分校正
if(a==4)
{
AAAA[3]-=1;
if(AAAA[3]<1)
AAAA[3]=7;//如果数组[3]的元素小于1时,则复位到7
if(c==0)
WRITE_DS1307_interrupt(0x03,AAAA[3]);//将经过修改的数组元素写入
else
if(c==1)
{
LCD_WRITE_interrupt(LINE1+13,COM);
DISP_HEX_interrupt(AAAA[3]);
}
}
//时部分校正
if(a==3)
{
AAAA[2]-=
篇3:基于51单片机和8279芯片的电子时钟设计报告
基于51单片机和8279芯片的电子时钟设计报告 本文关键词:单片机,时钟,芯片,报告,设计
基于51单片机和8279芯片的电子时钟设计报告 本文简介:任务书题目基于51单片机和8279芯片的电子时钟设计时间安排目的:通过《单片机原理与应用》这门课的课程设计,学生应能对MCS-51单片机有一个全面的认识,掌握以MCS-51单片机为核心的电子电路的设计方法和应用技术。1.进一步掌握8279键盘显示电路的编程方法。2.进一步掌握定时器的使用和编程方法。
基于51单片机和8279芯片的电子时钟设计报告 本文内容:
任务书
题
目
基于51单片机和8279芯片的电子时钟设计
时
间安排
目
的:
通过《单片机原理与应用》这门课的课程设计,学生应能对MCS-51单片机有一个全面的认识,掌握以MCS-51单片机为核心的电子电路的设计方法和应用技术。
1.进一步掌握8279键盘显示电路的编程方法。
2.进一步掌握定时器的使用和编程方法。
3.进一步掌握中断处理程序的编程方法。
要
求:
(1)
利用AT89C51作为主控器组成一个电子钟并具有闹钟功能。
(2)
利用8位LED用于显示当前时间。
(3)
利用8279芯片进行键盘和LED的管理和显示。
(4)
发挥自己的创造力,实现尽可能多的功能。
总体方案实现:
用AT89C51作为主控制器,并采用8279作为辅助芯片,控制键盘、LED数码管等的操作和显示。
指导教师评语:
评分等级:(
)
指导教师签名:
目录
一、系统总体设计方案规划与选定3
二、系统硬件功能及参数简介4
2.1
AT89C51单片机简介.4
2.2
AT89C51单片机的引脚说明.5
2.3
LED简介.7
2.4
8279基本原理说明.10
2.5
DS1302介绍及基本原理说明.13
2.6
DS18B20介绍及基本工作方式说明17
三、系统硬件电路设计19
3.1
proteus仿真接线图19
3.2分块硬件电路射界.20
4、
软件设计及实现过程.25
4.1程序设计简述.25
4.2系统程序流程图设计.26
五、系统的调试过程27
5.1程序性问题及解决.27
5.2调试过程出现问题及解决.27
六、新增功能及实现方法.29
6.1新增功能.29
6.2实现方法.29
7、
小节与体会.31
参考文献.33
附录34
硬件连接图.34
程序清单.36
一、系统总体设计方案规划与选定
首先,我们对于整个系统做了总体的规划,大致列了一下我们设想中的一些附加功能。由于附加功能较多,我们最终决定,先实现基本功能,然后在基本功能的基础上,对系统进行改进,逐步加入我们设想的拓展功能。
其次,是编程语言的选择,我们学习过的编程语言有两种:C语言与汇编语言。经过比较后决定使用C51编程,因为C语言结构整齐,各个子函数可以独立来写,思路更加清晰显得简单,所以选用C语言来进行编程。同时,利用C语言进行编程也有利于我们后续对系统的改进,也就是增加辅助功能,只要利用子函数实现就行,并且可以独立于整个系统运行,可以单独对子函数进行测试。对于所设想的附加功能,我们首先进行相关资料的查询,然后可以对子函数进行编写,并进行单独的调试。可以说,使用C语言编程在软件方面增加了我们系统的可拓展性。
最后,是有关硬件的设计,为了实现基本功能,我们对8979芯片以及DS1302芯片进行了仔细的学习,从网上查阅了不少资料。对于电路图的设计,我们也是按照老师的要求,先实现按照实现基本功能进行设计,按照课本进行电路图的链接,同时查阅了关于8279芯片的使用说明书。基本电路图设计完成之后,便查阅有关资料,对我们设想的附加功能所用到的DS1302时钟芯片和DS18B20温度传感器进行学习了解硬件的连接和测试过程。而且由于一开始对软件的使用不熟练,在页面的排版布局上也没有计划,最终显得整个电路硬件仿真连接图较乱,最后有进行了重新整理和布局,并配上详细说明,是的整体看起来协调、美观。
二、系统硬件功能及参数简介
2.1
AT89C51单片机简介
AT89C51单片机是在一块芯片中集成了CPU、RAM、ROM、定时器/计数器和多种功能的I/O线等一台计算机所需要的基本功能部件,AT89C51单片机内包含下列几个部件:
(1)
一个8位CPU;
(2)一个片内振荡器及时钟电路;
(3)4K字节ROM程序存储器;
(4)128字节RAM数据存储器;
(5)两个16位定时器/计数器;
(6)可寻址64K外部数据存储器和64K外部程序存储器空间的控制电路;
(7)32条可编程的I/O线(四个8位并行I/O端口);
(8)一个可编程全双工串行口;
(9)具有五个中断源、两个优先级嵌套中断结构。
其内部机构框图如图2.1所示:
图2.1
MCS-51单片机内部机构框图
2.2
AT89C51单片机的引脚说明
AT89C51单片机采用40条引脚双列直插式器件,引脚除5V(
40脚)和电源地(
20脚)外,其功能分为时钟电路、控制信号、输入/输出三大部分,逻辑框图及引脚图分别如图2.2(a)(b)所示
(a)
(b)
图2.2
AT89C51单片机逻辑图与引脚图
AT89C51单片机的管脚说明如下:
(1)VCC:供电电压
(2)GND:接地
(3)时钟电路
XTAL1(19脚)——芯片内部振荡电路(单级反相放大器)输入端。
XTAL2(18脚)——芯片内部振荡电路(单级反相放大器)输出端。
(4)控制信号
RST(9脚)复位信号:时钟电路工作后,在此引脚上将出现两个机器周期的高电平,芯片内部进行初始复位,P0口~P3口输出高电平,将初值07H写入堆栈指针。
ALE(30脚)地址锁存信号:当访问外部存储器时,P0口输出的低8位地址由ALE输出的控制信号锁存到片外地址锁存器,P0口输出地址低8位后,又能与片外存储器之间传送信息。另外,ALE可驱动4个TTL门。
(29脚)片外程序存储器读选通:低电平有效,作为程序存储器的读信号,输出负脉冲,将相应的存储单元的指令读出并送到P0口,可驱动8个TTL门。
/VPP(30脚):当为高电平且PC值小于0FFFH时,CPU执行内部程序存储器程序;当为低电平时,CPU仅执行外部程序存储器程序。
2.3
LED简介
LED数码管根据LED的接法不同分为共阴和共阳两类,了解LED的这些特性,对编程是很重要的,因为不同类型的数码管,除了它们的硬件电路有差异外,编程方法也是不同的。图2.3(a)是共阴和共阳极数码管的内部电路图,它们的发光原理是一样的,只是它们的电源极性不同而已。
将多只LED的阴极连在一起即为共阴式,而将多只LED的阳极连在一起即为共阳式。以共阴式为例,如把阴极接地,在相应段的阳极接上正电源,该段即会发光。当然,LED的电流通常较小,一般均需在回路中接上限流电阻。假如我们将“b“和“c“段接上正电源,其它端接地或悬空,那么“b“和“c“段发光,此时,数码管显示将显示数字“1”。而将“a“、“b“、“d“、“e“和“g“段都接上正电源,其它引脚悬空,此时数码管将显示“2”。其它数字的显示原理与此类同。
LED的7段数码管利用单只LED组合排列成“8”字型的数码管,分别引出它们的电极,点亮相应的点划来显示出0-9的数字。在这次的设计中采用的均是共阴极的LED显示,当I/O口输出为高电平的时候,对应段就被点亮。LED数码管的结构图如图2.3(b)所示。
(a)
(b)
图2.3
LED分类结构图和结构图
这次设计的显示部分采用AT89C51单片机动态扫描完成,在多数的应用场合中,我们并不希望使用多I/O端口的单片机,原则上是使用尽量少引脚的器件。在没有富余端口的情况下,应通过优化设计程序和扩展电路达到预期的目的。动态扫描的频率有一定的要求,频率太低,LED将出现闪烁现象。如频率太高,由于每个LED点亮的时间太短,LED的亮度太低,肉眼无法看清,所以一般均取几个ms左右为宜,这就要求在编写程序时,选通某一位LED使其点亮并保持一定的时间,程序上常采用的是调用延时子程序。
LED显示电路:
(1)
静态显示电路
LDE显示器工作在静态显示时,其公共阳极(或阴极)
接VCC(或GND)
,一直处于显示有效状态,所以每一位的显示内容必须由锁存器加以锁存,显示各位相互独立。
(2)
动态显示电路
将所有位的段选线的同名端联在一起,由一个8位I/O口控制,形成段选线的多位复用。而各位的公共阳极或公共阴极则分别由相应的I/O口线控制,实现各位的分时选通,即同一时刻只有被选通位是能显示相应的字符,而其他所有位都是熄灭的。由于人眼有视觉暂留现象,只要每位显示间隔足够短,则会造成多位同时点亮的假象。这就需要单片机不断地对显示进行控制,CPU需要不断地进行显示刷新,动态显示电路参见图2.4,图2.4中是扩展了五位的LED数码管显示,用一个74LS04作为五个LED的段选输入,采用动态显示的方式连接。类似地,16位的LED数码管显示也可以用这种方法来实现。
图2.4
五位LED数码管的动态显示
2.4
8279基本原理说明
8279显示部分按扫描的方式工作,可以显示8或16位LED显示块。
8279电路工作原理:
1.I/O控制及数据缓冲器
数据缓冲器是双向缓冲器,连接内、外总线,用于传送CPU和8279之间的命令或数据;I/O控制线是CPU对8279进行控制的引线。CS是8279的片选信号,CS=0时,8279才被允许读出或写入信息。WR、RD为来自CPU的控制信号。A0用于区别信息特性:A0=1时,表示数据缓冲器输入为指令、输出为状态字;A=0时,输入、输出皆为数据。
2.控制与定时寄存器及定时控制
控制与定时寄存器用来寄存键盘及显示的工作方式,以及由CPU编程的其它操作方式。这些寄存器一旦接受并锁存送来的命令,就通过译码产生相应的信号,从而完成相应的控制功能。
定时控制包含基本记数键。首级计数器是一个可编程的N级计数器。N可以2~31之间由软件编程,以便从外界时钟CLK分频得到内部所需要的100KHZ时钟。然后再经过分频为键盘扫描提供适当的逐行扫描频率和显示扫描时间。
3.扫描计数器
扫描计数器有两种工作方式。按编码方式工作时,计数器作二进制记数。4位记数状态从扫描线SL0~SL3输出,经外部译码器译码后,为键盘和显示器提供扫描线;按译码方式工作时,扫描计数器的最低二位被译码后,从SL0~SL3输出。因此,SL0~SL3提供了4中取1的扫描译码。
4.回复缓冲器、键盘去抖及控制来自RL0~RL3的8根回复线的回复信号,由回复缓冲器缓冲并锁存。
在键盘工作方式中,回复线作为行列式键盘的行列输入线。在逐行列输入时,在逐行列扫描时,回复线用来搜索每一行列中闭合的键。当某一键闭合时,去抖电路被置位,延时等待10ms后,再检验该键是否继续闭和,并将该键的地址和附加的移位、控制状态一起形成键盘数据被送入8279内部FIFO(先进先出)存储器。键盘数据格式如下:
D7
D6
D5D4
D3
D2
D1
D0
控制
移位
扫描
回复
控制和移位(D6、D7)的状态由两个独立的附加开关决定,而扫描(D5、D4、D3)和回复(D2、D1、D0)则是被按键置位的数据。D5、D4、D3来自动扫描计数器,是按下键的行列编码,而(D7D7D7)则来自行/列计数器,它们是根据回复信号而确定的行/列编码。
在传感器开关状态矩阵方式中,回复线的内容直接被送往和相应的传感器RAM(即FIFO存储器)。
在选通输入方式中,回复线的内容在CNTL/STB线的脉冲上升沿被送入FIFO存储
5.FIFO/传感器及其状态寄存器
FIFO/传感器RAM是一个双重功能的8×8RAM。
在键盘或选通方式工作时,它是FIFO存储器,其输入或读出遵循先入先出的原则。FIFO状态寄存器用于存放FIFO的工作状态。例如,RAM是满还是空;其中存有多少数据;是否操作出错等。当FIFO存储器不空,状态逻辑将产生IRQ=1信号向CPU申请中断。
在传感器矩阵方式工作时,这个存储器以是传感器不是存储器。它存放着传感器矩阵中的每一个传感器状态。在此方式中,若检索出传感器的变化,IRQ信号变为高电平,向CPU申请中断。
6.显示RAM和显示地址寄存器
显示RAM用来存储显示数据。容量为16×8位。在显示过程中,存储的显示数据轮流从显示寄存器输出。显示寄存器分别为A、B两组,OUTA0~3和OUTB0~3可以单独送数,也可以组成一个8位的字。显示寄存器的输出与显示扫描配合,不断从显示RAM中读出显示数据,同时轮流驱动被选中的显示器件,以达到多路复用的目的,使显示器件呈现稳定的显示状态。
显示地址寄存器用来寄存由CPU进行读/写显示RAM的地址,它可以由命令设定,也可以设置成每次读写或写入之后自动递减。
2.5
DS1302介绍及基本原理说明
2.5.1
主要功能
DS1302
是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
特性:
●
实时时钟,可对秒、分、时、日、周、月以及带闰年补偿的年进行计数
●
用于高速数据暂存的
31×8
RAM
●
2引脚的串行
I/O
●
2.5-5.5V满度工作范围
●
用于时钟或RAM数据读写的单字节或
多字节数据传送
●
双电源引脚
●
可选慢速充电至VCC1
2.5.2
内部结构及引脚功能
DS1302内部主要包括实时时钟(real
time
clock)、输入移位寄存器(input
shift
registers)、31字节静态RAM、电源控制部分(power
control)、命令控制逻辑(command
and
control
logic)、振荡器和分频器(oscillator
and
divider)等部分。DS1302内部结构如图2-5所示。
图2-5
DS1302内部结构
2-6
DS1302引脚排列
DS1302具有8脚DIP引脚排列如图2-6所示。
VCC1:后备电源,在主电源关闭的情况下,也能保持时钟的连续运行;当VCC2大于VCC1+0.2V时,VCC2给DS1302供电。
VCC2:主电源,当VCC2小于VCC1时,DS1302由VCC1供电。
X1、X2:振荡源,外接32768Hz晶振。
GND:接地端
SCLK:串行时钟输入端
I/O:串行数据输入输出端(双向)。
RST:复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
2.5.3
工作原理
DS1302工作时为了对任何数据传送进行初始化,需要将复位脚(RST)置为高电平且将8位地址和命令信息装入移位寄存器。数据在时钟(SCLK)的上升沿串行输入,前8位指定访问地址。命令字装入移位寄存器后,在之后的时钟周期,读操作时输出数据,写操作时输入数据。时钟脉冲的个数在单字节方式下为8+8(8位地址+8位数据),在多字节方式下最多可达8+248。
2.5.4
控制字节及寄存器
DS1302的一次数据传送是从发送控制字节开始的。控制字节的最高有效位(位7)必须是逻辑1,如果该位为0,则无法把数据写入到DS1302中;位6表示要读写的数据类型,为0表示存取日历时钟数据,为1表示存取
RAM数据;位5至位1指示要操作单元的地址;最低有效位(位
0)表示命令类型,为0表示要进行写操作,为
1
表示要进行读操作。控制字节总是从最低位开始输出。其控制字节格式如图2-7所示。
图2-7
控制字节格式
2.5.5
时钟/日历存储区(时分秒)
2.5.6
数据的传送
向
DS1302
写入数据时,数据在控制字节输入后的下一个
SCLK周期的上升沿被写入,多余的
SCLK将被忽略。数据写入时从低位(位0)开始;同样,从DS1302
读取数据时,数据在紧跟控制字节后的下一个
SCLK的下降沿读出,读出数据时也是从低位(0位)到高位(7
位),只要RST保持高电平,额外的
SCLK将导致数据字节的持续读出,这个特性用于实现该芯片的突发读模式。
对DS1302
的每一次读写需
16个时钟脉冲,前
8
个脉冲输入操作地址和读写命令,后8个脉冲写入或读出数据。数据传送时序如图2-8。
图2-8
数据读写时序图
2.6
DS18B20介绍及基本工作方式说明
DS18B20总体介绍:
DS18B20温度传感器是美国达拉斯(DALLAS)半导体公司推出的应用单总线技术的数字温度传感器。该器件将半导体温敏器件、A/D转换器、存储器等做在一个很小的集成电路芯片上。本设计中温度传感器之所以选择单线数字器件DS18B20,是在经过多方面比较和考虑后决定的,主要有以下几方面的原因:
(1)系统的特性:测温范围为-55℃~+128℃
,测温精度为士0.5℃;温度转换精度9~12位可变,能够直接将温度转换值以16位二进制数码的方式串行输出;12位精度转换的最大时间为750ms;可以通过数据线供电,具有超低功耗工作方式。
(2)系统成本:由于计算机技术和微电子技术的发展,新型大规模集成电路功能越来越强大,体积越来越小,而价格也越来越低。一支DS18B20的体积与普通三极管相差无几,价格只有十元人民币左右。
(3)系统复杂度:由于DS18B20是单总线器件,微处理器与其接口时仅需占用1个I/O端口且一条总线上可以挂接几十个DS18B20,测温时无需任何外部元件,因此,与模拟传感器相比,可以大大减少接线的数量,降低系统的复杂度,减少工程的施工量。
(4)系统的调试和维护:由于引线的减少,使得系统接口大为简化,给系统的调试.
DS18B20的复位时序图:
由上位机拉低总线480-960us的时间然后拉高总线,等待15-60us的时间,如果在总线上有DS18B20这个器件,并且将总线拉低60-240us的话,就证明该器件复位成功,已经准备好发送或接受数据了。
图2-9复位时序图
DS18B20的写时序图:
DS18B20的写时序分为写0时序和写1时序两个过程。DS18B20写0时序和写1时序的要求不同,当要写0时序是,单总线要被拉低至少60us,保证DS18B20能够在15us~45us之间能够正确地采样I/O总线上的低电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。
图2-10写时序图
DS18B20的读时序图:
DS18B20的读时序分为读0时序和读1时序两个过程。对于DS18B20的读时序是从主机把单总线拉低之后,在15秒之内就得释放单总线,让DS18B20把数据传输到单总线上。DS18B20完成一个读时序过程,至少需要60us。
三、系统硬件电路设计
3.1
proteus仿真接线图
全图除了分块电路之外,没有明线,看起来简洁明了,并且各个电路的区域不同,也便于查找。将键盘、数码管、二极管电路整合在一块,对系统的调试可以方便很多。
3.2分块硬件电路射界
3.2.1
ds1302时钟电路
通过P1.3口将时钟芯片内部RAM的内容读到单片机内部进而进行显示,内部RAM的内容即为当前日期
3.2.2
ds18b20温度传感器电路
通过P1.0口将温度传感器内部RAM的温度读入单片机,进而进行显示。
3.2.3
8279电路
经测验,将SHIFT和CTRL/STB口接地,可以使键盘的前两位为1,进而可以方便的读出键盘位置,P0口的数据通过图中蓝色总线传入8279芯片。P2.0口通过输出0或1控制8279用法。
3.2.4
二极管电路
第一部分二极管直接与单片机中P1.4-P1.7相连,显示温度的温馨提示。第二部分的二极管电路通过38译码器与单片机中P3.0、P3.1、P3.4相连,控制灯的开关,进行节日显示。
3.2.5
数码管显示电路
段选部分直接与8279芯片中OUTA和OUTB相连,用于控制每一位的显示,而片选部分则通过38译码器与8279中SL0-SL2相连,用于控制位的选择。
3.2.6
4*5键盘电路
键盘部分的行部分通过38译码器与8279中SL0-SL2相连,用于返回行值,键盘列部分直接与RL0-RL4相连,用于返回列值。
3.2.7
闹钟及音乐播放电路
第一部分为闹钟电路,通过控制P3.2口低电平与高电平的交替输出,进行闹钟响铃和整点报时功能。第二部分为音乐电路,通过控制P3.5口高低电平输出的频率产生不同节拍的音符,进而构成音乐。
5、
软件设计及实现过程
4.1程序设计简述
主程序先进行8279初始化,输出HELLO及开机音乐后,再进行整个系统的初始化。进入如图所示的程序循环过程,并在循环过程中不断判断是否满足相应的判断语句,进行闹钟的响铃和节日以及温度的提示,并且等待中断、进行键盘扫描。当检测到键值时,进入中断,根据键值判断所需要进行的功能,转到相应的子函数中进行。
4.2系统程序流程图设计
主函数程序设计流程图
显示子函数流程图
五、系统的调试过程
5.1程序性问题及解决
1.
由于word
的编写功能较为强大,开始使用word进行编写,然后复制如keil进行调试,由于使用word的原因,导致程序中出现了很多中问字符的空格,进行了仔细查找将空格抹去之后,方可正常运行。
2.
用proteus话电路,进行程序调试时,发现提示硬件错误,出现器件重名,导致无法运行。
5.2调试过程出现问题及解决
1.
数码管输出错误,与所要输出的相反。分析原因:程序中数码管输出部分顺序不对。改进方法:为了防止对程序进行大改,将命令字改为左端输入。
2.
闹钟时明明输出高电平,但喇叭并不响。分析原因:上网查询之后发现所用喇叭需要震荡,及高低电平交替输出才行。改进方法:在程序中加入void
di()子函数,使用时进行引用。
3.
对网上找的歌曲代码进行截取时发现截取后的蜂鸣器乱响。分析原因:歌曲代码中没两位表示一个音符,截取过程中将两位拆开,出现混乱,改进方法:以两位字符为单位进行截取。
4.
节日提示的二极管不亮。分析原因:运行时,发现二极管相应的端口显示低电平,故程序没有问题,最终发现马虎大意导致二极管接反。改进方法:反接二极管。
5.
温度显示错误,正值时正常显示,负值时显示零。分析原因:温度读取子函数有错误,但无论怎么修改,扔无法解决上述问题。将0;i--);
}
//****************开机唱歌函数**********************//
void
Time0_Init()
{
TMOD
=
0x10;
IE
=
0x88;
TH1
=
0xDC;
TL1
=
0x00;
}
void
Time0_Int()
interrupt
3
{
TH1
=
0xDC;
TL1
=
0x00;
Count++;
//长度加1
}
void
Delay_xMs(uint
x)
{
uint
i,j;
for(i=0;
i0;i--)
{
DQ
=
0;
//
给脉冲信号
datt>>=1;
DQ
=
1;
//
给脉冲信号
if(DQ)
datt|=0x80;
yanshi(5);
}
return(datt);
}
void
Write1(unsigned
char
datt)//写字节
{
unsigned
char
i=0;
for
(i=8;
i>0;
i--)
{
DQ
=
0;
DQ
=
datt
yanshi(5);
DQ
=
1;
datt>>=1;
}
}
void
ReadTemperature()
{
unsigned
char
tl=0,th=0,i=100;
while(i--)
{
Init();
Write1(0xCC);
//
跳过读序号列号的操作
Write1(0x44);
//
启动温度转换
yanshi(100);
Init();
Write1(0xCC);
//跳过读序号列号的操作
Write1(0xBE);
//读取温度寄存器等
yanshi(100);
tl=Read();
//读取温度值低位
th=Read();
//读取温度值高位
temp=th>=4;
//右移4位,相当于乘0.0625,将温度化为十进制
else
{
temp=~temp;
temp+=1;
}//经测试,温度零下时,直接在此函数中除16影响显示,故在显示函数中除16
temp1=temp%100;//用于温度显示
}
}
void
wendutishi()
{
if(t=15
LED1=0;
LED3=0;
LED2=0;
}
}
else
{
LED1=1;
LED2=0;
LED3=0;
LED4=0;
}
}
/***************节日提示*************/
void
jieritishi()
{
if(ctime.month==1D=0;C=0;}
else
if(ctime.month==5D=0;C=0;}
else
if(ctime.month==6D=1;C=0;}
else
if(ctime.month==7D=1;C=0;}
else
if(ctime.month==8D=0;C=1;}
else
if(ctime.month==9D=0;C=1;}
else
if(ctime.month==10D=1;C=1;}
}
/**********闹钟响铃函数*************/
void
di()
{
uchar
i
;
for(i=0;i0;
i--)
{
di();
delay(140);
}
}
/*********时钟函数************/
void
write(uchar
addr,uchar
dat)
{
uchar
i
;
RST
=
0
;
SCK
=
0
;
RST
=
1
;
for(i=0;i>=1
;
SCK
=
1
;
}
for(i=0;i>=
1
;
SCK
=
1
;
}
RST
=
0
;
}
uchar
read(uchar
addr)
{
uchar
i,dat
;
RST
=
0
;
SCK
=
0
;
RST
=
1
;
for(i=0;i>=1
;
SCK
=
1
;
}
for(i=0;i>=1
;
if(SDA)
dat|=0x80
;
SCK=1
;
}
RST=0
;
dat=(dat/16*10)+(dat
return
dat
;
}
void
read_time()
{
ctime.second
=
read(0x81);
ctime.minute
=
read(0x83);