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加一

相关推荐
代码游侠几秒前
学习笔记——嵌入式与51单片机学习
单片机·嵌入式硬件·学习·51单片机
代码游侠10 分钟前
学习笔记——嵌入式系统与51单片机核心
笔记·单片机·嵌入式硬件·学习·51单片机
小郭团队40 分钟前
教育公平的探索
大数据·人工智能·嵌入式硬件·算法·硬件架构
lemoncat842 分钟前
PCB线圈电感设计器推荐
嵌入式硬件·pcb
TEC_INO1 小时前
STM32_10:SPI
stm32·单片机·嵌入式硬件
polarislove02141 小时前
10.3[ADC]采样时间和转换时间-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
创思通信1 小时前
STM32L151RCT6 BC20 采集温湿度DHT11 采集GPS定位 和ADC发送到最新版本ONENET物联网开放平台
stm32·嵌入式硬件·物联网
__万波__1 小时前
STM32建立完全空白的工程
stm32·单片机·嵌入式硬件
松涛和鸣1 小时前
51、51单片机
c语言·网络·单片机·嵌入式硬件·tcp/ip·51单片机
麒qiqi2 小时前
51 单片机入门详解:从基础概念到实战开发
单片机·嵌入式硬件