89C51单片机定时/计数器0

发布者:灵感发电站最新更新时间:2015-01-15 来源: 51hei关键字:89C51  单片机  定时  计数器 手机看文章 扫描二维码
随时随地手机看文章

89C51单片机的定时计数功能由特殊功能寄存器TMOD和TCON共同控制。
TMOD没有位地址,不能进行位操作,其每位的名称和功能如下:
TMOD:GATE C/T1  M1 M0 GATE  C/T1   M1  M0
                         D7          D6           D5    D4       D3          D2         D1      D0
 GATE       C/T1      M1     M0    控制定时计时器1;
 GATE       C/T0      M1     M0   控制定时计时器0;
GATE=0时,定时计数信号是T0脚状态(P3.4)或机器周期(C/T=0计机器周期,即定时,C/T=1,计T0脚的状态,即计数),计数开始开关是TR0(0关闭计数,1开始计数)。
GATE=1时,定时计数功能由T0脚(P3.4)或者机器周期确定(C/T=0计数机器周期,即定时,C/T=1,计数T0脚的变化状态,即计数),计数开始开关由TR0(0关闭计数,1开始计数)和INT0(管脚P3.2)共同确定。
 M1M0是计数方式选择:计数在TH0和TL0进行。
 00为方式0,13位(TH0的8位和TL0的低5位)二进制计数器,由0可数到2的13次方-1;
 01为方式1,16位二进制计数器,由0可数到2的16次方-1;
 10为方式2,8位二进制计数器,TH0放计数初值,计数在TL0进行,溢出后自动将 
                     TH0中的初值装入TL0;
11为方式3,TH0是个8为计数器,HL0是个8位计数器。两个计数器相互独立。
T1和T0功能相同。
特殊功能寄存器TCON,可以位操作,但一般不用位地址,而用位的功能名称:
位地址:8FH  8EH  8DH  8Ch  8Bh  8Ah  89H  88H
TCON :TF1  TR1  TF0   TR0   IE1   IT1   IE0   IT0 
               D7    D6    D5    D4    D3   D2   D1    D0 
TF0是T0计数标志位:定时计数溢出时,该位被自动置1,中断计数结束后自动清0.
TR0是计数开关,GATE=0时,TR0=1打开计数,0关闭。当GATE=1时,和INT0一起控制计数器打开,即GATE=1,TR0=1,INT0=1才可打开计数,否则关闭。
定时/计数时,由TH0 TL0的值开始加1计数到FFFFH满,再计数就溢出,如果是定时/计数模式,溢出后将TF0置1,计数定时结束,如果是中断模式,中断请求由硬件给TF0置1,计数结束后,也就是中断结束后,自动将TF0清0。
/***************定时器定时50ms,在计数20下为1秒,显示60秒计时(查询模式)***********/
#include
#include
#define uchar unsigned char
#define uint unsigned int

int yu[]={
               0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
             };
int t,k,dat;
void delay(int ms)
{
 while(ms--)
   {
    int i;
    for(i=0;i<30;i++);
   }
}
void Timer0()
   {       
     if(TF0==1)//查询TF0为1,说明计数满了,计数结束。
         {
          t++;
          TH0=0x3c;//这里是计数满后重新装入计数初值.也可TH0=(65536-5000)/256
          TL0=0xb0;//计数溢出后再次计数从这里开始,也可TL0=(65536-5000)%256
       /*如果先计算初值麻烦,还可以用16位二进制的最大值65536-定时计数次数赋值给TH0和TL0,例如定时40ms,需对机器周期计数4000下,可以
            TH0=(65536-4000)/256;TL0=(65536-4000)%*/
          TF0=0;
         }
            //清除溢出标志
   }
