基于51单片机的定时器

发布者:gamma14最新更新时间:2017-12-26 来源: eefocus关键字:51单片机  定时器 手机看文章 扫描二维码
随时随地手机看文章

    在这里,小编带你一起 从零开始学51单片机定时器。基于单片机的定时器电路原理图如下所示:
 

34


  我们学单片机是首先学的就是 LED 闪烁,那是用延时程序做的,现在回想起来,这样做不很恰当,为什么呢?我们的主程序做了灯的闪烁,就不能再干其它的事了,难道单片机只能这样工作吗?当然不是,我们能用定时器来实现灯的闪烁的功能。

      例 1:查询方式

      ORG 0000H

      AJMP START

      ORG 30H

      START:

      MOV P1,#0FFH ;关所 灯

      MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1

      MOV TH0,#15H

      MOV TL0,#0A0H ;即数 5536

      SETB TR0 ;定时/计数器 0 开始运行

      LOOP:JBC TF0,NEXT ;如果 TF0 等于 1,则清 TF0 并转 NEXT 处

      AJMP LOOP ;不然跳转到 LOOP 处运行

      NEXT:CPL P1.0

      MOV TH0,#15H

      MOV TL0,#9FH;重置定时/计数器的初值

      AJMP LOOP

      END AJMP LOOP

      END

    键入程序,看到了什么?灯在闪烁了,这可是用定时器做的,不再是主程序的循环了。简单地分析一下程序,为什么用 JBC 呢?TF0 是定时/计数器 0 的溢出标记位,当定时器产生溢出后,该位由 0 变 1,所以查询该位就可知宇时时间是否已到。该位为 1 后,要用软件将标记位清 0,以便下一次定时是间到时该位由 0 变 1,所以用了 JBC 指令,该指位在判 1转移的同时,还将该位清 0。

      以上程序是能实现灯的闪烁了,可是主程序除了让灯闪烁外,还是不能做其他的事啊!不,不对,我们能在 LOOP:……和 AJMP LOOP 指令之间插入一些指令来做其他的事情,只要保证执行这些指令的时间少于定时时间就行了。那我们在用软件延时程序的时候不是也能用一些指令来替代 DJNZ 吗?是的,但是那就要求你精确计算所用指令的时间,然后再减去对应的 DJNZ 循环次数,很不方便,而现在只要求所用指令的时间少于定时时间就行,显然要求低了。当然,这样的办法还是不好,所以我们常用以下的办法来实现。

      程序 2:用中断实现

      ORG 0000H

      AJMP START

      ORG 000BH ;定时器 0 的中断向量地址

      AJMP TIME0 ;跳转到真正的定时器程序处

      ORG 30H

      START:

      MOV P1,#0FFH ;关所 灯

      MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1

      MOV TH0,#15H

      MOV TL0,#0A0H ;即数 5536

      SETB EA ;开总中断允许

      SETB ET0 ;开定时/计数器 0 允许

      SETB TR0 ;定时/计数器 0 开始运行

      LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

      TIME0: ;定时器 0 的中断处理程序

      PUSH ACC

      PUSH PSW ;将 PSW 和 ACC 推入堆栈保护

      CPL P1.0

      MOV TH0,#15H

      MOV TL0,#0A0H ;重置定时常数

      POP PSW

      POP ACC

      RETI

      END

      上面的例程中,定时时间一到,TF0 由 0 变 1,就会引发中断,CPU 将自动转至 000B处寻找程序并执行,由于留给定时器中断的空间只有 8 个字节,显然不足以写下所有有中断处理程序,所以在 000B 处安排一条跳转指令,转到实际处理中断的程序处,这样,中断程序能写在任意地方,也能写任意长度了。进入定时中断后,首先要保存当前的一些状态,程序中只 演示了保存存 ACC 和 PSW,实际工作中应该根据需要将可能会改变的单元的值都推入堆栈进行保护(本程序中实际不需保存护任何值,这里只作个演示)。

    上面的两个单片机程序运行后,我们发现灯的闪烁非常快,根本分辨不出来,只是视觉上感到灯有些晃动而已,为什么呢?我们能计算一下,定时器中预置的数是 5536,所以每计 60000 个脉冲就是定时时间到,这 60000 个脉冲的时间是多少呢?我们的晶体震荡器 是12M,所以就是 60000 微秒,即 60 毫秒,因此速度是非常快的。如果我想实现一个 1S 的定时,该怎么办呢?在该晶体震荡器濒率下,最长的定时也就是 65。536 个毫秒啊!上面给出 一个例程。

      ORG 0000H

      AJMP START

      ORG 000BH ;定时器 0 的中断向量地址

      AJMP TIME0 ;跳转到真正的定时器程序处

      ORG 30H

      START:

      MOV P1,#0FFH ;关所 灯

      MOV 30H,#00H ;软件计数器预清 0

      MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1

      MOV TH0,#3CH

      MOV TL0,#0B0H ;即数 15536

      SETB EA ;开总中断允许

      SETB ET0 ;开定时/计数器 0 允许

      SETB TR0 ;定时/计数器 0 开始运行

      LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

      TIME0: ;定时器 0 的中断处理程序

      PUSH ACC

      PUSH PSW ;将 PSW 和 ACC 推入堆栈保护

      INC 30H

      MOV A,30H

      CJNE A,#20,T_RET ;30H 单元中的值到了 20 了吗?

      T_L1: CPL P1.0 ;到了,取反 P10

      MOV 30H,#0 ;清软件计数器

      T_RET:

      MOV TH0,#15H

      MOV TL0,#9FH ;重置定时常数

      POP PSW

      POP ACC

      RETI

      END

    先自己分析一下,看看是怎么实现的?这里采用了软件计数器的概念,思路是这样的,先用定时/计数器 0 做一个 50 毫秒的定时器,定时是间到了以后并不是立即取反 P10,而是将软件计数器中的值加 1,如果软件计数器计到了 20,就取反 P10,并清掉软件计数器中的值,不然直接返回,这样,就变成了 20 次定时中断才取反一次 P10,因此定时时间就延长了成了 20*50 即 1000 毫秒了。

      这个思路在工程中是非常有用的,有的时候我们需要若干个定时器,可 51 中总共才有 2个,怎么办呢?其实,只要这几个定时的时间有一定的公约数,我们就能用软件定时器加以实现,如我要实现 P10 口所接灯按 1S 每次,而 P11 口所接灯按 2S 每次闪烁,怎么实现呢?对了我们用两个计数器,一个在它计到 20 时,取反 P10,并清零,就如上面所示,另一个计到 40 取反 P11,然后清 0,不就行了吗?这部份的程序如下

      ORG 0000H

      AJMP START

      ORG 000BH ;定时器 0 的中断向量地址

      AJMP TIME0 ;跳转到真正的定时器程序处

      ORG 30H

      START:

      MOV P1,#0FFH ;关所 灯

      MOV 30H,#00H ;软件计数器预清 0

      MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1

      MOV TH0,#3CH

      MOV TL0,#0B0H ;即数 15536

      SETB EA ;开总中断允许

      SETB ET0 ;开定时/计数器 0 允许

      SETB TR0 ;定时/计数器 0 开始运行

      LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

      TIME0: ;定时器 0 的中断处理程序

      PUSH ACC

      PUSH PSW ;将 PSW 和 ACC 推入堆栈保护

      INC 30H

      INC 31H ;两个计数器都加 1

      MOV A,30H

      CJNE A,#20,T_NEXT ;30H 单元中的值到了 20 了吗?

      T_L1: CPL P1.0 ;到了,取反 P10

      MOV 30H,#0 ;清软件计数器

      T_NEXT:

      MOV A,31H

      CJNE A,#40,T_RET ;31h 单元中的值到 40 了吗?

      T_L2:

      CPL P1.1

      MOV 31H,#0 ;到了,取反 P11,清计数器,返回

      T_RET:

      MOV TH0,#15H

      MOV TL0,#9FH ;重置定时常数

      POP PSW

      POP ACC

      RETI

  END


