51单片机定时器函数分享(8051汇编)

注:本篇文章部分基于上一篇数码管的文章,如果有关于数码管显示函数不懂的可以先看一下上一篇文章: 51单片机数码管显示函数

另外,关于定时器与中断系统的更多详细介绍,可以看一下我一年半前写的文章(当时讲解是基于C语言的):定时器与中断系统

目录

源代码

电路图

代码框架

代码使用

第一部分

第二部分

函数说明

功能拓展

拓展电路图

LED轮闪函数

基础配置

调用LED闪烁函数

拓展部分总代码

拓展部分实现效果


源代码

cpp 复制代码
ORG 00H
	SMGPTR DATA 30H
	DISDATA DATA 31H
		//DISDATA: 31H - 36H (DATA Arr)
	SMGBIN DATA 40H
	TEMP1 DATA 41H
	TEMP2 DATA 42H
	TEMP3 DATA 43H
		
	SEC DATA 50H
	COUNT1 DATA 51H
	COUNT2 DATA 52H
	COUNT3 DATA 53H
		
	LJMP START
	
	;ORG 000BH
	;LJMP T0M2_ISR
	;LJMP T0M1_ISR
	ORG 001BH
	;LJMP T1M1_ISR
	LJMP T1M2_ISR
	
	
	ORG 30H
	START:
	MOV SEC,#0
	MOV COUNT1,#0
	MOV COUNT2,#0
	MOV COUNT3,#0
	
	;LCALL T0M1_INIT
	;LCALL T1M1_INIT
	;LCALL T0M2_INIT
	LCALL T1M2_INIT
	
	LOOP:
		MOV A,SEC
		MOV B,#10
		DIV AB
		
		MOV DISDATA+0,A
		MOV DISDATA+1,B
		LCALL DISPLAY
	SJMP LOOP
			
	SJMP START
	/////////////////////////////////////////////////////////
	//TIMER0 MODE1
	T0M1_INIT:
		MOV TMOD,#01H
		MOV TH0,#(65535-50000)/256
		MOV TL0,#(65535-50000)MOD 256
		SETB EA
		SETB ET0
		SETB TR0
	RET
	
	T0M1_ISR:
		MOV TH0,#(65535-50000)/256
		MOV TL0,#(65536-50000)MOD 256
		INC COUNT1
		MOV R1,COUNT1
		CJNE R1,#4,T0M1_NEXT   //50ms*4=200ms
		MOV COUNT1,#0
		
		INC COUNT2
		MOV R1,COUNT2
		CJNE R1,#5,T0M1_NEXT	//200ms*5=1s
		MOV COUNT2,#0
		
		INC SEC
		MOV R1,SEC
		CJNE R1,#100,T0M1_NEXT
		MOV SEC,#0
	T0M1_NEXT:RETI
	/////////////////////////////////////////////////////////
	//TIMER1 MODE1
	T1M1_INIT:
		MOV TMOD,#10H
		MOV TH1,#(65535-50000)/256
		MOV TL1,#(65535-50000)MOD 256
		SETB EA
		SETB ET1
		SETB TR1
	RET
	
	T1M1_ISR:
		MOV TH1,#(65535-50000)/256
		MOV TL1,#(65536-50000)MOD 256
		INC COUNT1
		MOV R1,COUNT1
		CJNE R1,#4,T1M1_NEXT	//50ms*4=200ms
		MOV COUNT1,#0			
		
		INC COUNT2
		MOV R1,COUNT2
		CJNE R1,#5,T1M1_NEXT	//200ms*5=1s
		MOV COUNT2,#0
		
		INC SEC
		MOV R1,SEC
		CJNE R1,#100,T1M1_NEXT
		MOV SEC,#0
	T1M1_NEXT:RETI
	
	/////////////////////////////////////////////////////////
	//TIMER0 MODE2
	T0M2_INIT:
		MOV TMOD,#02H
		MOV TH0,#256-200
		MOV TL0,#256-200		
		SETB EA
		SETB ET0
		SETB TR0
	RET
	
	T0M2_ISR:
		INC COUNT1
		MOV R1,COUNT1
		CJNE R1,#100,T0M2_NEXT	//0.2ms*100 = 20ms
		MOV COUNT1,#0
		
		INC COUNT2
		MOV R1,COUNT2
		CJNE R1,#10,T0M2_NEXT	//20ms*10=200ms
		MOV COUNT2,#0
		
		INC COUNT3
		MOV R1,COUNT3
		CJNE R1,#5,T0M2_NEXT	//200ms*5=1s
		MOV COUNT3,#0
		
		INC SEC
		MOV R1,SEC
		CJNE R1,#100,T0M2_NEXT
		MOV SEC,#0
	T0M2_NEXT:RETI
	/////////////////////////////////////////////////////////
	//TIMER1 MODE2
	T1M2_INIT:
		MOV TMOD,#20H
		MOV TH1,#256-200
		MOV TL1,#256-200		
		SETB EA
		SETB ET1
		SETB TR1
	RET
	
	T1M2_ISR:
		INC COUNT1
		MOV R1,COUNT1
		CJNE R1,#100,T1M2_NEXT	//0.2ms*100 = 20ms
		MOV COUNT1,#0
		
		INC COUNT2
		MOV R1,COUNT2
		CJNE R1,#10,T1M2_NEXT	//20ms*10=200ms
		MOV COUNT2,#0
		
		INC COUNT3
		MOV R1,COUNT3
		CJNE R1,#5,T1M2_NEXT	//200ms*5=1s
		MOV COUNT3,#0
		
		INC SEC
		MOV R1,SEC
		CJNE R1,#100,T1M2_NEXT
		MOV SEC,#0
	T1M2_NEXT:RETI
	/////////////////////////////////////////////////////////
	DISPLAY:
		MOV SMGBIN,#01111111B
		MOV SMGPTR,#0
		
		DIS1:
			MOV A,SMGBIN
			RL A
			MOV SMGBIN,A
			MOV P2,SMGBIN	//BIT CHOICE
			
			MOV A,SMGPTR
			ADD A,#DISDATA
			MOV R0, A
			MOV TEMP1,@R0  //DATA CHOICE
			
			MOV DPTR,#TAB
			MOV A,TEMP1
			MOVC A,@A+DPTR
			MOV P0,A
			
			LCALL DELAY
			
			INC SMGPTR
			MOV A,SMGPTR
			CJNE A,#6,DIS1
	RET
	/////////////////////////
	DELAY:MOV R5,#1      //1ms
	   DELAY3:MOV R6,#2
	   DELAY2:MOV R7,#248
	   DELAY1:DJNZ R7,DELAY1
		  DJNZ R6,DELAY2
		  DJNZ R5,DELAY3
	RET	
	////////////////////////
	TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END

