您现在的位置是:首页 >其他 >汇编十二、定时/计数器网站首页其他

汇编十二、定时/计数器

朱嘉鼎 2024-06-17 11:28:39
简介汇编十二、定时/计数器

1、功能

        定时器/计数器的核心部件是一个加法(也有减法)的计数器,其本质是对脉冲进行计数。只是计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟周期或者每6个时钟周期得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚(T0为P3.4,T1为P3.5),则为计数方式,每来一个脉冲加1。

(1)定时功能,完成一些周期性的操作。

(2)计数功能:进行外部脉冲计数。

补充:单片机涉及到的定时方法。

(1)软件定时。(让CPU无意义的执行程序消耗时间)

(2)硬件定时。(555)

(3)可编程定时器。(8253)

2、定时器的一个时钟周期

(1)定时器时钟为SYSclk12M进行12分频,即定时器时钟为1Mhz。

(2时钟周期为1/1MHz = 1us,即计数值加1,定时1uS。

3、相关的寄存器

(1)TCON:定时器控制寄存器

(2)TMOD:定时器模式寄存器

(3)TLx

(4)THx

4、示例程序实现功能

(1)实现8颗LED灯呈流水灯依次被点亮;静态数码管显示数值每秒加1,循环依次显示0-9。

(2)间隔的1S采用定时/计数器定时。

5、原理图及硬件连接

5.1、LED灯

(1)51单片机P1端口接八个共阴极LED灯,即IO口输出高电平,LED点亮。

5.2、静态数码管

(1)P0端口连接静态数码管(JP3)

(2)IO口对应数码段。

P0.0对应aP0.1对应bP0.2对应cP0.3对应d
P0.4对应eP0.5对应fP0.6对应gP0.7对应dp

(3)数码管为共阳数码管。

(4)P0端口的对应IO输出低电平,对应数码段被点亮,输出高电平,数码管熄灭。

6、示例程序

6.1、注意点

(1)中断产生到中断响应是需要时间。

(2)中断服务程序中不要有延时程序。

6.2、代码

;使用P0接静态数码管
;使用P1接LED灯
;-------------------------------------	
	ORG 0000H     ;ORG为程序段说明伪指令,它向汇编程序说明该程序段的起始地址,所以可以当中断向量地址用
	LJMP L_Main   ;跳转到L_Main标号处
	ORG 000BH     ;定时器0中断向量地址
	LJMP I_T0     ;跳转到I_T0标号处
	
	;ORG 0030H     ;记不得这句有啥作用了,后续删了试试
		
L_Main:
	;your code
	;初始化定时器,1秒 = 50毫秒 * 20次
	MOV TMOD,#0x01              ;配置为16位定时器/计数器,TL0、TH0全用
	MOV TH0,#HIGH(65536-50000)  ;定时器计数值溢出才产生中断,取高八位
	MOV TL0,#LOW(65536-50000)   ;51单片机定时器为加法定时器,取低八位
	SETB EA                     ;总中断允许控制位设置为1
	SETB ET0                    ;T0溢出中断允许位设置为1
	SETB TR0                    ;打开定时器
	
	MOV DPTR,#T_table           ;T_table所在地址赋值给DPTR
	MOV R0,#0x00                ;立即数赋值给R0,给R0赋初值,在中断中用到
	MOV P0,#0xC0                ;设置数码管显示的初始值
	MOV R2,#20                  ;进入定时器中断20次有1秒   
	
	;流水灯
	MOV A,#0x01        ;把立即数0x01赋值给累加器A
L_loop:
	MOV P1,A          
	LCALL F_Delay1S    ;调用子程序,函数延时1秒
	RL	A              ;累加器循环左移
	LJMP L_loop        ;跳到标号L_loop处
;---------------------------------------
F_Delay1S:                 ;1S = 2us*500000	(50*100*100)
	MOV R7,#50             ;立即数50赋值给寄存器R7
L_loop2:
	MOV R6,#100            ;立即数100赋值给寄存器R6
L_loop1:
  	MOV R5,#100            ;立即数100赋值给R5寄存器
	DJNZ R5,$	           ;R5寄存器值减1,不是零就跳转到当前位置,即减到零才跳出循环
	DJNZ R6,L_loop1        ;相当于了100*100了
	DJNZ R7,L_loop2        ;相当于50*100*100了
	RET
	
;---------------------------------------
I_T0:
	PUSH ACC           ;ACC地址单元中的数据压栈
	PUSH PSW           ;程序状态字寄存器压栈
	MOV TH0,#HIGH(65536-50000)
	MOV TL0,#LOW(65536-50000)
	DJNZ R2,L_exit      ;寄存器值减1,不等于0就跳转,不等于0直接出定时中断
	MOV R2,#20
	;数码管+1
	INC R0              ;R0寄存器值加1      
	CJNE R0,#10,L_Next  ;如果R0不等于10就跳转到L_next
	MOV R0,#0x00
L_Next:
	MOV A,R0
	MOVC A,@A+DPTR      ;基地址变址
	MOV P0,A   	
L_exit:
	POP PSW             ;程序状态字寄存器出栈
	POP ACC             ;ACC地址单元中的数据出栈
	RETI                ;中断返回
	
;---------------------------------------
T_table:
	;声明并初始化数据。
	;声明数据的本质就是:在内存中占用一块空间 ;
	;初始化数据的本质就是:给这个空间赋予一个值 。
	DB	0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90  
	END
		
		


 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。