51单片机课程设计作业(共12篇)
1.51单片机课程设计作业 篇一
单片机课程设计
俄罗斯方块
学院:工程技术学院
专业:08级电子科学与技术
小组成员:
何冠羲,马志祥,李洋,张世刚,叶彪,郑先安,洪之
目录
摘要
引言
1.程序整体思路
2.8X8LED模块显示原理 3.硬件电路仿真图 4.图形显示 5.消层算法 6.旋转算法 7.实物焊接
8.心得体会
附录 程序代码
摘 要
记得在很小的时候,有一种掌上游戏机,里面有一款游戏叫做俄罗斯方块,那时的我们只是简单的按照游戏规则进行“堆积木”,而其中的原理却很少有人去思考,毕竟当时的我们都还很年幼。
基于单片机课程设计的机会,我们这个小组将使用51单片机和8x8led的组合,来实现比较简单的俄罗斯方块设计。
此次设计初期是在keil和proteus联合仿真中进行,编程语言为51汇编,后期是进行实物焊接。
论文描述了俄罗斯方块的主要功能函数的实现,算法分析和实物焊接过程中遇到的问题。
关键词:俄罗斯方块;算法; 8X8led;
引 言
游戏是人们活动中一项非常重要的内容,有人认为如果哪一天人类对所有的游戏都失去兴趣,恐怕世界的末日就要到了。电脑对游戏的贡献有目共睹,现在摸过电脑的人很少有没玩过电脑游戏的,喜欢游戏的人也很少有不玩电脑的。
俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事。这款游戏最初是由苏联的游戏制作人Alex Pajitnov制作的,它看似简单但却变化无穷,令人上瘾。相信大多数用户都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。究其历史,俄罗斯方块最早还是出现在PC机上,而我国的用户都是通过红白机了解、喜欢上它的。现在联众又将重新掀起这股让人沉迷的俄罗斯方块风潮。对一般用户来说,它的规则简单,容易上手,且游戏过程变化无穷,而在“联众俄罗斯方块”中,更有一些联众网络游戏所独有的魅力――有单机作战与两人在线对战两种模式,用户可任选一种进行游戏。网络模式还增加了积分制,使用户既能感受到游戏中的乐趣,也给用户提供了一个展现自己高超技艺的场所。
俄罗斯方块游戏可以说是随计算机的发展而发展,并不断推陈出新演变出各种类似游戏, 深受广大玩家喜爱。这个游戏有的简单, 有的复杂, 但其根本原理是一样的都是对运动的方块进行组合, 来训练玩家的反应能力。本文利用单片机进行俄罗斯方块设计,采用51汇编语言进行编程,基于汇编语言的原因是在编写程序的过程中,对于程序的执行会有一个比较直观的表现。
1.程序整体思路
单片机上的程序设计一般是一个大循环结构,对于俄罗斯方块的程序设计,首先产生一个伪随机数,其范围是0-6,然后程序根据此数值所对应的图形模块装入ram的固定区域内,紧接着将此图像写入led所对应的显示缓冲区中,显示程序将缓冲区内的内容显示在led上,如果没有控制键按下,图形将自动向下移动。如果有键按下,程序将根据按下的键来改变图形存储区的值,同时程序将判断图形是否已到达边界,当图形最上层到达显示区顶部,则游戏结束,此时将清楚显示缓冲的内容,游戏重新开始。2.8x8led显示原理
8x8led显示屏的原理图如下
由于人眼的视觉暂留现象,通过逐行扫描显示的方式来显示要显示的内容,当每一行扫描的时间很小时人眼观察的将是一幅完整的图像。
3. 硬件电路仿真图
.4.图形显示
8x8led一共有64个led,可以从下至上一次对其编号,对于显示类的基本操作是任意点亮一个点,熄灭一个点,任意点亮n(0 我们将ram中从21h单元到28h单元作为led的显示缓冲区,这里面的每一位对应led的一个点,led将实时显示缓冲区的内容,也就是当此缓冲区内容一改变,led上看到的也会做出相应的改变。同时在俄罗斯方块中那些方块被存放在一个类似于一维的数组之中,每一个方块对应四个小方块,根据伪随机数将这四个小方块对应的值装入ram固定的区域内。如果要显示方块只需将这些方块所对应的点写入缓冲区。5.消层算法 设置循环变量数R2=8,即总共至少要扫描8次,每一次循环过程中检测此行是否已满,也就是检测这一行所对应的存储单元是否全为一,如果全为一则将消去此行,即将此行对应的ram清零。同时将此行上面ram的内容按每列依次下移,下移完之后重新将R2=0,又从第一行开始检测。此行不全为零时只需将R2=R2+1。直到R2=9消层过程结束。6.旋转算法 首先要确定一个旋转中心,假如旋转中心的编号是34,将34除以8,商是4存入R1余数是2存入R2,及时用商和余数建立坐标系。此时若以此为旋转中心的图形需要旋转,则将每一个小方块对应编号除以8,商减去R1,余数减去R2,而每一个方块一次将旋转90度,所以有公式x1,y1,x2,y2 x2=-y1,y2= x1 其中x1,y1为旋转之前的坐标,x2,y2为旋转之后的坐标。旋转完之后将x2加上R1将y2加上R2,然后将x2乘以8再加上y2。执行四次此过程旋转结束。7.实物焊接 器件:stc51单片机一块,8x8led显示模块一块,电阻10k10个,开关5个,与门,12m晶振一个,电容3个。 首先按照目的进行进行元器件布局,然后按照电路图里的导线的连接次序将元器件焊在电路板上,焊好之后进行调试。8.心得体会 写程序的过程中,首先应该把程序思路理清,然后再写代码,否则写到一半感觉行不通时是很令人心烦的。还有就是焊接是一个技术活,因为在电子工艺实习之后大家便没有碰过电烙铁,所以焊的过程还是很辛苦的。 附录:程序代码 ORG 0000H AJMP START ORG 0003H AJMP INTERRUPT AA EQU 10000000B BB EQU 11111111B HANG EQU 32H LIE EQU 33H COUNT EQU 34H REMOVEROW EQU 35H STEPS EQU 36H XUNHUAN EQU 37H BIANLIANG EQU 38H GRAPHRAM1 EQU 39H GRAPHRAM2 EQU 40H GRAPHRAM3 EQU 41H GRAPHRAM4 EQU 42H XXX EQU 43H YYY EQU 44H KEY EQU 45H LEDHEAD EQU 21H TEST BIT 100 BITS BIT 99 RIGHT BIT 98 LEFT BIT 97 DOWN BIT 96 HARD BIT 95 TURN BIT 94 KEYDOWN BIT 93 TESTING BIT 92 BOTTOM BIT 91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;程序由此处开始执行;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START: MOV TCON,#00000001B;;;;;;;;;;;;;设置外部中断0响应方式为下降沿触发 SETB EX0 SETB EA MOV SP,#60H;;;;;;;;;;;;;;;;;;;;;将堆栈指针SP设置在RAM的高地址处 MOV R7,#6;;;;;;;;;;;;;;;;;;;;;;R7作为存放0-6这7个随机数的变量 MOV P0,#11111111B;;;;;;;;;;;;;;;;;;;;;;将P0口最为输入口 LCALL WRITEGRAPHTORAM CLR TESTING GAMELOOP:;CLR EA LCALL SHOWGRAPH MOV R6,#30 TIMING: LCALL SHOWLEDRAM LCALL DJNZ LCALL JNB ABCD: MOV CJNE LCALL LCALL JMP NEXT1:;JB JMP KEY1: CLR CLR MOV CJNE LCALL JB LCALL LCALL LCALL KEY2: CJNE LCALL JB LCALL LCALL LCALL KEY3: CJNE ;LCALL ;JNB DELAY R6,TIMING DOWNTEST DOWN,NEXT1 A,28H A,#0,GAMEOVER REMOVEBLOCK WRITEGRAPHTORAM GAMELOOP KEYDOWN,KEY1 KEY4 TESTING KEYDOWN A,KEY A,#1,KEY2;1-LEFT LEFTTEST LEFT,KEY4 CLEANGRAPH MOVELEFT GAMELOOP A,#2,KEY3;2-RIGHT RIGHTTEST RIGHT,KEY4 CLEANGRAPH MOVERIGHT GAMELOOP A,#4,KEY4;4-ROTATE ROTATIONTEST TURN,KEY4 LCALL CLEANGRAPH LCALL ROTATION JMP GAMELOOP KEY4: CJNE A,#8,KEY5 SWEAT: LCALL DOWNTEST JB DOWN,GAMELOOP LCALL CLEANGRAPH LCALL MOVEDOWN JMP SWEAT KEY5: LCALL CLEANGRAPH LCALL MOVEDOWN INC R7 CJNE R7,#7,NEXT5 MOV R7,#0 NEXT5: JMP GAMELOOP GAMEOVER: MOV R0,#8 MOV R1,#LEDHEAD CLEAR: LCALL CLEANGRAPH MOV @R1,#0 INC R1 DJNZ R0,CLEAR MOV R0,#4 MOV R1,#GRAPHRAM1 ASDF: MOV A,@R1 ADD A,#16 MOV @R1,A INC R1 DJNZ R0,ASDF JMP GAMELOOP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;测试图形是否能向下移动;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;DOWNTEST: PUSH 0 PUSH PUSH PUSH PUSH B PUSH ACC MOV R2,#4 MOV R0,#GRAPHRAM1 DOWN0: MOV A,@R0 SUBB A,#8 MOV B,A MOV R3,#4 CLR C MOV R1,#GRAPHRAM1 DOWN2: CLR C SUBB A,@R1 JZ DOWN1 INC R1 MOV A,B DJNZ R3,DOWN2 LCALL TESTBIT JB BITS,DOWN3 DOWN1: INC R0 DJNZ R2,DOWN0 CLR DOWN JMP HOPE DOWN3: SETB DOWN;DOWN WEI YI BIAO SHI BU NENG WANG CPL P3.4 JMP DOWN4 HOPE: MOV R2,#4 MOV R0,#GRAPHRAM1 YOUQIANG2: MOV R3,#1 CCC2: MOV A,R3 MOV B,A CLR C SUBB A,@R0 JNZ CCC1 SETB DOWN SETB BOTTOM JMP DOWN4 XIA YI DONG CCC1: MOV A,B INC R3 CJNE R3,#9,CCC2 INC R0 DJNZ R2,YOUQIANG2 DOWN4: POP ACC POP B POP POP POP POP 0 RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;外部中断0中断处理程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;INTERRUPT: PUSH 0 PUSH PUSH ACC INC R7 CJNE R7,#7,INTT MOV R7,#0 INTT: SETB TESTING SETB KEYDOWN MOV A,P0 CPL A MOV KEY,A POP ACC POP POP 0 RETI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;测试能否旋转 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;向下移动 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOVEDOWN: PUSH 0 PUSH PUSH ACC MOV R0,#GRAPHRAM1 MOV R1,#4 MOVE1: MOV A,@R0 CLR C SUBB A,#8 MOV @R0,A INC R0 DJNZ R1,MOVE1 POP ACC POP POP 0 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;向左移动 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOVELEFT: PUSH 0 PUSH PUSH ACC MOV R0,#GRAPHRAM1 MOV R1,#4 MOVE2: MOV A,@R0 CLR C SUBB A,#1 MOV @R0,A INC R0 DJNZ R1,MOVE2 POP ACC POP POP 0 RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;向右移动 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MOVERIGHT: PUSH 0 PUSH PUSH ACC MOV R0,#GRAPHRAM1 MOV R1,#4 MOVE3: MOV A,@R0 CLR C INC A MOV @R0,A INC R0 DJNZ R1,MOVE3 POP ACC POP POP 0 RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;将图形写入RAM缓存中;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WRITEGRAPHTORAM: PUSH ACC PUSH B PUSH 0 PUSH PUSH PUSH MOV R1,#4 MOV A,R7 MOV B,#4 MUL AB MOV R2,A MOV R0,#GRAPHRAM1 MOV DPTR,#GRAPH WRITEGRAPH: MOV A,R2 MOVC A,@A+DPTR;SUBB A,#16 MOV @R0,A INC R2 INC R0 DJNZ R1,WRITEGRAPH POP POP POP POP 0 POP B POP ACC RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;测试某一个二进制位是否为1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;TESTBIT: PUSH 0 PUSH PUSH B PUSH ACC MOV B,#8 DIV AB MOV R0,A MOV A,B CJNE A,#0,TEST3 MOV A,R0 DEC A JMP TEST4 TEST3: MOV A,R0 TEST4: MOV DPTR,#TAB1 MOV R1,#LEDHEAD ADD A,R1 MOV R1,A MOV A,B MOVC A,@A+DPTR ANL A,@R1 CJNE A,#0,TEST1 CLR BITS JMP TEST2 TEST1: SETB BITS TEST2: POP ACC POP B POP POP 0 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;测试图形是否能向左移动;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LEFTTEST: PUSH 0 PUSH PUSH PUSH PUSH B PUSH ACC MOV R2,#4 MOV R0,#GRAPHRAM1 LEFT0: MOV A,@R0 CLR C SUBB A,#1 MOV B,A MOV R3,#4;CLR C MOV R1,#GRAPHRAM1 LEFT2: CLR C SUBB A,@R1 JZ LEFT1 INC R1 MOV A,B DJNZ R3,LEFT2 LCALL TESTBIT JB BITS,LEFT3 LEFT1: INC R0 DJNZ R2,LEFT0 CLR LEFT JMP LEFT4 LEFT3: SETB LEFT;DOWN WEI YI BIAO SHI BU NENG WANG CPL P3.4 JMP LEFT5 LEFT4: MOV R2,#4 MOV R0,#GRAPHRAM1 YOUQIANG: MOV R3,#9 MOV A,#1 HHH2: MOV B,A CLR C XIA YI DONG SUBB A,@R0 JNZ HHH1 SETB LEFT JMP LEFT5 HHH1: MOV A,B ADD A,#8 DJNZ R3,HHH2 INC R0 DJNZ R2,YOUQIANG LEFT5: POP ACC POP B POP POP POP POP 0 RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;测试图形是否能向右移动;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;RIGHTTEST: PUSH 0 PUSH PUSH PUSH PUSH B PUSH ACC MOV R2,#4 MOV R0,#GRAPHRAM1 RIGHT0: MOV A,@R0 ADD A,#1 MOV B,A MOV R3,#4;CLR C MOV R1,#GRAPHRAM1 RIGHT2: SUBB A,@R1 JZ RIGHT1 INC R1 MOV A,B DJNZ R3,RIGHT2 LCALL TESTBIT JB BITS,RIGHT3 RIGHT1: INC R0 DJNZ R2,RIGHT0 CLR RIGHT JMP RIGHT4 RIGHT3: SETB RIGHT;DOWN WEI YI BIAO SHI BU NENG WANG CPL P3.4 JMP RIGHT5 RIGHT4: MOV R2,#4 MOV R0,#GRAPHRAM1 YOUQIANG1: MOV R3,#8 MOV A,#8 III2: MOV B,A CLR C SUBB A,@R0 JNZ III1 SETB RIGHT JMP RIGHT5 III1: MOV A,B ADD A,#8 DJNZ R3,III2 INC R0 DJNZ R2,YOUQIANG1 RIGHT5: POP ACC POP B POP POP POP POP 0 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;图形旋转 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XIA YI DONG ROTATION: PUSH 0 PUSH PUSH PUSH PUSH B PUSH ACC MOV A,GRAPHRAM1;A=50 MOV B,#8 DIV AB ;A=6 B= 2 MOV HANG,A ;HANG = 6 MOV LIE,B ;LIE = 2 MOV R3,#4 MOV R0,#GRAPHRAM1 ROTATESTART: MOV A,@R0 MOV B,#8 DIV AB CLR C SUBB A,HANG MOV R1,A MOV A,B CLR C SUBB A,LIE MOV R2,A;;;;;;;;;;;;;;;;;;X2=-Y1 Y2=X1 MOV A,#0 CLR C SUBB A,R2;-Y1 MOV B,R1;X1 MOV R1,A;X2=-Y1 MOV R2,B;Y2=X1 MOV A,R1 ADD A,HANG MOV R1,A MOV A,R2 ADD A,LIE MOV R2,A MOV A,R1 MOV B,#8 MUL AB ADD A,R2 MOV @R0,A INC R0 DJNZ R3,ROTATESTART POP ACC POP B POP POP POP POP 0 RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;显示LEDRAM中的内容;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SHOWLEDRAM: PUSH 0 PUSH PUSH B PUSH ACC MOV R0,#LEDHEAD MOV R1,#8 MOV A,#AA SHOW1: MOV P1,A MOV P2,@R0 LCALL DELAY INC R0 RL A DJNZ R1,SHOW1 POP ACC POP B POP POP 0 RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;软件延时 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;DELAY: PUSH PUSH MOV R1,#5 FQFQ: MOV R2,#200 FWFW: DJNZ R2,FWFW DJNZ R1,FQFQ POP POP RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;清楚图形在LEDRAM中的内容;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CLEANGRAPH: PUSH ACC PUSH MOV A,#GRAPHRAM1 MOV XUNHUAN,#4 MOV R1,A DADA1: MOV A,@R1;SUBB A,#16 LCALL WRITEPOINT0 INC R1 DJNZ XUNHUAN,DADA1 POP POP ACC RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;显示图形在LEDRAM中的内容;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SHOWGRAPH: PUSH ACC PUSH MOV A,#GRAPHRAM1 MOV XUNHUAN,#4 MOV R1,A DADA2: MOV A,@R1;SUBB A,#16 LCALL WRITEPOINT1 INC R1 DJNZ XUNHUAN,DADA2 POP POP ACC RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;消除已经填满的行 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;REMOVEBLOCK: PUSH 0 PUSH PUSH B PUSH ACC REMOVESTART: MOV R0,#1 MOV R1,#LEDHEAD REMOVE2: MOV A,@R1 CJNE A,#11111111B,REMOVE1 MOV @R1,#00000000B MOV REMOVEROW,R0 LCALL DOWNBLOCK JMP REMOVESTART REMOVE1: INC R0 INC R1 MOV A,R0 CJNE A,#9,REMOVE2 POP ACC POP B POP POP 0 RET DOWNBLOCK: PUSH 0 PUSH PUSH B PUSH ACC MOV R0,#1 DOWN11: MOV A,REMOVEROW MOV B,#8 MUL AB ADD A,R0 LCALL DOWNSTEP LCALL JUSTMOVE INC R0 MOV A,R0 CJNE A,#9,DOWN11 POP ACC POP B POP POP 0 RET DOWNSTEP: PUSH 0 PUSH PUSH B PUSH ACC MOV R0,#0 MOV R1,REMOVEROW STEP2: CLR C SUBB A,#8 LCALL TESTBIT JB BITS,STEP1 INC R0 DJNZ R1,STEP2 STEP1: MOV STEPS,R0 POP ACC POP B POP POP 0 RET JUSTMOVE: PUSH 0 PUSH PUSH PUSH B PUSH ACC MOV R0,A MOV A,STEPS MOV B,#8 MUL AB MOV B,A MOV A,R0 CLR C SUBB A,B MOV R1,A MOV R2,REMOVEROW MOV A,#8 CLR C SUBB A,R2 MOV JUST3: MOV LCALL JB MOV LCALL JMP JUST1: MOV LCALL JUST2: MOV ADD MOV MOV ADD MOV DJNZ MOV DDD: MOV LCALL MOV ADD MOV DJNZ JUSTEND: POP POP POP POP POP RET R2,A A,R0 TESTBIT BITS,JUST1 A,R1 WRITEPOINT0 JUST2 A,R1 WRITEPOINT1 A,R0 A,#8 R0,A A,R1 A,#8 R1,A R2,JUST3 R2,REMOVEROW A,R1 WRITEPOINT0 A,R1 A,#8 R1,A R2,DDD ACC B 2 1 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;将某个二进制位写1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WRITEPOINT1: PUSH 0 PUSH PUSH PUSH PUSH B PUSH PUSH PUSH CLR MOV SUBB JNC MOV MOV MOV DIV MOV MOV CJNE MOV DEC JMP WRITE11: MOV WRITE12: ADD MOV MOV MOV MOV MOV MOVC ORL MOV END1: POP POP POP POP POP ACC DPH DPL C R0,A A,#65 END1 A,R0 R1,#LEDHEAD B,#8 AB R0,A A,B A,#0,WRITE11 A,R0 A WRITE12 A,R0 A,R1 R1,A A,@R1 R2,A DPTR,#TAB1 A,B A,@A+DPTR A,R2 @R1,A DPL DPH ACC B 3 POP POP POP 0 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;将某个二进制位写0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WRITEPOINT0: PUSH 0 PUSH PUSH PUSH B PUSH ACC PUSH DPH PUSH DPL MOV R0,A CLR C SUBB A,#65 JNC END2 MOV A,R0 MOV R1,#LEDHEAD MOV B,#8 DIV AB MOV R0,A MOV A,B CJNE A,#0,WRITE01 MOV A,R0 DEC A JMP WRITE02 WRITE01: MOV A,R0 WRITE02: ADD A,R1 MOV R1,A MOV A,@R1 MOV R2,A MOV DPTR,#TAB2 MOV A,B MOVC A,@A+DPTR ANL A,R2 MOV @R1,A END2: POP DPL POP DPH POP ACC POP B POP POP POP 0 RET GRAPH: DB 69,60,61,62,69,68,61,62,69,70,60,61,69,70,61,62,69,77,61,62,69,77,61,60,69,69,61,77 TAB1: DB 00000001B,10000000B,01000000B,00100000B,00010000B,00001000B,00000100B,00000010B TAB2: DB 11111110B,01111111B,10111111B,11011111B,11101111B,11110111B,11111011B,11111101B END 关键词:单片机,温度传感器,模/数转换器 单片机具有体积小、功能强、成本低、应用面广等优点, 可以说, 智能控制与自动控制的核心就是单片机。目前, 一个学习与应用单片机的高潮在全社会大规模地兴起。学习单片机的最有效方法就是理论与实践并重, 用80C51单片机自制了一个温度控制系统, 重点介绍了该系统的硬件结构及编程方法。 1 单片机温度控制系统的组成及工作原理 在工业生产和日常生活中, 对温度控制系统的要求, 主要是保证温度在一定温度范围内变化, 稳定性好, 不振荡, 对系统的快速性要求不高。以下简单分析了单片机温度控制系统设计过程及实现方法。现场温度经温度传感器采样后变换为模拟电压信号, 经低通滤波滤掉干扰信号后送放大器, 信号放大后送模/数转换器转换为数字信号送单片机, 单片机根据输入的温度控制范围通过继电器控制加热设备完成温度的控制。本系统的测温范围为0℃~99℃, 启动单片机温度控制系统后首先按下第一个按键开始最低温度的设置, 这时数码管显示温度数值, 每隔一秒温度数值增加一度, 当满足用户温度设置最低值时再按一下第一个按键完成最低温度的设置, 依次类推通过第二个按键完成最高温度的设置。然后温度检测系统根据用户设定的温度范围完成一定范围的温度控制。 2 温度检测的设计 系统测温采用AD590温度传感器, AD590是美国模拟器件公司生产的单片集成两端感温电流源。它的主要特性如下: 2.1 流过器件的电流 (m A) 等于器件所处环境的热力学温度 (开尔文) 度数;即式中:Ir-流过器件 (AD590) 的电流, 单位为m A;T-热力学温度, 单位为K。 2.2 AD590的测温范围为-55℃~+150℃; 2.3 AD590的电源电压范围为4V~30V; 2.4 输出电阻为710MW; 2.5 精度高。 AD590温度传感器输出信号经放大电路放大10倍, 再送入模/数转换器ADC0804, 转换后送单片机。根据AD590温度传感器特性以及放大10倍后的电压值与现场温度的比较发现, 实际温度转换后送入单片机的值与按键输入数值之间有一定的差值, 模/数转换器送入单片机的数值是按键输入值得2.5倍。由于单片机不能进行小数乘法运算, 所以先对按键输入进行乘5, 然后根据运算结果及程序状态字的状态再进行循环右移一位, 如果溢出标志位为低电平时直接对累加器进行一次带进位循环右移, 如果溢出标志位为高电平时, 先对进位标准位CY位置为高电平, 然后再进行一次带进位循环右移, 通过上述操作使按键输入的温度值与模/数转换器送入单片机的温度值相统一。 3 结论 给出了用单片机在0℃~99℃之间, 通过用户设置温度上限、下限值来实现一定范围内温度的控制;给出了温度控制系统的硬件连接电路以及软件程序, 此系统温度控制只是单片机广泛应用于各行各业中的一例, 相信通过大家的聪明才智和努力, 一定会使单片机的应用更加广泛化。 参考文献 [1]李广弟, 朱月秀, 王秀山.单片机基础[M].北京:北京航空航天大学出版社, 2001, 7. 关键词:51单片机 LCD12864 程序设计 0 引言 液晶显示器根据显示方式可分为:段位式、字符式和点阵式LCD,其中段位式与字符式只能显示数字与字符。而点阵式LCD不仅能显示数字与字符,还能显示各种图形、曲线及汉字等。本文研究的TG12864B是能显示曲线、图形及汉字的点阵式LCD。 1 TG12864介绍 TG12864是一款无字库的图形点阵显示器,其屏幕由64行×128列点阵组成,可以显示16点阵的4行×8列(32个)汉字、8点阵的8行×8列(64个)字母和128×64全屏幕点阵图形。 1.1 TG12864B内部功能器件介绍 在使用TG12864B前须了解其相关功能器件,如下所示:①指令寄存器(IR):用于寄存指令码。②数据寄存器(DR):用于寄存数据的。DR和显示数据存储器DDRAM(见表1)之间的数据传输是模块内部自动执行的。③显示数据RAM(DDRAM):DDRAM是存储图形显示数据的。数据为1表示显示选择,数据为0表示显示非选择。DDRAM与地址和显示位置的关系见DDRAM地址表。④XY地址计数器。XY地址计数器是一个9位计数器。高3位是X地址计数器,低6位为Y地址计数器,XY地址计数器实际上是作为DDRAM的地址指针,X地址计数器为DDRAM的页指针,Y地址计数器为DDRAM的Y地址指针。X地址计数器是没有记数功能的,只能用指令设置。Y地址计数器具有循环记数功能,各显示数据写入后,Y地址自动加1,Y地址指针从0到63。 1.2 TG12864的控制指令 ①开关显示:开显示,指令码为0X3F;关显示,指令码为0X3E。②设置Y地址:0x40~0x4f,其中0x40为第0列列地址,0x4f为第63列列地址。③设置X页地址:模块有64行,其中8行为一页,即有8页,A2~A0表示0~7页:如,当A2~A0为000时表示第0页,为111是表示第7页。页地址分别是0XB8~0XBF。④显示开始线:该指令中A5~A0为显示起始行的地址,它规定了显示屏起始行所对应的显示存储器的行地址。通过修改显示其实行寄存器的内容,可以实现显示屏向上或向下滚动。⑤读状态:BF:判断忙信号标志位。BF=1表示液晶屏正在处理MCU发过来的指令或者数据,此时接口电路被挂起,不能接受除读操作以外的任何操作,BF=0表示液晶屏接口控制电路处于空闲状态,可以接受外部数据和指令。 2 电路设计 图1 TG12864显示线路图 图1为AT89S51控制12864LCD线路图,图中DB0~DB7为TG12864的数据线,单片机通过该端口给TG12864写命令或读写数据;RS为寄存器与显示内存操作选择管脚,单片机通过P3.7脚与之连接,当RS脚为高电平时,对液晶显示器的数据寄存器进行读或写操作;当RS脚为低电平时,对命令寄存器进行操作;RW为读写控制脚,与单片机P3.6脚连接,当RW脚为高电平时,准备对液晶显示器执行读操作,低电平时执行写操作;E脚为使能端,与P3.5脚连接,下降沿有效;CS1为高电平是选择芯片(右半屏)信号,CS2为高电平时选择芯片(左半屏)信号;RST复位脚,低电平复位。 3 LCD12864的驱动程序设计 LCD12864驱动程序的编程要想让LCD12864显示出需要的内容,就得严格按照LCD12864的工作时序来进行编程。驱动LCD12864显示程序含有以下几个子程序: sbit di=P3^7;//高电平写数据,低电平写命令 sbit rw=P3^6;//高电平读操作,低电平写操作 sbit e=P3^5;//读写使能端,下降沿有效 sbit cs1=P3^4;//定义P3.4为左半屏片选信号 sbit cs2=P3^3;//定义P3.3为右半屏片选信号 sbit rst=P3^2;//TG12864复位信号 sbit bf=P2^7;//检测LCD忙引脚 sbit res=P2^4;//检测是否处于复位状态,高电平处于复位,低电平正常。 define dataport P0 //定义P0口为LCD数据总线,用于传输指令命令和显示数据。 3.1 忙检测子程序 void check_busy(void) { dataport=0xff; di=0; rw=1; delay(1); e=1; while(bf||res==1); e=0; } 3.2 写命令或数据子程序 void write( char dat_comm,char content) { Chk_busy; di=dat_comm;//dat_comm为高电平写数据,低电平写命令 rw=0; dataport=content; e=1; delay(1); e=0; } 3.3 初始化子程序 void init_lcd(void) { rst=0; delay(50); rst=1; cs1=1;cs2=1;/左右半屏选中 write(comm,0x3e);//关显示 write(comm,0x3f);//开显示 } 4 总结 本文对TG12864B用通俗易懂的语言进行了简单的介绍,并对TG12864B的驱动程序进行了简单的设计,使读者能初步了解12864LCD的简单应用。要想熟练的掌握TG12864B,还需要不断的实践,不断的摸索,熟悉编程语言,不断提高TG12864B的编程技巧,使程序得到最大程度的优化。 参考文献: [1]朱华光.浅议LCD1602的编程技巧[J].电脑知识与技术, 2010.6. [2]林嘉.基于89S52的LCD1602程序设计[J].电脑知识与技术,2012.8. [3]田开坤.基于LCD12864显示器的数字示波器设计[J].电子制作,2010.5. 一.课程设计背景 当今时代,是一个新技术层出不穷的时代。在电子领域,尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统正以前所未见的速度被单片机智能控制系统所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。过去习惯于传统电子领域的工程师、技术员正面临着全新的挑战,如不能在较短时间内学会单片机,势必会被时代所遗弃,只有勇敢地面对现实,挑战自我,加强学习,争取在较短的时间内将单片机技术融会贯通,才能跟上时代的步伐。 它所给人带来的方便也是不可否定的,它在一块芯片内集成了计算机的各种功能部件,构成一种单片式的微型计算机。20世纪80年代以来,国际上单片机的发展迅速,其产品之多令人目不暇接,单片机应用不断深入,新技术层出不穷。20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。本设计是由单片机实现的模拟计算器,它不仅能实现数据的加减乘除运算,而且还能使数据及其计算结果在数码管上显示出来,能够实现0-256的数字四则运算。本设计是用单片机AT89C51来控制,采用共阳极数码显示,软件部分是由C语言来编写的。设计任务 二、元器件清单及简介 89c51型芯片 一片 排阻 两个 晶振12MHZ 一个 电容22uf 两个 面包板 三个 导线 若干 三、设计原理及分析 根据功能和指标要求,本系统选用MCS 51 单片机为主控机。通过扩展必要的外围接口电路,实现对计算器的设计。具体设计考虑如下: ①由于要设计的是简单的计算器,可以进行四则运算,对数字的大小范围要求不高,故我们采用可以进行四位数字的运算,选用8 个LED 数码管显示数据和结果。 ②另外键盘包括数字键(0~9)、符号键(+、-、×、÷)、清除键和等号键,故只需要16 个按键即可。系统模块图: 2.1 输入模块: 键盘扫描计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会很简单,但是会占用大量的I/O 口资源,因此在很多情况下都不采用这种方式。为此,我们引入了矩阵键盘的应用,采用四条I/O 线作为行线,四条I/O 线作为列线组成键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4×4个。这种行列式键盘结构能有效地提高单片机系统中I/O 口的利用率。矩阵键盘的工作原理:计算器的键盘布局如图所示:一般有16 个键组成,在单片机中正好可以用一个P 口实现16 个按键功能,这种形式在单片机系统中也最常用。 以上键盘从上到下依次编号为1,2,3,4,D,C,B,A 1 由图 3 矩阵键盘内部电路图可以知道,当无按键闭合时,P10~P13 与P14~P17 之间开路。当有键闭合时,与闭合键相连的两条I/O 口线之间短路。判断有无按键按下的方法是:第一步,置列线P14~P17 为输入状态,从行线P10~P13 输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。第二步,行线轮流输出低电平,从列线P14~P17 读入数据,若有某一列为低电平,则对应行线上有键按下。综合一二两步的结果,可确定按键编号。但是键闭合一次只能进行一次键功能操作,因此须等到按键释放后,再进行键功能操作,否则按一次键,有可能会连续多次进行同样的键操作。2.2 运算模块:(单片机控制)AT89C51 单片机是在一块芯片中集成了CPU、RAM、ROM、定时器/计数器和多功能I/O等一台计算机所需要的基本功能部件。如果按功能划分,它由如下功能部件组成,即微处理器(CPU)、数据存储器(RAM)、程序存储器(ROM/EPROM)、并行I/O 口、串行口、定时器/计数器、中断系统及特殊功能寄存器(SFR)。[3][5]单片机是靠程序运行的,并且可以修改。通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,通过使用单片机编写的程序可以实现高智能,高效率,以及高可靠性!因此我们采用单片机作为计算器的主要功能部件,可以进行很快地实现运算功能。2.3 显示模块: LED 显示发光二极管LED 是单片机应用系统中的一宗简单而常用的输出设备,其在系统中的主要作用是显示单片机的输出数据、状态等。因而作为典型的外围器件,LED 显示单元是反映系统输出和操作输入的有效器件。LED 具备数字接口可以方便的和大年纪系统连接;它的优点是价格低,寿命长,对电压电流的要求低及容易实现多路等,因而在单片机应用系统中获得了广泛的应用。[2][4]通常的数码显示器是由7 段条形的LED 组成(如图4 所示),点亮适当的字段,就可显示出不同的数字。我们采用8 段数码管,其中位于显示器右下角的LED 作小数点用。LED 显示器有两种不同的形式:共阴极和共阳极。本次设计采用共阴极接法(如图5所示)。 3、软件设计 在程序设计方法上,模块化程序设计是单片机应用中最常用的程序设计方法。设计的中心思想是把一个复杂应用程序按整体功能划分成若干相对独立的程序模块,各模块可以单独设计、编程和调试,然后组合起来。这种方法便于设计和调试,容易实现多个程序共存,但各个模块之间的连接有一定的难度。根据需要我们可以采用自上而下的程序设计方法,此方法先从主程序开始设计,然后再编制各从属程序和子程序,层层细化逐步求精,最终完成一个复杂程序的设计。这种方法比较符合人们的日常思维,缺点是一级的程序错误会对整个程序产生影响。功能流程图如下: 4、硬件原理 以下为简易计算器的总体电路图 加运算: 减运算: 乘运算: 除运算: 清零: 四.总结 通过此次单片机实训设计,我们学到了很多东西,在器件的了解和器件选择上有个明确的认识,并在程序的设计,及理论在实践反面的运用能力有巨大的提高。 这次单片机课程设计由我们六位同学经过一周努力设计得到。软件的编程要我们不断的调试,最终我们终于完成了单片机实训课程设计,很高兴它能按着设计思想与要求运动起来。 当然,这其中也有很多的问题。第一、不够细心,由于对课本理论的不熟悉导致的编程错误,对于器件的实际情况的不了解,理论与实践的差距导致我们在设计实际电路时出现了很多错误,使得实验不能一次通过。第二、是在学习态度上,这次课程设计是对我们的学习态度的一次体验。对于这次单片机综合课程实习,我们的第一大心得体会就是作为一名工程技术人员,要求具备的首要素质绝对应该是严谨,这次的课程设计我们所遇到的问题多半是由于我们不够严谨。第三、在做人上,我们认识到,无论做什么事情,只要你足够坚强,有足够的毅力和决心,有足够的挑战困难的勇气,就没什么办不到的。还有就是团队的合作精神。 在这次难得的课程设计过程中我们锻炼了自己的思考能力和动手能力,加强了我们思考问题的完整性和实际生活联系的可行性。在方案设计选择和芯片的选择上,培养了我们综合应用单片机的能力,对单片机的各个管脚的功能也有了进一步的认识。还锻炼我们个人的查阅技术资料的能力,动手能力,发现问题、解决问题的能力。 五.参考文献 《单片机原理及应用》 张毅刚 高等教育出版社 《MCS—51单片机应用设计》 张毅刚 哈尔滨工业大学出版社 《MCS—51系列单片机实用接口技术》 李华 北京航空航天大学出版社 《单片机应用技术选集》 何立民 北京航空航天大学出版社 《单片机原理及其接口技术》 胡汉才 《数码管显示驱动和键盘扫描控制器CH451及其应用》 清华大学出版社 施隆照 /*********************************************** **实现说明: 1:变量flag_fuhao为键入+、-、*、/运算符标志 (即当前一个键值为+、-、*、/运算符时,flag_fuhao为1,其他键值则flag_fuhao置零,其用在显示时) 2:变量flag_shu数输入情况,flag_shu为0时,输入的符号无效(flag_shu为2时,变量fuhao更新为新键值) *********************************************/ #include sbit OFF = P1^0;//关机键定义 float shu1,shu2;//进行运算的两个变量数 uchar num;////键盘扫描返回值 char flag1,flag_shu,flag_fuhao,fuhao,newkey,update; //flag1开机标志newkey新按键标志,fuhao运算符,update表示等于号 //之后紧接着输入的是数的话则清零shu1 char key_shu;//按键值 char ge=0xdf;//char code Wela[]={0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//六位数码管的位选 unsigned char code Duan[]={0x3f,0x06,0x5b, // 0 1 2 0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};// 3 4 5 6 7 8 9 无显示 共阴极数码管 // 函数声明 uchar keyscan();//键盘扫描函数 void display(float);//数码管显示函数 void delay(uint i)//延时函数 { while(i--);} /*********************************************** 主函数 ************************************************/ void main(){ flag1=0;//标志关机 while(1){ if(keyscan()==15)//开机检测 { flag1=1;//标志开机 shu1=shu2=fuhao=flag_shu=newkey=0;//初始化变量 while(flag1)//判断是否已开机 { if(!flag_fuhao) display(shu1);//如果输入的不是 else display(shu2); key_shu=keyscan(); if(newkey==1)//有新键值 { if(key_shu==15)//按下ON/C键,清零 { flag_fuhao=update=0; shu1=shu2=fuhao=flag_shu=newkey=0; } else if(key_shu==14&&flag_shu==1&&fuhao)//按下“=” { switch(fuhao) { case 10:shu1=shu2+shu1;break; case 11:shu1=shu2-shu1;break; case 12:shu1=shu2*shu1;break; case 13:shu1=shu2/shu1;break; } flag_fuhao=0; fuhao=0; update=1; } 10 else if((key_shu>=0)&&(key_shu<=9))//按下数字键 { if(update) shu1=0; if(shu1<100000) { shu1=key_shu+shu1*10; flag_shu=1; } update=0; flag_fuhao=0; } else if((key_shu>=10)&&(key_shu<=13))//按下运算符 { flag_fuhao=1;//表示按下了运算符号键 update=0; if(flag_shu==1)//表示之前有数字键按下 { if(fuhao==0)//表示计算时只有一次按下运算符,如1*8=8,第二个数字后面是=,而不是其他运算符 { shu2=shu1; shu1=0; fuhao=key_shu;//将按下的运算符号的键的值赋值给fuhao,记录前一个运算符,以便按=后实现相应的计算。 flag_shu=2; } else //表示计算时按了多次运算符,如1*8*9=72,第二个数字后面并没有=,而是* { switch(fuhao) { case 10:shu2=shu2+shu1;break; case 11:shu2=shu2-shu1;break; case 12:shu2=shu2*shu1;break; case 13:shu2=shu2/shu1;break; } shu1=0; fuhao=key_shu;//将按下的运算符号的键的值赋值给fuhao,记录前一个运算符,以便按=后实现相应的计算。 } } else if(flag_shu==2) fuhao=key_shu;//将按下的运算符号的键的值赋值给fuhao,记录前一个运算符,以便按=后实现相应的计算。 } newkey=0; } } } } } /*********************************************** 数码管显示函数 ************************************************/ void display(float dis_shu){ long zhengshu=(long)dis_shu;char dis_flag,dis_aa,dis_zero=0;uchar dis_data[6]={0,0,0,0,0,0},xiaoshu[6]={0,0,0,0,0,0}; ge=0xdf;//11 01 111 if(zhengshu>99999)dis_flag=6;else if(zhengshu>9999)dis_flag=5;else if(zhengshu>999)dis_flag=4;else if(zhengshu>99)dis_flag=3;else if(zhengshu>9)dis_flag=2;else dis_flag=1; dis_shu=dis_shu-zhengshu; for(dis_aa=0;(dis_aa<6-dis_flag)&&(dis_shu=(dis_shu-(char)dis_shu)*10);dis_aa++){ xiaoshu[dis_aa]=(long)dis_shu;} for(dis_aa=0;(dis_aa<6-dis_flag);dis_aa++){ if(dis_zero||xiaoshu[5-dis_flag-dis_aa])12 { duan=Duan[xiaoshu[5-dis_flag-dis_aa]]; wei=ge; ge>>=1; delay(100); wei=0xff; dis_zero=1; } } // for(dis_aa=0;dis_aa dis_data[dis_aa]=zhengshu%10; zhengshu=zhengshu/10;} //数码管段选 for(dis_aa=0;dis_aa if(0xdf!=ge&&dis_aa==0) { duan=Duan[dis_data[dis_aa]]|0x80; wei=ge; ge>>=1; delay(100); wei=0xff; } else { duan=Duan[dis_data[dis_aa]]; wei=ge; ge>>=1; delay(100); wei=0xff; } } //数码管位选 } /*********************************************** 键盘扫描函数 ************************************************/ uchar keyscan()// 函数返回按键的值 { //将第一行线置低电平,其余行线全部为高电平,即扫描第一行 key=0xfe; if(key!=0xfe){ delay(500);//延时消抖操作 if(key!=0xfe) { switch(key) { case 0xee:num=7;break;//7 case 0xde:num=8;break;//8 case 0xbe:num=9;break;//9 case 0x7e:num=13;break;//除号 ”/” } newkey=1; delay(500); while(key!=0xfe) { if(flag1)//如果已开机 if(!shu1&&num>=0&&num<=9)//如果输入的第一个数不为0且第二个数为数字,则显示第二个数字,否则显示第一个数字 display(num); else display(shu1); } return num; } } //将第二行线置低电平,其余行线全部为高电平,即扫描第二行 key=0xfd;if(key!=0xfd){ delay(500);//延时消抖操作 if(key!=0xfd) { switch(key) { case 0xed:num=4;break;//4 case 0xdd:num=5;break;//5 case 0xbd:num=6;break;//6 case 0x7d:num=12;break;//* } newkey=1; delay(500); while(key!=0xfd) { if(flag1) if(!shu1&&num>=0&&num<=9)//如果输入的第一个数不为0且第二个数为数字,则显示第二个数字,否则显示第一个数字 display(num); else display(shu1); } return num; } } //将第三行线置低电平,其余行线全部为高电平,即扫描第三行 key=0xfb;if(key!=0xfb){ delay(500); if(key!=0xfb) { switch(key) { case 0xeb:num=1;break;//1 case 0xdb:num=2;break;//2 case 0xbb:num=3;break;//3 15 case 0x7b:num=11;break;//- } newkey=1; delay(500); while(key!=0xfb) { if(flag1) if(!shu1&&num>=0&&num<=9)//如果输入的第一个数不为0且第二个数为数字,则显示第二个数字,否则显示第一个数字 display(num); else display(shu1); } return num; } } //将第四行线置低电平,其余行线全部为高电平,即扫描第四行 key=0xf7;if(key!=0xf7){ delay(500); if(key!=0xf7) { switch(key) { case 0xe7:num=15;break;// ON/C:开关机按键 case 0xd7:num=0;break;// 0 case 0xb7:num=14;break;// = case 0x77:num=10;break;// + } newkey=1; delay(500); while(key!=0xf7) { if(flag1) if(!shu1&&num>=0&&num<=9)//如果输入的第一个数不为0且第二个数为数字,则显示第二个数字,否则显示第一个数字 display(num); else display(shu1); } 16 return num; } } //判断关机按键是否被按下 if(!OFF){ delay(500);//延时消抖操作 if(!OFF) { flag1=0;// } } return 100; } typedef unsigned char UINT8;typedef unsigned int UINT16;code UINT8 SEGMENT[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};code UINT8 SELECT[8] ={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};#define S1 0x0e #define S2 0x0d #define S3 0x0b #define S4 0x07 sbit SPEAK=P3^5;sbit P3_3=P3^3;UINT8 Second; void timer_10ms(void)//定时器T0定时10ms { TMOD=0x01;TH0=0xdc;TL0=0x32;TR0=1;//启动T0 } void Delay(UINT16 t){ UINT16 i,j; for(i=0;i for(j=0;j<114;j++);} void Display(void){ static UINT8 num=0;P2=0xff;switch(num){ case 0: P0=0xff; break; case 1: P0=0xff; break; case 2: P0=0xff; break; case 3: P0=0xff; break; case 4: P0=0xff; break; case 5: P0=0xff; break; case 6: P0=SEGMENT[Second%100/10]; break; case 7: P0=SEGMENT[Second%10]; break;} P2=SELECT[num];num++;num%=8;//if(num==8)num=0;} UINT8 Scankey(void){ UINT8 key;if((P3&0x0f)==0x0f) return(0xff);Delay(10); if((P3&0x0f)==0x0f) return(0xff);key=P3&0x0f;while((P3&0x0f)!=0x0f);return(key);} void main(){ UINT8 i; EA=1; //打开总中断 EX1=0;//打开外部中断1 IT1=1;TH0=0xdc;TL0=0x32;TR0=1;//启动T0 ET0=1; Second=60;while(1) { Display(); Delay(2); i = Scankey(); if(i==S1)//启动 { EA=1; } else if(i == S2)//暂停 { EA=0; } } } } void int_0()interrupt 1 { unsigned char z,aa; for(aa=59;aa>0;aa--){ for(z=0;z<50;z++) { P0=SEGMENT[aa/10]; P2=SELECT[3]; delay(5); //10ms P0=SEGMENT[aa%10]; P2=SELECT[4]; delay(5); //10ms LED台灯作为LED绿色照明光源产品,作为国家绿色照明推广使用的产品。在实际的应用中,发现LED灯在周边亮度大时依然以同一功率发光,存在电能浪费;在周边亮度小时LED灯不能提供足够和恰当的光度。本文介绍了以STC89C51为控制核心,通过光敏电阻感应光度,并利用PWM调光技术对LED进行光度的自动调节。同时设置手动控制。该LED台灯电路简单,很大程度上节省电能,延长LED灯寿命,适宜阅读。 关键词 LED台灯 光度 PID PWM调光 自动调节 原创性声明 本设计所用到的程序代码和电路均是来自本团队,如没有经过允许,不得复制和转载。 目录 前言··············································4 总体方案设计······································5 硬件设计··········································5 软件设计··········································9 总结·············································12 附录1:作品照片··································13 附录2:程序·······································15 前言 LED照明又称固态照明,作为继白炽灯、荧光灯后的第三代照明技术,具有节能、环保、安全可靠的特点,固态光源是被业界看好的未来十年替换传统照明器具极具潜力的新型光源,代表照明技术的未来。发展新固态照明,不仅是照明领域的革命,而且符合当前政府提出的“建设资源节约型和环境友好型社会”的要求。 LED台灯就是以LED(Light Emitting Diode)即发光二极管为光源的台灯,LED是一种固态的半导体器件,它可以直接把电转化为光。LED台灯是典型的绿色照明光源产品,作为国家绿色照明推广使用的产品,具有广阔的应用前景。 在实际的应用中,发现LED灯在周边亮度大时依然以同一功率发光,存在电能浪费。另外一方面,因为LED的发热量和电流存在正相关的关系,发热影响了LED的寿命,所以在不必要的亮度下也减少了LED的寿命。然而,当LED在周边亮度小时,LED灯不能提供足够和恰当的光度,这样又影响了阅读,造成视觉疲劳。 PWM方法的基本思想就是利用单片机具有的PWM端口,在不改变PWM方波周期的前提下,通过软件的方法调整单片机的PWM控制寄存器来调整PWM的占空比,从而控制充电电流。本方法所要求的单片机必须具有ADC端口和PWM端口这两个必须条件,另外ADC的位数尽量高,单片机的工作速度尽量快。在调整充电电流前,单片机先快速读取充电电流的大小,然后把设定的充电电流与实际读取到的充电电流进行比较,若实际电流偏小则向增加充电电流的方向调整PWM的占空比;若实际电流偏大则向减小充电电流的方向调整PWM的占空比。 本文介绍了以STC89C51为控制核心,通过光敏电阻感应光度,并利用PWM调光技术对LED进行光度的自动调节。同时设置手动控制。该LED台灯电路简单,很大程度上节省电能,延长LED灯寿命,适宜阅读。 一、总体方案设计 基于C51单片机和PWM调光的LED台灯以STC89C51作为主控芯片,设置了手动控制和自动控制。在手动控制时,分为三档,输出不同的PWM占空比对LED的电流进行控制,从而实现了对光度的手动调节。 在自动控制时,通过ADC0809模拟-数字转换芯片不断检验光敏电阻的电压来间接测量感应光度,将电压和预设的阈值进行对比,调整PWM的占空比对LED的电流进行控制,从而实现了对光度的自动调节。总体框图如下(图1.1): 图1.1 二、硬件设计 硬件设计总体框图如下: 图2.0 1、主控电路: 主控电路采用STC89C51作为主MCU。STC89C51是一款八位,片内有ROM/EPROM的单片机,其硬件结构具有功能部件种类全,功能强等特点。这种芯片构成的最小系统简单、实用﹑可靠。用STC89C51单片机构成最小应用系统时,只要将单片机接上时钟电路和复位电路即可,如下图(图2.1)所示。本设计所选用的晶振为12MHZ,晶振电容为30PF。 图2.1 2、LED驱动 LED的亮度受电流控制,通过控制电流调节LED灯的亮度。利用公式ILtONTI可知,利用调整PWM不同的占空比就可以控制电流的大小。电流通断的变化用NMOS管K2717实现,三极管9014提供驱动K2717的电流,PWM由P2.0输出,低电平有效。如下图(图2.2)所示: 图2.2 2、手动控制 KEY4变化控制的方式,KEY4为自锁按键,按下为手动控制,弹起为自动控制。手动控制时可以分为三档,对应与KEY1~3三个按键。如下图(图2.3)所示: 图2.3 3、自动控制 <1>光敏电阻反馈部分 光敏电阻器是利用半导体的光电效应制成的一种电阻值随入射光的强弱而改变的电阻器;入射光强,电阻减小,入射光弱,电阻增大。光敏电阻器一般用于光的测量、光的控制和光电转换。因此,不断采集光敏电阻对地的电压便可以获知台灯周边光强的变化。如下图(图2.4)所示: 图2.4 <2>ADC0809模数转换部分 ADC 0808和ADC 0809除精度略有差别外(前者精度为8位、后者精度为7位),其余各方面完全相同。它们都是CMOS器件,不仅包括一个8位的逐次逼近型的ADC部分,而且还提供一个8通道的模拟多路开关和通道寻址逻辑,因而有理由把它作为简单的“数据采集系统”。利用它可直接输入8个单端的模拟信号分时进行A/D转换,在多点巡回检测和过程控制、运动控制中应用十分广泛。 如下图(图2.4)所示,ADC0809的参考电压设置成5V,时钟信号通过单片机P3.3口利用定时器中断输出。光敏电阻的对地电压从IN3口输入,ADC0809将其转换成数字量后通过OUT1-7输出,以便单片机进一步处理。 图2.5 三、软件设计 1、总体框图 图3.1 8 2、主要程序 <1>按键扫描 不断扫描按键判断是手动控制和自动控制。程序代码: void keyscan(){ ad(); if(key==1) //key4松开,a恒为0 ,通过读c的值确定b的值 { if(c<0.40) last=0; else if((c>=0.40)&&(c<2.0)) last=2; else if((c>=2.0)&&(c<3.0)) last=5; else if((c>=3.0)&&(c<4.0)) last=7; else last=10; } if(key==0) //key4按下,{ if(key1==0) { delayms(10);//去抖 if(key1==0) last=1; } if(key2==0) { delayms(10); if(key2==0) last=6; } if(key3==0) { delayms(10); if(key3==0) last=10; } } } 手动控制 9 <2>AD转换 定时器1产生CLK信号,定时时间为2us,亦即CLK周期为0.4us。程地址为011,即IN3口输入。利用公式getdata*1.0/255*VREV+对数字量进行变化。程序代码如下: void ad(){ } ST=0;//关闭转换 OE=0;//关闭输出 ST=1;//开启转换 ST=0;//关闭转换 P34=1;//选择通道0 P35=1;P36=0;while(EOC==0);//判断是否转换结束:是则执行以下语句,否则等待 OE=1;//开启数据输出允许 getdata=P0;//将数据取走,存放在变量getdata中 OE=0;//关闭输出 c=getdata*1.0/255*4.85;//电压值转换,5V作为参考电压,分成256 <3>PWM调节 定时器0控制PWM周期和占空比。程序代码如下: void into(void)interrupt 1 { TH0=(65536-500)/256;TL0=(65536-500)%256; count++;if(count>CIRCLE) { count=1;} if(count<=last)pwm=0;//占空比,使用反相器应为1 else pwm=1; 四、总结 基于C51单片机和PWM调光的LED台灯以STC89C51作为主控芯片,设置了手动控制和自动控制。在手动控制时,分为三档,输出不同的PWM占空比实现了对光度的手动调节。在自动控制时,通过ADC0809模拟-数字转换芯片不断检验光敏电阻的电压来间接测量感应光度,将电压和预设的阈值进行对比,调整PWM的占空比实现了对光度的自动调节。该LED台灯电路简单,很大程度上节省电能,延长LED灯寿命,适宜阅读。 同时,在本次课程设计中,主要有以下体会: 1、对LED的驱动有进一步的了解,明白了如何对LED进行规定电流驱动,并通过输出不同的占空比来调节LED的亮度,从而对LED的耗电进行相应的管理; 2、进一步掌握了AD转换原理以及相关芯片的应用,通过ADC0809对外界的模拟量进行转换。 近年来, 随着科学技术的快速发展, 特别是单片机的普及使用, 推动了仪器仪表向着集成化、小型化、智能化发展。其中仪器仪表量程自动转换技术就是突出的表现, 传统仪器仪表量程选择以人为手动为主, 使用中不同量程间转换频繁极易损坏仪器仪表中机械部件, 甚至可能造成测量误差影响测量结果。新型仪器仪表量程自动转换解决了这个难题, 利用单片机控制完成量程选择, 不需要人为干预自动对被测量选择合适的量程, 保护设备不被人为操作损坏。使测量仪器仪表具有智能化特性, 真正实现检测技术领域的智能化测量, 减轻使用人员工作负担。本系统利用单片机与多路选择器及A/D转换器完成对量程自动控制。 1 设计思路 1.1 通道模拟多路选择器CD4051 CD4051 最大的特点就是能选通模拟信号和实现多路信号的选择和分配, 也就是说模拟信号除了能从X0~X7 进入CD4051 而选择惟一输出外, 还能从CD4051的第3 管脚X输入, 而从X0~X7 管脚某一路输出。可见CD4051 是一个双向输入、输出型器件, 而且它能选通的模拟信号的最大峰-峰值VP - P=15 V, 非常适用于多通道信号选通/分配的场合。 如果在CD4051 的X0~X7 端连接不同阻值的电阻, 如图1 所示, 把这些电阻另一端一同连接到放大器模型的反相输入端, 而CD4051 的X端与放大器模型的输出端连接, CD4051 和8 个电阻相当于放大器的反馈电阻Rf。这时, 如果CD4051 的地址线A、B、C在单片机I/O口的控制下每次只选通某一通道, 这样不同阻值的电阻在某次选通下成为了放大器模型的反馈电阻, 因为这些电阻阻值有所不同, 所以在不同地址线信号的控制下, 放大器具有了不同的增益。 1.2 量程自动转换 在多通道信号检测系统中, 多个通道可通过CD4051 实现某一通道信号的选通, 这个被选通的信号经过放大等处理后至A/D进行数字化转换。由于各个传感器的输入信号幅度不同, 例如, 传感器2所测量的物理量对应电信号输出范围为10~50 m V, 而传感器6 所测量的物理量可能对应输出范围为l00~200 m V。这样就出现一个问题, 某些传感器最大的输出电平还没有其他传感器最小的输出电平大, 而放大器的职责是把传感器的最大信号尽可能地放大到贴近A/D输入的最大值, 以获得A/D转换的最大分辨率。 这种放大器只有一种放大倍数显然是不能完美地应付不同幅度范围信号放大问题的。 即便对于单通道的信号, 如果该信号的变化范围很大, 若放大器只有一种放大倍数, 也常会出现小信号得不到尽可能高的放大倍数而丧失A/D转换精度的问题。这就是图1 使用了两个CD4051 的原因, 一个用来切换通道, 另一个用来调整放大器的增益。 量程自动转换的方法与图1 所示的方法是一致的, 即在模拟信号通道中设置增益可控的放大器, 借助量程转换控制信号, 使量程根据实际需要进行转换。 2 量程自动转换电路设计 图2 所示为单通道数据采集量程自动转换的硬件电路, 图中量程控制部分使用CD4051 来调整反馈电阻的阻值, 当P1.1=P1.0=0 时, CD4051 的X0与X连通, 此时, 放大器的放大倍数为1, 相当于一个跟随器。 当P1.1=0, P1.1=1 时, X1 与X连通, 放大倍数为: 当P1.1=1, P1.0=0 时, X2 与X连通, 放大倍数为: 由此可得到量程转换时放大倍数与地址线之间的关系, 见表1。 在实际系统中, 只要改变P1.1 和P1.0 的状态就能调整放大器的放大倍数, 从而为不同幅度的模拟输入信号选择一个合适的增益, 以保证A/D转换的精度最大化。当然, 在实际系统中, 应当根据实际信号的幅度特点增加更多的量程, 以适应放大倍数的调整需要。 3 量程自动转换软件系统 无论量程自动转换的电路如何, 其软件控制的方法都是相似的, 都是通过改变CD4051 的选通通道, 从而改变反馈电阻阻值, 进而实现增益调整的。 软件控制的基本思路是:首先设置最大量程档, 即×1 档, 进行数据采集, 将采样值进行必要的计算后与下一个量程 (×5 档) 的满度值进行比较判别, 如果采样值大于下一个量程 (×5 档) 的满度值, 就在最大量程档 (×1 档) 进行采集。否则, 还要继续与更小量程档 (×20档) 的满度值进行比较, 直到采样值大于下一档的满度值, 这样所选择的量程必然是处在最适合于该采样值的量程档内。其软件流程图如图3 所示。 4 结语 以本系统为基础可以实现多种仪器仪表量程自动转换功能, 为仪器仪表数据采集做好准备, 具有集成化、智能化、简便的特点。本系统最大优点是利用单片机进行核心控制, 在整个工作过程中改变单片机程序可以使控制方式多样化, 并可以单片机为核心添加数据处理, 数据显示, 过程控制等单元, 为下一步的扩展留有空间。 参考文献 [1]张毅坤, 陈善久, 裘雪红.单片微型计算机原理及应用[M].西安:西安电子科技大学出版社, 1998. [2]龚尚福, 朱宇.微机原理与接口技术[M].西安:西安电子科技大学出版社, 2003. [3]于海生.微型计算机控制技术[M].北京:清华大学出版社, 1998. [4]柴钰, 刘晓荣, 杨良煜.QTH-2008XS单片机实验指导书[M].西安:西安科技大学出版社, 2007. [5]康华光.电子技术基础 (数字部分) [M].北京:高等教育出版社, 2000. [6]沙占友, 沙江.数字万用表功能扩展与应用[M].北京:人民邮电出版社, 2005. [7]沙占友.新型数字电压表原理与应用[M].北京:北京航空航天大学出版社, 1999. [8]朱齐嫒, 莫长江.单片机控制自动量程转换设计[J].淮阴工学院学报, 2005 (5) :47-49. [9]凌志浩.智能仪表原理与设计技术[M].上海:华东理工大学出版社, 2003. 1、前言 随着现代科技的发展,门禁控制系统在安全技术防范领域扮演着越来越重要的角色,这是建立在先进的计算机技术,通信技术各非接触的射频识别技术之上,通过持有非接触式IC卡来对人的进出实施放行,拒绝和记录等操作的智能化控制系统。非接触式IC卡的核心技术为射频识别,其环境适应性强,可全天候,无接触地完成自动识别功能。 本系统以89C51系列单片机STC89C52为控制核心,利用非接触式射频卡模块读取用户手中的IC卡信息,识别成功后与系统存储的IC卡库数据进行比对校验,如果IC卡数据库中有IC卡则证明IC卡合法,单片机通过控制继电器控制电子锁门禁开启和关闭。同时采用键盘作为IC卡录入和删除,LCD1602液晶作为人机交互显示,让系统具备更大的实用价值。 2、系统总程序设计 系统上电后首先进行初始化,完成液晶、键盘等初始化任务。然后进入死循环,单片机控制IC卡模块时时扫描判断是否有IC靠近,当靠近时,启动IC卡读取程序,识别IC卡卡片信息后,与AT24C02芯片内存储的IC卡数据库信息进行比对,如果校验成功则控制门禁开,反之则不开门禁。整个过程LCD1602液晶显示操作过程及数据信息。 3、IC卡读写子程序设计 3.1 Mifare射频卡技术参数 (1)容量为8K位(bits)1K字节(bytes)EEPROM (2)分为16个扇区,每个扇区为4块,每块16个字节,以块为存取单位 (3)每个扇区有独立的一组密码及访问控制 (4)每张卡有唯一序列号,为32位 (5)具有防冲突机制,支持多卡操作 (6)无电源,自带天线,内含加密控制逻辑和通讯逻辑电路 (7)数据保存期为10年,可改写10万次,读无限次 (8)工作温度:-20℃~50℃(湿度为90%) (9)工作频率:13.56MHZ (10)通信速率:106 KBPS (11)读写距离:10 cm以内(与读写器有关) 3.2 IC卡读写卡的过程一般包含如下几个步骤: (1)复位应答(Answer to request) 射频卡的通讯协议和通讯波特率是定义好的,当有卡片进入读写器的操作范围时,读写器以特定的协议与它通讯,从而确定该卡是否为M1射频卡,即验证卡片的卡型。 (2)防冲突机制(Anticollision Loop) 当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作,未选中的则处于空闲模式等待下一次选卡,该过程会返回被选卡的序列号。 (3)选择卡片(Select Tag) 选择被选中的卡的序列号,并同时返回卡的容量代码。 (4)三次互相确认(3 Pass Authentication) 选定要处理的卡片之后,读写器就确定要访问的扇区号,并对该扇区密码进行密码校验,在三次相互认证之后就可以通过加密流进行通讯。(在选择另一扇区时,则必须进行另一扇区密码校验。) IC卡读写流程图如图所示 3.3 IC卡读写操作流程图 4.按键程序的设计 按键作为人机交互的方式,在该设计中起着至关重要的作用。实现IC卡的录入与删除。当读卡模块检测到该IC卡时,如果该IC卡没有被录入,当有键按下时,则该卡被记录,拥有进出该门禁的权限;如果该IC卡被录入了,当有键按下时,则该卡被删除,被取消进出权限。 图4.3 键盘子程序流程图 本系统用到了5个按键,它们的功能分别是:调节时间的时钟加、时钟减、分钟加、分钟减和添加/删除用用户卡。它们采用的是独立按键的连接方式,一端连接地,一端连在单片机的P1.0到P1.4口上。它们的程序实现是:首先给P1.0到P1.4口高电平,然后扫描这些I/O口上是否有电平变化,当它们有变化是说明有键被按下,最后根据是哪个I/O口的电平变化了判断是哪个键被按下。它的程序流程图如图4.3所示 5. LCD1602液晶显示子程序 1602液晶是字符型液晶,它的内部自带字符库,它可以写两行的字符,同时每行可以显示16个字符。在这里要显示的是实时时间,IC的编号和权限以及一些提示信息。 LCD1602的操作步骤:初始化;写命令(RS=L)设置显示坐标;写数据(RS=H)。根据其操作步骤设计LCD1602液晶显示程序流程图如图4.4。 从此流程图我们得出:LCD液晶显示屏在写显示程序的时候,我们要先写命令,再设定字符显示和汉字的位置,最后写数据,在每写一次命令或数据都需要判断液晶是否忙。打开液晶显示屏进入初始化状态,开始写命令,首先判断LCD是否忙,如果是P0.7=0,那么进入下一步写命令,如果不是P0.7=0,返回LCD是否忙。 6 电子锁门禁开关子程序设计 本系统的电子锁门禁开关,单片机只需要输出高低电平即可。当输出高电平时门禁关、低电平门禁开。程序流程如图4.5所示。 7 报警子程序设计 本系统的报警提示是通过蜂鸣器和LED来实现的,系统中用的是无源蜂鸣器。无涯蜂鸣器要给脉冲信号才能实现鸣叫,在程序的设计中,通过定时器产生脉冲信号来控制蜂鸣器报警。根据报警电路原理,当读卡模块检测到有非法卡进入,单片机输出一个报警信号,开启定时器产生脉冲信号给蜂鸣器报警。 报警子程序的流程图如图4.6所示。 8小结 一、中断的概念 CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务); 待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断 二、中断源 在51单片机中有5个中断源 中断号优先级中断源中断入口地址 01(最高)外部中断00003H12定时器0000BH 23外部中断10013H 34定时器10018H 45串口总段0023H 三、中断寄存器 单片机有10个寄存器主要与中断程序的书写控制有关 1.中断允许控制寄存器IE 2.定时器控制寄存器TCON 3.串口控制寄存器SCON 4.中断优先控制寄存器IP 5.定时器工作方式控制寄存器TMOD 1、我从不说51是基础,如果我这么说,也请把这句话理解为微机原理是基础。 2、对51单片机的操作本质上就是对寄存器的操作,对其他单片机也是如此。 库只是一个接口,方便使用者使用而已。 3、汇编语言在工作中很少用到,了解就好。 4、51的P0口很特别。 5、C语言就是C语言,51单片机就是51单片机,算法就是算法,外围电路就是外围电路,传感器就是传感器,通信器件就是通信器件,电路图就是电路图,PCB图就是PCB图,仿真就是仿真。 当你以后再也不使用51了,C语言的知识还在,算法的知识还在,搭建单片机的最小系统的技能还在,传感器和通信器件的使用方法还在,还会画电路图和PCB图,当然也会仿真。 6、51单片机是这个: 而不是这个: 7、当程序调试不如人意的时候,静下心来好好查资料,51单片机最大的好处就是网上资料非常多,你遇到的问题别人肯定也遇到过。 作为学习者,问人可能更方便点,但一直这样是培养不出解决问题的能力的。 接下来上点干货: 首先要放清51的定位,跟我一起再念一遍:51只是个工具51只是个工具51只是个工具。 当然51还有一个地位就是大学生单片机启蒙教程。 换句话说:单片机只是个工具单片机只是个工具单片机只是个工具。 然后什么是基础:模电数电微机原理,然后熟练翻阅数据手册,可以试着做一些模块或者最小系统练练手,C语言其实也可以算工具吧,就单片机来说,作为必要条件也算作基础吧。 再然后是要尽早搞明白自己的专业方向或者自己准备发展的方向,然后不同方向又有不同的专业基础,你学测控,就需要各种传感器、控制原理、理论、算法//买测量模块用不叫测控啊喂;你学信号处理,就需要信号与系统、数字信号处理基础,然后慢慢接触DSP、FPGA//信号处理真的不是result=(AD+0.5)/4096*3.3啊喂;你想做嵌入式开发,就慢慢研究ARM的架构,跑一些实时系统甚至高端ARM跑Linux开发驱动或应用;你要是想做通信,每天晚上拜一拜香农好了,这茬貌似挺苦的,什么通信原理编码论电磁场blablabla…… 总之51/单片机可以实现很多事情,但这不是一定说51重要,而是你如何利用51。 哦对了,当你使用更高级的芯片的时候,很多底层的东西慢慢可以忽略了,甚至很多芯片厂商都会提供库给你,你可以安心的专注于自己的算法而不是如何去控制单片机。 当然你最好还是要有一个芯片怎么通过寄存器及各种逻辑电路工作的概念。 还有说一下你大学课余生活的选择、首先那种机器人实验室或者学生领导的实验室,适合打比赛刷奖状、长期下来你的模数电技能能有很大的锻炼,甚至你可以收货一些专利,而且学生之间气氛也还不错。 另外一种就是找个导师跟着学习、帮忙、做项目,尽管最开始可能感觉导师分配给你的任务怎么都和单片机无关啊好无聊,但是你能在某个领域收获不一样的技术。 当然前提是你要喜欢导师的研究方向了,一般院网站都有或者去知网看这个老师发表的论文。 谈谈我的经历吧。 1、一个没有C基础的的我,从师兄老师那打听到学51从郭天祥的视频开始,所以我就下载了全套来看。 刚开始看真是头都晕了,点亮一个LED灯还可以,到了第二课的延时函数就吃不消了,可以说我耐力差吧,没有坚持,可以说我没恒心吧,不是真正想学东西的人,当时的我没有把它放心上,只是看了4课而已,其实对里面的程序不太理解的,于是就停下来不学了。 到了大二下学期,我发现要学点技术,所以重抄旧业,学期单片机,然后再重第1课开始看起,结果发现以前不明白的东西现在豁然开朗。 我写这经历是想说,如果当时我坚持下去,不懂的地方看多几遍,不懂再看再看,就不会浪费大半年的时间了。 有些知识理论靠时间的积累,第一遍看不懂,第二遍看不懂,第三遍可能就懂一点了,刚开始上手一件事是会遇到类似的情况的。 2、当我学了1个月后,学校里有个比赛,团队需要一个人搞硬件,于是我自己提出搞硬件,为什么?因为在学单片机的过程中发现,自己只会跑程序,连原理图都不怎么会看,单片机的接线我都是看开发板提供的资料来接的,很狗血吧。 于是我就开始接触Altium Designer了,这是我这学期学的第二个软件。 是看视频入门的,刚开始看的是郭天祥的视频,结果发现看不下去啊,太长太累了,看完一集好痛苦啊,于是我搜搜,结果发现一个很好的教学视频,用的也是比较新的版本,叫《边学边玩Altium Designer》 四人行工作室开的。 我真的提感谢作者这种开源的精神的,对我们初学者帮助很大。 跟着他的视频学习1个月,会画出51最小系统,基本布线,不过我觉得还是不够(当然不够啦,你才学了一个月……) 3、在学Altium Designer的过程中涉及到电路分析,也就是我们现在学的《电子电路基础》,于是爱折腾的我开始捣鼓起Multisim 12.0,这是一款电路模拟仿真的软件。 跟着老师学挺慢的,但是教材又高深了一点,比如说分析放大电路,稳压电源,教材上的东西大多列出公式,对于零基础学习的.朋友是挺苦逼的,而且老师也是赶鸭子式,讲考试内容。 这里建议大家买一本书《电子设计零基础》第二版,这本书是我在图书馆偶然发现的,但从此就迷恋上了他。 刚开始他不会介绍一大堆公式,以一个例子开始教学,一步一步教你认识元器件(这里对学PCB是有帮助的),然后从电路图的一步分开始分析,接着分析怎么系统,书本结合Multisim 仿真,教你一步一步使用里面的控件。 写到这里自己总结下: 对于1:学单片机最重要的是 1.先认识单片机,了解单片机的主要组成和各个管脚的定义及功;推荐书《单片机原理及其接口技术》胡汉才(很熟悉吧。 呵呵这就是我们大学的单片机教材啊!!经典中的经典啊!基础中的基础啊!!人家几十年的教材没有变是有道理的,原理这种东西不会变到哪里去的。 不用专门去看,当作了解,对你理解编程是很有帮助的。) 2.了解一些单片机汇编知识,方便后续调试;这本书《单片机原理及其接口技术》里面就是讲汇编的,一举两得。 3.掌握单片机中断机制; 4.掌握单片机定时和计数器;(3和4是对单片机内部寄存器的控制,要熟练掌握。 那些外部拓展功能大多都基于这些内部控制) 5.掌握单片机的串口通信。 以上是对想从事单片机学习的人必须掌握的基本内容。 对于2、3:2、3可以在一起讲,这是硬件部分的。 Altium Designer主要学原理图库设计,PCB库设计,布线。 没入门的朋友看下视频,不要求什么都会画,起码要会用人家的库,把人家的库移植过来自己用,这样可以快速上手这个软件。 关键词:单片机,智能,温度,调节,开关 0 引言 国家一直在提倡节约能源, 而且地球上的淡水资源也十分有限。想必很多人也有这样的感受, 冬天的时候, 如果热水器离用水的地方比较远, 比如太阳能热水器安装在楼顶, 而用户在楼下用热水, 往往需要放掉几分钟的冷水才能用到热水, 这个时候大量的冷水就白白地浪费掉了。 针对这个问题, 笔者设计出一款可以根据水管内的水温来控制的开关, 水温低于预设温度时, 开关打到储水箱, 冷水流到储水箱存放;水温高于预设温度时, 开关打到龙头, 热水流到使用端。 1 总体设计 本设计将温度检测模块、供水电磁阀控制模块、按键模块和显示模块组合, 由单片机控制各模块, 实现以下功能: (1) 使用者可以选择节水开关是否工作; (2) 开关根据水温切换水流的方向; (3) 使用者可以根据环境温度和自身需要调整龙头出水温度。 开关安装示意图如图一所示。 整个系统使用直流12V电源供电。单片机、LED和数码管等元器件工作电压为5V, 通过LM7805将12V电源转换成5V供电。供水电磁阀开关工作电压为12V, 单片机通过继电器对其进行控制。整个系统使用低电压直流供电可以避免触电, 同时具有功耗低、节能等特点, 满足了政府提倡的低碳绿色生活的要求。 2 硬件选择 以下详细介绍主要硬件的设计思路和具体参数。 2.1 单片机 作为整个系统的核心部件, 单片机的选择最为重要。根据以往使用单片机的经验, 笔者需要寻找一款性能稳定、使用方便、价格便宜的单片机。宏晶科技最新的一款MCU进入笔者视野:STC15W404AS。宏晶科技是中国单片机电子产品制造开发设计方案的领导品牌, 是国内本土集设计、生产于一体的单片机公司, 有很强的研发实力, 主打8051系列单片机。而STC15W404AS正是一款基于8051核心的新型单片机, 其主要功能有: (1) 高速, 1T, 单时钟/机器周期, 增强型8051内核, 速度比普通8051芯片快7~12倍。 (2) 18个通用I/O口, 10位高速ADC, 满足普通功能使用。 (3) 内置高可靠复位电路, 省去外部复位电路, 降低成本。 (4) 内部集成高精度R/C时钟, ±1%温漂 (-40℃~85℃) , 常温 (-20℃~60℃) 下温漂±0.6%, 内部时钟5M~35M宽范围可设, 可彻底省掉外部昂贵的晶振时钟, 降低成本。 (5) 支持ISP/IAP, 在系统可编程/在应用可编程, 升级调试方便。 (6) 低功耗设计, 低速模式, 掉电模式, 空闲模式。 (7) 价格低廉, 比一般8051系列单片机便宜一半以上。 基于笔者以往使用宏晶科技51系列单片机的经验, 宏晶科技的51单片机性能强劲、品质优良、价格低廉。宏晶科技的最新单片机STC15W404AS的管脚定义如图二所示。 2.2 温度检测模块 DS18B20是美国DALLAS半导体公司推出的第一片支持“一线总线”接口的温度传感器, 它具有体积小、功耗低、性能强、硬件开销低、抗干扰能力强、精度高的特点。其主要功能有: (1) 独特的单线接口, 仅需一个端口引脚进行通信。 (2) 无需外部器件, 在使用中不需要任何外围元件, 全部传感元件及转换电路集成在形如三极管的封装中。 (3) 测温范围为-55℃~+125℃, 在-10~+85℃范围内精确度为±0.5℃。 温度检测模块使用外部供电模式, 其接线图如图三所示。 2.3 供水电磁阀模块 笔者选用了一进二出的电磁水阀, 此电磁水阀的两个出水口都有电磁阀, 可以分别控制其开关。根据使用次数和使用周期, 笔者决定通过继电器来控制其工作, 这样可以降低成本, 同时也能取得很好的效果。电磁阀实物图如图四所示。 电磁阀接线设计如图五所示。 2.4 数码管显示 笔者选用的是一款0.36英寸红光3位共阴级LED数码管。因为本设计使用了宏晶科技的最新单片机, I/O口丰富, 足够使用, 所以并没有使用驱动LED数码管常用的8位串入、并出移位寄存器74HC164D。 一般地, 红光LED数码管每段流过5m A的电流, 亮度就可以了, 7m A电流会更亮些, 但10m A以上不会再亮多少。如果长期运行于10m A以上反而会缩短其寿命。所以在接线中都串入了一个1K电阻来限流。 LED数码管译码方法通常有两种:软件查表法和硬件译码法。根据此产品的设计, 我们将采用软件查表法, 在软件设计的时候只需要在程序中安排一张显示字符段码表。段码表应根据硬件电路中使用的数码管的极性和显示字符的需要而设定。 LED显示器有静态显示和动态显示两种方式。 静态显示:即显示驱动电路具有输出锁存功能, 单片机将所要显示的数据送出去后, 数码管始终显示该数据, CPU不再控制LED。到下一次显示时, 再传送一次新的显示数据。静态显示的接口电路采用一个并行口接一个数码管, 数码管的公共端按共阴极或共阳极分别接地或接VCC;这种接法, 每个数码管都要单独占用一个并行I/O口, 以便单片机传送字形码到数码管控制数码管的显示。其优点是显示的数据稳定, 无闪烁, 占用CPU时间少;其缺点是由于数码管始终发光, 功耗比较大。 动态显示:为了克服静态显示方式的缺点, 节省I/O口线, 常常使用动态显示方式。动态扫描方法是用其接口电路把所有数码管的8个笔划段a~g和dp同名端连在一起, 而每一个数码管的公共极COM各自独立地受I/O线控制。CPU向字段输出口送出字形码时, 所有数码管接收到相同的字形码。哪个数码管亮, 则取决于COM端, COM端与单片机的I/O口相连, 由单片机输出位码到I/O控制何时哪一位数码管亮。动态扫描用分时的方法轮流控制各个数码管的COM端, 使各个数码管轮流点亮。在需要多个字符同时显示时, 可以轮流给每一个字符通以电流, 逐次把所需显示的字符显示出来。在每点亮一个显示器之后, 必须持续通电一段时间, 使之发光稳定, 然后再点亮另一个显示器, 如此巡回扫描所有的显示器。由于巡回显示速度较快, 每秒可重复多次 (为了不产生闪烁, 可每秒扫描24次左右) 。虽然在同一时刻只有一个显示器通电, 但是由于人眼的视觉暂留作用和发光二极管的余辉效应, 看起来每个显示器都在稳定地显示。这种巡回扫描显示器的操作要靠程序控制, CPU始终要介入显示扫描。动态显示的亮度随电流平均值的增大而增强, 亮度大体上等同于通过同样大的稳定电流的静态显示器的亮度。优点:当显示位数较多时, 采用动态显示方式比较节省I/O口, 硬件电路也较静态显示简单。缺点:其稳定度不如静态显示方式, 而且在显示位数较多时CPU要轮番扫描, 占用CPU较多的时间。 数码管接线设计如图六所示。 2.5 按键模块 常见的非编码按键按其结构可分为独立按键和矩阵按键。独立按键的每个按键需要占用一个I/O口, 当按键较多时, I/O口利用率不高, 编程相对简单, 适用于按键较少的场合。而矩阵按键电路连接较独立、按键复杂, 但提高了I/O的利用率, 编程相对也复杂, 适用于需要大量按键的场合。因为本设计使用了4个按键, 独立按键和矩阵按键设计都需要使用4个I/O, 但相比电路和编程的复杂度, 笔者选用了最简单的独立按键设计, 按键接线如图七所示。 3 系统软件设计 此系统的软件流程设计如图八所示。在系统上电后, 单片机进行初始化, 然后确认节水开关的功能是否激活。如果功能未启用, 那开关将指向龙头, 热水器里的水, 不管温度都将直接流向龙头, 这个模式适合在夏天使用。如果功能启用, 那开关内的感温探头将工作, 测试水管内的温度, 若水温低于预设值, 开关将指向储水箱, 冷水流入储水箱;若水温高于预设值, 开关将指向龙头, 此时LED将闪烁, 告诉用户水龙头的温度已经满足预设值, 可以使用。 4 结束语 通过试做样品, 并连接试用, 实现设计预期, 功能正常, 具备批量生产和市场推广的条件。但同时也存在一些问题, 主要如下: (1) 体积过大, 因为开始设计时所使用的都是普通元器件, 并没有考虑体积问题, 但实际试做的过程中发现开关体积过大, 导致外观不美观。所以在后面的改版中, 要考虑使用小型元器件及优化供电模块, 将开关做的小巧美观。 (2) 指示效果不够明显。当水温达到预设值的时候, 只有灯光闪烁, 给用户的指示效果不够明显。在后面的改版中, 将加入蜂鸣器声音报警, 声光同时指示, 可以让用户获得更加明显的指示。 参考文献 [1]廖爽.模拟电路[M].北京:电子工业出版社, 1997. [2]陈桂友.单片微型计算机原理及接口技术[M].北京:高等教育出版社, 2012. [3]丁向荣.增强型8051单片机原理与系统开发 (C51版) [M].北京:清华大学出版社, 2013. void delay_100ms(unsigned int t){ unsigned char i,j,k;for(i=t;i>0;i--){ for(j=200;j>0;j--); { for(k=248;k>0;k--); } } } void beep(){ BEEP=1; delay_100ms(100); BEEP=0; } void T0_int()interrupt 1 { static unsigned char count;unsigned char a=1;count++; TH0=(65536-50000)/256; TL0=(65536-50000)%256;if(count==20){ count=0; P0=TAB[pulse_number1--]; } beep(); if(pulse_number1==0) { P0=TAB[0]; TR0=0; while(a) { beep();if(!key5)a=0; } } } void main(){ bit flag; temp=0x00; P2=temp; P0=0x3f; TMOD=0x01; TH0=(65536-50000)/256;TL0=(65536-50000)%256;ET0=1;EA=1; TR0=1; while(!flag) { } while(flag);} if(!key1){P0=0x06;beep();flag=1;TR0=0;} 【51单片机课程设计作业】推荐阅读: 基于51单片机的智能小车设计08-31 基于51单片机恒压供水系统设计06-27 单片机课程设计实验06-23 2022 单片机原理课程设计要求12-01 at89s51单片机简介07-21 《单片机与外围电路设计》课程设计大纲10-27 单片机实训作业09-26 基于单片机的毕业设计06-252.51单片机课程设计作业 篇二
3.51单片机课程设计作业 篇三
4.51单片机课程设计作业 篇四
5.51单片机课程设计作业 篇五
6.51单片机课程设计作业 篇六
7.51单片机课程设计作业 篇七
8.51单片机课程设计作业 篇八
9.51单片机中断学习 篇九
10.51单片机心得体会 篇十
11.51单片机课程设计作业 篇十一
12.51单片机四路抢答器程序 篇十二