void T1s()
{
  if(t==20)//计数一次50ms,20次为1秒
      {t=0;
       dat++;
       if(dat==60)//60次为1分钟
        dat=0;
      }
}
void main()
{
  TMOD=0x01;
   /*此设置(0000 0101)T0的GATE=0,C/T为0,M1M0为01。
    GATE=0,关闭INT0(P3.2)脚对计数开始的控制,只由TR0控制开始。
    C/T=0,定时功能,计数机器周期的个数。
    M1M0=01,计数方式选择方式1,16位二进制计数器,由TH0 TL0开始计数到FFFFH满
    再计数就溢出,如果是定时/计数模式,溢出后将TF0置1,计数定时结束,如果是中
    断模式清0,有硬件给TF0置1,计数结束,也就是中断结束,自动将TF0清0.
    打开计数器0中断将ET0=1,EA=1 */
  TH0=0x3c;//设置计数器计数初值50ms从3CB0H开始计数
  TL0=0xb0;//第一次从这里的设置开始计数
  TR0=1; 
  while(1)
   { 
      Timer0();
      T1s();     
     P0=yu[dat%10];
      delay(1);
      P2=0x01;   
      delay(1);
      P2=0x00;
     P0=yu[dat/10];
      delay(1);
      P2=0x02;
      delay(1);
      P2=0x00;   
   }

/*******定时/计数器0中断应用,按键没按一次数码管显示加1(中断模式)*************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
int yu[]={
               0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
             };
int k;
void delay(int ms)
{
 while(ms--)
   {
    int i;
    for(i=0;i<30;i++);
   }
}
void ddd() interrupt 1
   {
     TH0=0xff;//这里是计数满后重新装入计数初值
     TL0=0xfa;//计数溢出后再次计数从这里开始
     delay(5);
     if(TF0==0)//计数中断时TF0由硬件置1,响应中断并开始计数,计数产生溢出后自动清0,结束计数。
            {        //所以,响应中断后,查询TF0的状态可以判断中断计数是否结束
               if(k==99)
               k=0;
              else
               k++;
           }        
   }
void main()
{
  TMOD=0x05;
/*此设置(0000 0101)T0的GATE=0,C/T为1,M1M0为01。
   GATE=0,关闭INT0(P3.2)脚对计数开始的控制,只由TR0控制开始。
    C/T=1,计数功能,计数管脚T0(P3.4)的状态变化。
   M1M0=01,计数方式选择方式1,16位二进制计数器,由TH0 TL0开始计数到FFFFH满,再计数就溢出,如果是定时/计数模式,溢出后将TF0置1,计数定时结束,如果是中断模式清0,有硬件给TF0置1,计数结束,也就是中断结束,自动将TF0清0.打开计数器0中断将ET0=1,EA=1 */[page]
  TH0=0xff;//设置计数器计数初值
  TL0=0xfc;//第一次从这里的设置开始计数
  ET0=1;
  TR0=1;
  EA=1;
  while(1)
   {
   P0=yu[k%10];
      delay(1);
      P2=0x01;   
      delay(1);
      P2=0x00;
      P0=yu[k/10];
      delay(1);
      P2=0x02;
      delay(1);
      P2=0x00;   
   }
}


/******用查询模式计数
#include
#include
#define uchar unsigned char
#define uint unsigned int
int yu[]={
               0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
             };
int k;
void delay(int ms)
{
 while(ms--)
   {
    int i;
    for(i=0;i<30;i++);
   }
}
void jishu()
   {     
     if(TF0==1)//查询TF0,为1,说明计数满了,计数结束。
         {
           TH0=0xff;//这里是计数满后重新装入计数初值
           TL0=0xff;//计数溢出后再次计数从这里开始
           delay(5);
           if(k==99)
           k=0;
           else
           k++;
         }
        TF0=0;     //清除溢出标志
   }
void main()
{
  TMOD=0x05;
/*此设置(0000 0101)T0的GATE=0,C/T为1,M1M0为01。
   GATE=0,关闭INT0(P3.2)脚对计数开始的控制,只由TR0控制开始。
    C/T=1,计数功能,计数管脚T0(P3.4)的状态变化。
   M1M0=01,计数方式选择方式1,16位二进制计数器,由TH0 TL0开始计数到FFFFH满,再计数就溢出,如果是定时/计数模式,溢出后将TF0置1,计数定时结束,如果是中断模式清0,有硬件给TF0置1,计数结束,也就是中断结束,自动将TF0清0.打开计数器0中断将ET0=1,EA=1 */
  TH0=0xff;//设置计数器计数初值
  TL0=0xff;//第一次从这里的设置开始计数
  TR0=1;
  while(1)
   { 
      jishu();
   P0=yu[k%10];
      delay(1);
      P2=0x01;   
      delay(1);
      P2=0x00;
     P0=yu[k/10];
      delay(1);
      P2=0x02;
      delay(1);
      P2=0x00;   
   }
}
/**********************用定时中断设计秒表及显示****************************/

#include
#include
#define uchar unsigned char
#define uint unsigned int
int yu[]={
               0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
             };
