一、实验目的与要求 1.熟悉 Keil C51 集成环境软件的使用方法。 2.熟悉 MCS51 汇编指令,能自己编写简单的程序,控制硬件。 3.熟悉畅学开发平台,掌握单片机最小系统及 IO 口的简单控制及不同组 IO 口的特点。
二、实验内容1、熟悉Keil C51集成环境软件的安装和使用方法。 2、照接线图编写程序,完善给出程序,实现以下功能。 要求LED灯实现从上到下依次点亮,再从下到上依次点亮。完成后实现从两侧向中间循环点亮,再从中间往外循环点亮。功能完成后循环上述过程。 3、观察实验结果,验证程序是否正确。
2.1 实验完成内容1、延时实现LED流水灯效果,p1端口的八个灯作跑马灯。在本实验中,p1作为输出口,接8只发光二极管,编写程序,使发光二极管循环点亮。 本例实验主要用到了延时子程序,CLR、AJMP、RRC、RLC、CALL等指令,通过轮流点亮p0.0,….p0.7实现效果。 2、照接线图编写程序,完善给出程序,实现功能:LED灯实现从上往下依次点亮,在从下往上依次点亮。完成后实现从两侧到中间循环点亮,在从中间向外循环点亮。功能完成后循环上述过程。
2.2 芯片选型STC12C5A60S2 2.3 电路原理图2.4 关键资源说明(所应用单片机内部资源及外围接口芯片的核心说明)畅学系列开发平台一套; PC 机一台; 内部:累加器A,寄存器R4和进位标志位C以及外部外部I/O接口与P1口。
2.5 设计分析为了实现跑马灯的效果,即:LED依次点亮(循环),就是要求从P1口: P1.0至P1.7依次输出低电平,当某引脚为低电平时,其余引脚都输出高电平。 从输出的数据分析: 第一个LED点亮时,对应的是P1.0的位为0,其余位为1,组合为一个二进制位从高到低为:1111 1110,即十六 进制数0xFE;同理,第二个LED点亮对应的数为:1111 1101,化为十六进制数为0xFD。 依次类推,逐次点亮LED所对应的数据为:1111 1110、1111 1101、1111 1011、1111 0111、 1110 1111、1101 1111、1011 1111、0111 1111。 规律:数据中的二进制数0的位置依次往左移动了一位。 
2.6程序流程图
四、实验运行效果及说明LED灯实现从上往下依次点亮,再从下往上依次点亮。完成后实现从两侧到中间循环点亮,在从中间向外循环点亮。 五、思考题1、循环间隔时间通过延时怎么控制?答:通过延时程序可以控制循环间隔的时间,无论是C语言还是汇编,延时起到的作用都是不可或缺的。 Delay: MOV R0,#10 ;(1) Delay1: MOV R1,#100 ;(1*10) DJNZ R1,$ ;(2*100*10) DJNZ R0,Delay1 ;(2*10) ret ;(2) total=1+1*10+2*100*10+2*10+2=2033 time=total*1/(focse/12)
void Delay(unsigned int uiCount) { unsigned char j = 244; for(;uiCount > 0;uiCount--) while(--j); }
2、跑马灯模式如何实现间隔亮、多位同时亮等其他效果?答:间隔亮可以利用子函数DELAY三重循环控制,多位同时亮可以给多位赋初值来体现。 ORG 0000H LJMP MAIN ORG 0020H MAIN: MOV R6,#07H MOV R7,#FEH ;1111 1110 LOOP1: MOV P1,R7 LCALL DELAY MOV A,R7 RLC A MOV R7,A DJNZ R6,LOP1 MOV R6,#07H MOV R7,#7FH ;0111 1111 LOOP2: MOV P1,R7 LCALL DELAY MOV A,R7 RRC A MOV R7,A DJNZ R6,LOP2 LJMP MAIN DELAY: MOV R3,#0FFH LOOP3: MOV R4,#0FFH LOOP4: NOP DJNZ R4,LOP4 DJNZ R3,LOP3 RET END
六、实验分析与小结通过汇编语言和C语言程序分别实现使八个跑马灯从上往下,在从下往上的循环亮灯,以及实现从中间到两边,在从两边到中间的循环亮灯。此次实验中,从开始的蜂窝鸣叫测试,到后续自己编写,烧录跑马灯程序,虽然过程因为开始的不懂原理有点绕路,到后来循序渐进,还是一个比较有趣的过程。将想法变为现实,与以往的设计软件不同,此次通过程序指令使得硬件实现自己想要的功能。让自己实打实的,眼看手做去实现,挺好的。
- 三、实验程序
- 汇编:
- ORG 0000H
- LJMP START
- ORG 0100H
- START:
- MOV A , #0FFH
- CLR C
- MOV R4 , #08H
- LOOP1:
- RRC A
- MOV P1 , A
- LCALL DELAY
- DJNZ R4 ,LOOP1
- MOV A , #0FFH
- CLR C
- MOV R4 , #08H
- LOOP2:
- RLC A
- MOV P1 , A
- LCALL DELAY
- DJNZ R4 ,LOOP2
- JMP START
-
- DELAY:
- MOV R1 , #20H
- D0:
- MOV R2 , #00H
- D1:
- MOV R3 , #00H
- DJNZ R3 , $
- DJNZ R2 , D1
- DJNZ R1 , D0
- RET
- END
- 从中间往两边依次点亮,再从两边往中间依次点亮
- ORG 0000H
- LJMP START
- ORG 0100H
- START:
- MOV A,#0EFH
- MOV P1,A
- MOV R2,#08H
- LOOP1:
- MOV R6,A
- RRC A
- MOV P1,A
- LCALL DELAY
- MOV A,R6
- RLC R6
- MOV P1,A
- LCALL DELAY
- DJNZ R4,LOOP1
- MOV R4,#08H
- MOV A,#0EFH
- MOV P1,A
- MOV R4,#08H
- LOOP2:
- MOV A,#FEH
- MOV P1,A
- LCALL DELAY
- MOV R7,A
- MOV A,#07H
- MOV P1,A
- LCALL DELAY
- MOV A,R7
- RLC A
- MOV P1,A
- LCALL DELAY
- DJNZ R4,LOOP2
- CLR C
- JMP START
- DELAY:
- MOV R1,#20H
- D0:
- MOV R2,#00H
- D1:
- MOV R3,#00H
- DJNZ R3,$
- DJNZ R2,D1
- DJNZ R1,D0
- RET
- END
-
- C语言:
- #include <reg51.H>
- //延时函数,uiCount-延时参数,每加1增加0.5ms
- void Delay(unsigned int uiCount)
- {
- unsigned char j = 244;
- for(;uiCount > 0;uiCount--) while(--j);
- }
- unsigned char code table[]={ 0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff,
- };
- void Delay(unsigned int); //延时函数
- //主函数,控制LED
- void main(void)
- {
- unsigned char i;
- while(1)
- {
- for(i=0;i<16;i++) //依次点亮和熄灭8个LED
- {
- P1=table[i];
- Delay(1000);
- }
- P1=0x7f; //赋初始值
- for(i=0;i<8;i++) //循环右移点亮LED
- {
- Delay(500);
- P1>>=1;
- P1=P1|0x80; //右移后,最左端自动赋值0,把第7位置1
- }
- }
- }
复制代码
完整的Word格式文档51黑下载地址:
跑马灯.docx
(332.88 KB, 下载次数: 20)
|