代码作用就是每1s实现让SEC+1,并且显示在数码管上,这里相较于上期文章有点修改,就是DELAY函数的时间从10ms改成了1ms,尽量使得对中断的干扰没有那么大

电路图

代码框架

讲使用之前先讲一下框架,主要框架就是

ORG 00H

//变量定义

LJMP START

//中断向量地址(四选一)

;ORG 000BH

;LJMP T0M2_ISR

;LJMP T0M1_ISR

ORG 001BH

;LJMP T1M1_ISR

LJMP T1M2_ISR

ORG 30H

START:

//初始化变量

MOV SEC,#0

MOV COUNT1,#0

MOV COUNT2,#0

MOV COUNT3,#0

//初始化定时器(四选一)

;LCALL T0M1_INIT

;LCALL T1M1_INIT

;LCALL T0M2_INIT

LCALL T1M2_INIT

LOOP:

//取出数字并且显示

MOV A,SEC

MOV B,#10

DIV AB

MOV DISDATA+0,A

MOV DISDATA+1,B

LCALL DISPLAY

SJMP LOOP

SJMP START

//下面是各种函数定义

代码使用

代码使用主要配置两个部分

第一部分

这里的配置是ORG 000BH对应定时器0(包含定时器0模式1和2) ,然后ORG001BH对应定时器1(包含定时器1模式1和2),写完定时器起始地址之后立刻接上中断函数的名字

例如上面就是调用定时器1模式2,所以用ORG 001BH接上LJMP T1M2_ISR(定时器1模式2的中断函数)

假设我需要调用定时器1模式1,就用ORG 000BH后面接上LJMP T0M1_ISR(定时器0模式2的中断函数)

当然,要注意,如果确定了一个中断函数和模式,整段代码就只能使用这个中断函数和模式,否则定时器就没有办法正常使用

第二部分

第二部分就是在LOOP循环前的初始化部分调用一下选择的定时器及模式初始化函数

比如这里就是调用初始化定时器1模式2的函数

函数说明

这是定时器0模式1的函数,主要分为初始化函数和中断处理函数两个部分,中断处理函数就是每50ms进入这个函数,然后执行计数,这里设置的就是50ms*4*5=1s就加一次SEC,这样我们就可以在主函数中用数码管显示SEC,实现的效果就是每秒SEC+1并且显示到数码管上的效果

当然,我们也可以在中断处理函数里调用别的函数,比如我们在这里调用函数

这里调用的函数就是在200ms计数之后,就可以实现200ms执行一次这个函数,比如每200ms控制LED开关之类的作用,当然,这里的时间间隔也可以自己控制,实现更多的功能,比如下面

功能拓展

拓展电路图

如图,在P3.0和P3.1分别接了LED1和LED2,并且LED共阳极,通过控制P3.0和P3.1让LED闪烁,这里的拓展功能是使用上面的函数,用定时器1工作方式2实现两个LED轮流发光,同时保留秒表每秒+1的作用

LED轮闪函数

这里通过判断LEDMODE来判断状态,如果LEDMODE为1就执行模式1并且把LEDMODE置为0,如果LEDMODE为0就执行模式2并且把LEDMODE置为1,如此循环,实现LED的循环闪烁

基础配置

同上面讲述的时候说的,配置主要两个部分,一是选择中断地址,二是选择初始化函数