int k,dat;
void delay(int ms)
{
 while(ms--)
   {
    int i;
    for(i=0;i<30;i++);
   }
}
void ddd() interrupt 1
   {
     TH0=(8192-4000)-(8192-4000)%32;//这里是计数满后重新装入计数初值
     TL0=(8192-4000)%32;//计数溢出后再次计数从这里开始
     delay(5);
     if(TF0==0)//计数中断时TF0由硬件置1,响应中断并开始计数,计数产生溢出后自动清0,结束计数。
            {        //所以,响应中断后,查询TF0的状态可以判断中断计数是否结束
              if(k==250)
               {k=0;
               dat++;}
              else
               k++;
                //关闭T0计数器,TR0=0句不能在主程序中,要在查询函数或中断函数中,否则停不下来。
           }       
   }
void main()
{
  TMOD=0x00;
/*此设置(0000 0101)T0的GATE=0,C/T为1,M1M0为01。
   GATE=0,关闭INT0(P3.2)脚对计数开始的控制,只由TR0控制开始。
    C/T=1,计数功能,计数管脚T0(P3.4)的状态变化。
   M1M0=01,计数方式选择方式1,16位二进制计数器,由TH0 TL0开始计数到FFFFH满,再计数就溢出,如果是定时/计数模式,溢出后将TF0置1,计数定时结束,如果是中断模式清0,有硬件给TF0置1,计数结束,也就是中断结束,自动将TF0清0.打开计数器0中断将ET0=1,EA=1 */
  TH0=0xa3;//设置计数器计数初值
  TL0=0x00;//第一次从这里的设置开始计数
  ET0=1;
  TR0=1;
  EA=1;
  while(1)
   {
    
   P0=yu[dat%10];
      delay(1);
      P2=0x01;   
      delay(1);
      P2=0x00;
      P0=yu[((dat%1000)%100)/10];
      delay(1);
      P2=0x02;
      delay(1);
      P2=0x00;
   P0=yu[(dat%1000)/100];
      delay(1);
      P2=0x04;   
      delay(1);
      P2=0x00;
      P0=yu[dat/1000];
      delay(1);
      P2=0x08;
      delay(1);
      P2=0x00;
   }

=====================================================
汇编语言编写的T0中断定时器
    ORG 0000H
     Ljmp main
     ORG 000BH
     Ljmp T0ZD
     org 0100h
main:mov TMOD,#00h
     mov TH0,#83h
     mov TL0,#00h
     mov r7,#00h
     setb EA
     setb ET0
     setb TR0
     mov dptr,#0300h
disp:mov 70h,r3
     mov a,70h
     mov b,#0ah
     div ab
     movc a,@a+dptr
     mov P0,a
     mov P2,#02h
     nop
     nop
     mov P2,#00h
     mov a,b
     movc a,@a+dptr
     mov P0,a
     mov P2,#01h
     nop
     nop
     mov P2,#00h
     sjmp disp
T0ZD:mov TL0,#00h
     mov TH0,#83h
     cpl p1.7    
     cjne r7,#250D,zzz
     mov r7,#00h
     cjne r3,#60h,ddd
     mov r3,#00h
ddd: inc r3
zzz: inc r7
     reti
     org 0300h
db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh
     end
=================================================== 
关键字:89C51  单片机  定时  计数器 引用地址:89C51单片机定时/计数器0

上一篇:用51单片机中断编写的4x4键盘程序
下一篇:关于51单片机双机通信

推荐阅读最新更新时间:2024-03-16 13:51

单片机的常见输入输出电路介绍(一)
针时电气控制产品的特点,讨论了几种单片机常用输入/ 输出电路 的设计方法,对合理地设计电气控制系统,提高电路的接口能力,增强系统稳定性和抗干扰能力有实际指导意义。   引 言   传统电气设备采用的各种控制信号,必须转换到与单片机输入/输出口相匹配的数字信号。用户设备须输入到单片机的各种控制信号,如限位开关,操作按钮、选择开关、行程开关以及其他一些传感器输出的开关量等,通过输入电路转换成单片机能够接收和处理的信号。输出电路则应将单片机送出的弱电控制信号转换、放大到现场需要的强输出信号,以驱动功率管、电磁阀和继电器、接触器、电动机等被控制设备的执行元件,能方便实际控制系统使用。   1 输入电路设计   一般输入信号最终会以
[模拟电子]
<font color='red'>单片机</font>的常见输入输出电路介绍(一)
用STC系列MCU的IO口直接驱动段码LCD
当产品需要段码LCD显示时,如果使用不带LCD驱动器的MCU,则需要外接LCD驱动IC,这会增加成本和PCB面积。事实上,很多小项目,比如大量的小家电,需要显示的段码不多,常见的是4个8带小数点或时钟的冒号 : ,这样如果使用IO口直接扫描显示,则会减小PCB面积,降低成本。 但是,本方案不合适驱动太多的段( 占用IO太多),也不合适非常低功耗的场合。 段码LCD驱动简单原理:如图1所示。 LCD是一种特殊的液态晶体,在电场的作用下晶体的排列方向会发生扭转,因而改变其透光性,从而可以看到显示内容。LCD有一个扭转阀值,当LCD两端电压高于此阀值时,显示内容,低于此阀值时,不显示。通常LCD有3个参数:工作电压、DUTY(对应CO
[单片机]
用STC系列<font color='red'>MCU</font>的IO口直接驱动段码LCD
用CPLD实现单片机读写模块
摘要:介绍实现单片机与Xilinx公司XC9500系列可编程逻辑器件的读写逻辑功能模块的接口设计,以及Xilinx公司的XC9500系列可编程逻辑器件的开发流程。 关键词:复杂可编程逻辑电路 微处理器 在系统编程 现场可编程门阵列 1 概述 CPLD(复杂可编程逻辑电路)是一种具有丰富的可编程I/O引脚的可编程逻辑器件,具有在系统可编程、使用方便灵活的特点;不但可实现常规的逻辑器件功能,还可实现复杂的时序逻辑功能。把CPLD应用于嵌入式应用系统,同单片机结合起来,更能体现其在系统可编程、使用方便灵活的特点。CPLD同单片机接口,可以作为单片机的一个外设,实现单片机所要求的功能。例如,实现常用的地址译码、锁存器、8255
[半导体设计/制造]
MSP430 延时总结
*****************************************软件延时************************************/ # define CPU_F ((double)8000000) #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) /*****************************************************************
[单片机]
STM32单片机串口通信波特率计算方法
1. 什么是波特率 不管是什么单片机,在使用串口通信的时候,有一个非常重要的参数:波特率。什么是波特率:波特率就是每秒传送的字节数。双方在传输数据的过程中,波特率一致,这是通讯成功的基本保障。下面以STM32单片机为例,讲解一下串口波特率的计算方法。 2. STM32波特率相关的寄存器 STM32单片机设置波特率的寄存器只有一个:USART_BRR寄存器,如下图所示。 该寄存器的有效位数为16位,前4位用于存放小数部分,后12位用于存放整数部分。将波特率算出来后,数值填入这个波特率就可以了。下面介绍如何计算。 3. 波特率计算方法 STM32的数据手册给出了计算方法,有一个公式,如下图所示: 在这个公式上,共有三
[单片机]
STM32<font color='red'>单片机</font>串口通信波特率计算方法
51单片机AD转换之PCF8591
PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。 AD转换即(模拟量)Analog 转换成 (数字量)Digital 1.引脚分析 PCF8591具有4个模拟输入(AIN0~AIN3)、1个模拟输出(AOUT)和1个串行I²C总线接口(SDA、SCL)。 PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,允许在同个I2C总线上接入8个PCF8591器件,而无需额外的硬件。在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I2C总线以串行的方式进行传输。 OSC:外部时钟输入端,内部时钟 EXT:内部、外部时钟选择线,使用内部时钟时 EXT 接地。 VD
[单片机]
51<font color='red'>单片机</font>AD转换之PCF8591
51单片机入门经验分享6-利用STC单片机的ADC采集电压
在实际开发中,AD,DA用的相当多,这一节,我们写一个程序,将采集到的电压数值显示在数码管上,程序如下: /******************************************************************************* * 文件名: ADC转换器使用 * 描 述: 电池电压 * 功 能:中断方式 11.059200MHZ * 作 者:大核桃 * 版本号:1.0.1(2017.05.23) *******************************************************************************/ #in
[单片机]
51<font color='red'>单片机</font>入门经验分享6-利用STC<font color='red'>单片机</font>的ADC采集电压
理清单片机中的各种周期
单片机 时钟周期 时钟周期: 时钟周期也叫振荡周期或晶振周期,即晶振的单位时间发出的脉冲数,一般有外部的振晶产生,比如12MHZ=12×10的6次方,即每秒发出12000000个脉冲信号,那么发出一个脉冲的时间就是时钟周期,也就是1/12微秒。通常也叫做系统时钟周期。是计算机中最基本的、最小的时间单位。 在8051单片机中把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。 机器周期: 在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。一般情况下,
[单片机]
理清<font color='red'>单片机</font>中的各种周期
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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