关键字:51单片机  定时器 引用地址:基于51单片机的定时器

上一篇:51单片机如何进行ROM外扩分析
下一篇:用51单片机设计解决电动车在跷跷板上的运行和控制问题

推荐阅读最新更新时间:2024-03-16 15:50

基于51单片机超声波避障+蓝牙遥控智能小车
单片机源程序如下: #include reg52.h #include intrins.h typedef unsigned char u8; typedef unsigned int u16; typedef unsigned long u32; sbit Sevro_moto_pwm = P2^6; //接舵机信号端输入PWM信号调节速度 sbit ECHO= P1^1; //超声波接口定义 sbit TRIG= P1^0; //超声波接口定义 sbit PWM1 = P2^5; //左电机高电平 sbit PWM2 = P2^
[单片机]
STM32 学习笔记_TIME定时器详解1
STM32 单片机的定时器的确很强大,参考说明书中就占了一百多页,占参考手册1/4 有多了。 STM32的定时器分了好几个类别,各个类别针对功能作用都不大相同。 分有: 一、高级定时器 二、通用定时器 三、基本定时器 四、看门狗定时器 五、SysTick定时器 其中看门狗定时器和SysTick定时器本篇笔记阐述,这里主要记下对平时使用定时器作用的计时计数器的一些自己的理解。 按照参考手册中的定义 高级定时器 通用定时器基本定时器,这三个定时器成上下级的关系,即基本定时器有的功能通用定时器都有,而且还增加了向下、向上/向下计数器、PWM生成、输出比较、输入捕获等等功能;而高级定时器又包含了通用定时器的所有功能,另外还增加了死区互补输
[单片机]
STM32 学习笔记_TIME<font color='red'>定时器</font>详解1
定时器进行计数的一个简单例子
/* 注:该程序主要是如何运用定时器进行计数,体现模块化的子函数,是一个比较浅显的程序 */ #include reg52.h //头文件 #define uchar unsigned char //宏定义 #define uint unsigned int uchar count; //定义全局变量 void display_led() //led显示子函数 { if(count==20) //每隔1S发生变化(晶振为:12MHZ) { count=0; //计数清零,以便下次计数 P2=~P2; //P2的值取反 P2=P2 1; //P2的值左移 P2=~P2; if(P2==0xff) //如果最后一个L
[单片机]
STM32CubeMX之定时器控制微秒延时详解
写在前面的话,为什么另需定时器进行微秒级延时。 1.在HAL固件库中只有使用Systick作为延时计数器,毫秒级延时HAL_Delay()。为了增加精确的微秒级延时,一般都是更改Systick配置参数,但HAL固件库许多地方都使用了HAL_Delay()函数,因此建议大家不要修改系统自动配置的Systick参数; 2.个人觉得到加入操作系统时要占用Systick,而MCU系统自身的时基还要选择其他的定时器,综上所述,对Systick做的更改基本白搭; 因此采用定时器控制微妙延时的方法,是比较灵活的。需要用户增加的代码很少,经济实用,节能环保- -; 步骤1.配置时钟 注意,一定要确定红色部分标记的晶振频率要与实际的晶振保持一致。
[单片机]
51单片机定时器TMOD与TCON、SCON
51单片机中断级别 中断源 默认中断级别 序号(C语言用) INT0---外部中断0 最高 0 T0 ---定时器/计数器0中断 第2 1 INT1---外部中断1 第3 2 T1 ----定时器/计数器1中断 第4 3 TX/RX---串行口中断 第5 4 T2 ---定时器/计数器2中断 最低 5 ———————————————— 定时器/计数器模式控制寄存器TMOD是一个逐位定义的8位寄存器,但只能使用字节寻址,其字节地址为89H。 D0~D3为
[单片机]
<font color='red'>51单片机</font><font color='red'>定时器</font>TMOD与TCON、SCON
51单片机控制SL811HS的USB主机底层驱动
引言 基于USB接口的设备使用方便,性价比高,因此在人们的工作和生活中得到了广泛的应用,如U盘,移动硬盘,光驱,USB摄像头,USB鼠标键盘等,同时,51系列单片机以其成熟的技术和高性价比吸引了大量国内用户,被广泛应用于测控和自动化领域,因此,如果在51单片机系统中增加USB主机接口,实现对USB从机设备的控制,则该单片机系统可以充分利用现有的各种USB从机设备,大大扩展单片机系统功能。 本设计实现了在51单片机系统中增加USB主机功能,采用普通51单片机外接专用USB接口芯片的方案,这种方案虽然会使系统传输速度受到限制,而且在稳定性有所欠缺,但此方案设计灵活性高,且易于移植,为低成本产品的开发提供了广阔前景,设计中采用51单
[单片机]
51单片机串口通信的原理实例
一、原理简介 51单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。 与之前一样,首先我们来了解单片机串口相关的寄存器。 SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。从而控制外部两条独立的收发信号线RXD(P3.0)、TXD(P3.1)
[单片机]
<font color='red'>51单片机</font>串口通信的原理实例
STM32F103标准库开发---定时器中断实验---通用定时器TIM3使用
一、STM32F103定时器 二、STM32F103通用定时器 1. 主要功能 通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括: 位于低速的APB1总线上(注意:高级定时器是在高速的APB2总线上); 16位向上、向下、向上/向下自动装载计数器(TIMx_CNT); 16位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为1~65536之间的任意数值; 4个独立通道(TIMx_CH1~4),这些通道可以用来作为:输入捕获、输出比较、PWM生成(边缘或中间对齐模式)、单脉冲模式输出; 使用外部信号控制定时器和定时器互连的同步电路; 如下事件发生时产生中断/DMA:更新(计数
[单片机]
STM32F103标准库开发---<font color='red'>定时器</font>中断实验---通用<font color='red'>定时器</font>TIM3使用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved