实验-跑马灯(汇编语言与接口技术)

一、 实验要求

  1. 在单片机开发板的LED灯D1~D8上实现跑马灯。LED与单片机引脚连线电路如下图:

实验-跑马灯(汇编语言与接口技术)_第1张图片

  1. 单片机芯片选择AT89C51,晶振频率设为12MHz,操作参考单片机开发板使用说明。
  2. 跑马灯点亮的时间间隔为1秒。
  3. 分别用定时器的模式1和模式2实现。

二、 实验设计

2.1整体思路

  1. 在主程序中,设置循环次数、定时器初始化。且点亮第一个LED灯,再进行中断初始化,以及打开定时器,最后原地循环,等待中断。
  2. 当定时器溢出时,跳转到中断程序。在中断程序中,通过控制循环次数,来实现点亮1秒的功能。
  3. 循环结束后,LED灯右移一位,点亮下一LED灯,再返回主程序。
  4. 返回主程序中继续原地循环,等待中断来临。

2.2流程图

(1)方式一

实验-跑马灯(汇编语言与接口技术)_第2张图片(2)方式二

实验-跑马灯(汇编语言与接口技术)_第3张图片

2.3主要模块设计思路及分析

(1)定时器方式1的设计

        定时器方式1是16位的,在晶振为12MHZ的情况下(机器周期为10^-6s),最多可以定时65.536ms。由于需要点亮1秒,这里可以用50ms * 20次来实现。所以初值需要设计为:3CB0H

        由于方式1不会自动重载。所以每次进行中断时,需手动设置初值。        

(2)定时器方式二的设计

        定时器方式2是8位的,在晶振为12HZ的情况下(机器周期为10^-6s),最多可以定时0.256ms。由于需要点亮1秒,这里可以用0.2ms * 5000次来实现。所以初值需要设计为:38H

        5000次可以通过双重循环100*50来实现

        由于方式2会自动重载。所以每次进行中断时,不需要手动设置初值。只需在主程序中初始化一次即可。

(3)LED灯顺序点亮模块

        由于LED灯需要顺序点亮,且LED灯连接P2口(由电路图可知),所以可以先点亮P2.0(P2口=FEH),每次中断,左移一位,就可以点亮下一位的LED灯。

(4)主程序模块

        在主程序中,主要需要做以下:

        设堆栈指针-->设置定时器循环次数-->调用方式1/2定时-->定时器设置初值-->点亮LED灯-->设置允许中断(ET0、EA)-->启动T0计数-->原地循环,等待中断

(5)中断程序模块

        在中断程序中,需要做以下:

        设置计数器初值(方式2不用)-->进行循环1s-->左移A(点亮下一LED灯)-->点亮下一LED灯-->放回主程序

三、 实现效果

上图为跑马灯的部分过程。

四、源代码

//在单片机开发板的LED灯D1~D8上实现跑马灯   P2引脚连接
//3.跑马灯点亮的时间间隔为1秒。
//4.分别用定时器的模式1和模式2实现。--->模式1
    ORG 0000H
    LJMP MAIN

    ORG 000BH       ; 中断向量表地址,定时器0中断
    LJMP INT

    ORG 0100H
MAIN:
	MOV SP, #60H	  ;设置堆栈地址
	MOV A, #0FEH	  ;点亮P2.0引脚
	MOV R0, #20	  ;定时器循环次数为20次
	//定时器初始化
	MOV TMOD, #01H    ;方式1定时
	MOV TL0, #0B0H	  ;初值
	MOV TH0, #3CH	  ;初值

	MOV P2, A		  ;点亮LED灯
	//中断初始化
	SETB ET0		  ;允许T0中断
	SETB EA			  ;总中断允许

	SETB TR0		  ;启动T0计数

	SJMP $			  ;当前位置循环,等待中断
INT:
	PUSH ACC
	PUSH PSW

	MOV TL0, #0B0H	  ;初值
	MOV TH0, #3CH	  ;初值

	DJNZ R0, FINISH 	  ;是否已中断20次/1s ,未到1s则跳转
	MOV R0, #20	  ;定时器循环次数为20次

	MOV A, P2
	RL A			  ;循环左移
	MOV P2, A
FINISH:
	POP PSW
	POP ACC

	RETI

    END             ; 汇编结束


//在单片机开发板的LED灯D1~D8上实现跑马灯   P2引脚连接
//3.跑马灯点亮的时间间隔为1秒。
//4.分别用定时器的模式1和模式2实现。--->模式2
    ORG 0000H
    LJMP MAIN

    ORG 000BH       ; 中断向量表地址,定时器0中断
    LJMP INT

    ORG 0100H
MAIN:
	MOV SP, #60H	  ;设置堆栈指针
	MOV A, #0FEH	  ;点亮P2.0引脚
	MOV R0, #100	  ;定时器内循环,共100次
	MOV R1, #50	  ;定时器外循环,共50次	 
	//定时器初始化
	MOV TMOD, #02H    ;方式2定时
	MOV TL0, #38H	  ;初值
	MOV TH0, #38H	  ;初值

	MOV P2, A		  ;点亮LED灯
	//中断初始化
	SETB ET0		  ;允许T0中断
	SETB EA			  ;总中断允许

	SETB TR0		  ;启动T0计数

	SJMP $			  ;当前位置循环,等待中断
INT:
	PUSH ACC
	PUSH PSW
	
LOOP:
	DJNZ R0, FINISH 	  ;R0不为0,继续循环,直到10次结束
	MOV R0, #100
	DJNZ R1, FINISH
	MOV R0, #100
	MOV R1, #50	  ;定时器外循环,共50次

	MOV A, P2
	RL A			  ;循环左移
	MOV P2, A
FINISH:
	POP PSW
	POP ACC
	RETI

    END             ; 汇编结束 	 

五、总结和思考

(1)本次跑马灯实验的中断编程思维框架:从定时器配置、中断使能到服务程序编写。通过两种定时模式的对比实现,不仅理解了技术手册上的理论参数,更获得了宝贵的调试经验。最大的收获是认识到嵌入式开发中"硬件特性决定软件设计"的基本原则——12MHz晶振的机器周期直接决定了我们的定时方案选择。

(2)未来可以进一步探索:① 使用PCA模块实现更精确的定时 ② 加入看门狗防止程序跑飞 ③ 通过Proteus仿真验证不同晶振频率下的定时效果。这些延伸实践将帮助建立更完整的嵌入式时序控制知识体系。

你可能感兴趣的:(单片机,嵌入式硬件)