调用LED闪烁函数

要求每200ms实现LED闪烁变换,就在中断处理函数200ms位置调用LED_CHANGE函数

如此即可....

拓展部分总代码

cpp 复制代码
ORG 00H
	SMGPTR DATA 30H
	DISDATA DATA 31H
		//DISDATA: 31H - 36H (DATA Arr)
	SMGBIN DATA 40H
	TEMP1 DATA 41H
	TEMP2 DATA 42H
	TEMP3 DATA 43H
		
	SEC DATA 50H
	COUNT1 DATA 51H
	COUNT2 DATA 52H
	COUNT3 DATA 53H
	
	LEDMODE DATA 54H
		
	LJMP START
	
	ORG 001BH
	LJMP T1M2_ISR
	
	ORG 30H
	START:
	MOV SEC,#0
	MOV COUNT1,#0
	MOV COUNT2,#0
	MOV COUNT3,#0
	
	LCALL T1M2_INIT
	
	LOOP:
		MOV A,SEC
		MOV B,#10
		DIV AB
		
		MOV DISDATA+0,A
		MOV DISDATA+1,B
		LCALL DISPLAY
	SJMP LOOP
			
	SJMP START
	/////////////////////////////////////////////////////////
	LED_CHANGE:
		MOV A,LEDMODE
		CJNE A,#1,LEDMODE2
	LEDMODE1://LEDMODE==1
		SETB P3.0
		CLR P3.1
		MOV LEDMODE,#0
		SJMP LED_EXIT
	LEDMODE2://LEDMODE==0
		SETB P3.1
		CLR P3.0
		MOV LEDMODE,#1
	LED_EXIT:
	RET
	
	/////////////////////////////////////////////////////////
	//TIMER1 MODE2
	T1M2_INIT:
		MOV TMOD,#20H
		MOV TH1,#256-200
		MOV TL1,#256-200		
		SETB EA
		SETB ET1
		SETB TR1
	RET
	
	T1M2_ISR:
		INC COUNT1
		MOV R1,COUNT1
		CJNE R1,#100,T1M2_NEXT	//0.2ms*100 = 20ms
		MOV COUNT1,#0
		
		INC COUNT2
		MOV R1,COUNT2
		CJNE R1,#10,T1M2_NEXT	//20ms*10=200ms
		MOV COUNT2,#0
		
		LCALL LED_CHANGE
		
		INC COUNT3
		MOV R1,COUNT3
		CJNE R1,#5,T1M2_NEXT	//200ms*5=1s
		MOV COUNT3,#0
		
		INC SEC
		MOV R1,SEC
		CJNE R1,#100,T1M2_NEXT
		MOV SEC,#0
	T1M2_NEXT:RETI
	/////////////////////////////////////////////////////////
	DISPLAY:
		MOV SMGBIN,#01111111B
		MOV SMGPTR,#0
		
		DIS1:
			MOV A,SMGBIN
			RL A
			MOV SMGBIN,A
			MOV P2,SMGBIN	//BIT CHOICE
			
			MOV A,SMGPTR
			ADD A,#DISDATA
			MOV R0, A
			MOV TEMP1,@R0  //DATA CHOICE
			
			MOV DPTR,#TAB
			MOV A,TEMP1
			MOVC A,@A+DPTR
			MOV P0,A
			
			LCALL DELAY
			
			INC SMGPTR
			MOV A,SMGPTR
			CJNE A,#6,DIS1
	RET
	/////////////////////////
	DELAY:MOV R5,#1      //1ms
	   DELAY3:MOV R6,#2
	   DELAY2:MOV R7,#248
	   DELAY1:DJNZ R7,DELAY1
		  DJNZ R6,DELAY2
		  DJNZ R5,DELAY3
	RET	
	////////////////////////
	TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END

拓展部分实现效果

LED以200ms周期循环闪烁,定时器1s加一

相关推荐
许嵩663 小时前
virtual_clock
单片机·嵌入式硬件
EVERSPIN3 小时前
N32H高性能32位MCU在具身机器人上的应用
单片机·嵌入式硬件·机器人·32位mcu·高性能32位mcu·n32h系列
泰勒朗斯3 小时前
STM32 几种烧录方式
stm32·单片机·嵌入式硬件
清风6666664 小时前
基于单片机的多波形信号发生器设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
深圳市青牛科技实业有限公司 小芋圆5 小时前
30V N 沟道 MOSFET SP30N06NK 全面解析:参数、特性与应用场景
人工智能·单片机·嵌入式硬件·无人机·高频dc-dc谐振变换器·笔记本电脑开合检测
YeGop6 小时前
51单片机汇编实现DHT11读取温湿度
汇编·嵌入式硬件·51单片机
点灯小铭9 小时前
基于单片机的超声波人体感应PWM自动调光灯设计与实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
玄奕子13 小时前
F280049C学习笔记之EPWM
单片机·嵌入式硬件·dsp开发·ti c2000·f280049c
资料,小偿14 小时前
8086汇编语言定制,8086仿真proteus8086定制,emu8086汇编语言
汇编