52单片机有几个定时器?52单片机定时器1和52单片机定时器2程序对比

电子常识

2583人已加入

描述

  52单片机有几个定时器?

  STC89C52RC是有三个定时器的单片机,STC89C52RC共有3个定时器,分别是T0、T1、T2。

  而51单片机只有T0,T1 两个定时器。

  52单片机的默认(此时的IP寄存器不做设置)中断优先级为:

  外部中断0 > 定时/计数器0 > 外部中断1> 定时/计数器1 > 定时/计数器2 > 串行中断;
 

  而在做定时则用一般采用16位模式,也就是TMOD=0x11(10或01单独一个定时器的话),初值的计算是这样的:

  假设时间是X毫秒,晶振为YMhz,那么:

  THn=(65536-1000*X*Y/12)/256

  TLn=(65536-1000*X*Y/12)%256

  之后就是TRn=1(开启定时器)

  ETn=1(开启定时器中断)

  EA=1

  下面我们给大家分享一下52单片机定时器0、52单片机定时器1和52单片机定时器2的各自程序。

  STC89C52单片机定时器0的中断实验

  //////////////////////////////////////////////////////////////////////////

  实现功能: 配置定时器0的相关寄存器,使其实现定时器中断功能,然后通过发光

  二极管的闪烁展现出中断的进行

  实验板型号:BS-XYD-C52

  实验名称: 定时器0的中断实验

  //////////////////////////////////////////////////////////////////////////

  #include《reg52.h》

  #define uchar unsigned char //定义unsigned char 为 uchar

  #define uint unsigned int //定义unsigned int 为 uint

  sbit Led=P1^0; //将P1^0口定义为led,方便程序编写

  //////////////////////////////////////////////////////////////////////////

  函数名称:Init_time0

  函数功能:配置定时器0,配置的模式是定时器0采用16位计数器模式,同时允许定时器0

  中断,并打开总中断

  参数介绍:无

  返回值: 无

  注意事项:无

  //////////////////////////////////////////////////////////////////////////

  void Init_time0(void)

  {

  TMOD |= 0x01;

  TH0=0x00;

  TL0=0x00; //定时器0的,写入数值寄存器的低8位

  EA=1; //总中断打开

  ET0=1; //定时器T0允许中断

  TR0=1; //定时器T0开始工作

  }

  //////////////////////////////////////////////////////////////////////////

  函数名称:main

  函数功能:实现定时器0中断,且通过名为D1的发光二级管展现出来

  参数介绍:无

  返回值: 无

  注意事项:无

  //////////////////////////////////////////////////////////////////////////

  void main()

  {

  Init_time0(); //初始化定时器0

  while(1);

  }

  //////////////////////////////////////////////////////////////////////////

  函数名称:Interrupt_handler_time0

  函数功能:重新给寄存器TH0和TL0赋值,并且让开发板上的名为D1的发光二级管,每次

  取相反的值,使其不断地闪烁,也达到测试定时器0中断的效果

  参数介绍:无

  返回值: 无

  注意事项:无

  //////////////////////////////////////////////////////////////////////////

  void Interrupt_handler_time0(void) interrupt 1

  {

  TH0=0x00; //重新赋值

  TL0=0x00;

  Led=~Led; //指示灯反相,可以看到闪烁。“ ~ ”按位取反运算符

  }



  STC89C52单片机定时器1实现计数器的程序

  ///////////////////////////////////////////////////////////////////////////

  实现功能: 配置定时器1的相关寄存器,使其实现定时器中断功能,然后通过在数码管显示

  实验板型号:BS-XYD-C52

  实验名称: 定时器1实现计数器

  ///////////////////////////////////////////////////////////////////////////

  #include《reg52.h》

  #define uchar unsigned char //定义unsigned char 为 uchar

  #define uint unsigned int //定义unsigned int 为 uint

  uchar cTime_10ms_counter; //中断次数计数单元

  uchar cTime_1s_ok; //判断是否为1s的变量

  uchar uDis_buff[2]; //显示缓冲区,存放要显示的2个字符的段码值

  uchar cTime; //秒计数单元

  #define Time_1s_Sign 100 //根据中断周期,判断是否到一秒的标志

  sbit Duan=P2^6; //定义数码管的段选使能端

  sbit Wei =P2^7; //定义数码管的位选使能端

  #define Digital_tube_Wei_Enable Wei=1; //开启控制数码管的位选使能端

  #define Digital_tube_Wei_Disable Wei=0; //关闭控制数码管的位选使能端

  #define Digital_tube_Duan_Enable Duan=1; //开启控制数码管的段选使能端

  #define Digital_tube_Duan_Disable Duan=0; //关闭控制数码管的段选使能端

  #define Digital_tube_Duan P0 //定义数码管数据端口

  uchar code Dis_table[]= //将BCD码转换成数码管扫描码的数组

  {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};

  uchar code Dis_Position[]= //定义数码管位选的数组

  {0x3e,0x3d,0x3b,0x37,0x1f,0x2f};

  ///////////////////////////////////////////////////////////////////////////

  函数名称:毫秒延时函数

  函数功能:实现毫秒级的延时

  参数介绍:Delay_MS: 定义需要延时的毫秒的数值

  iNumber: 记录Delay_MS的数值,以for语句实现所要求的延时

  iValue: 要延时毫秒所要进行的循环数值,本数值为实际测得

  返回值: 无

  注意事项:本实验是在所用晶振为12M的前提下实现的毫秒延时,本函数是通过循环的形

  式完成,所以如果改变了晶振的频率,请做相应的改变

  ///////////////////////////////////////////////////////////////////////////

  void DelayMs(uint Delay_MS)

  {

  uint iNumber,iValue;

  for(iNumber=0;iNumber《Delay_MS;iNumber++) //用for语句实现单片机的延时

  {

  iValue=107; //107这个数值是通过测定而得

  while(iValue--);

  }

  }

  ///////////////////////////////////////////////////////////////////////////

  函数名称:One_DigitalTube_display

  函数功能:完成在实验板上数码管指定显示,即在特定的数码管上显示特定的数字,比

  在第一个数码管上显示0

  参数介绍:uData:要显示的数字的BCD码数组

  uNumber:选择哪个数码管显示,即让某个特定数码管显示

  返回值: 无

  注意事项:实验板上的数码管是共阴极的数码管,如果使用共阳极的数码管,请注意不

  要弄反了

  ///////////////////////////////////////////////////////////////////////////

  void One_DigitalTube_display(uchar uData,uchar uNumber)

  {

  Digital_tube_Duan_Enable; //使能数码管的段选

  Digital_tube_Duan=Dis_table[uData];//输入所要显示的数值

  Digital_tube_Duan_Disable; //关闭数码管的段选

  Digital_tube_Duan=Dis_Position[uNumber]; //点亮特定的数码管

  Digital_tube_Wei_Enable; //使能数码管的位选

  Digital_tube_Wei_Disable; //关闭数码管的位选

  DelayMs(5); //调整时序,以实现稳定显示

  }

  ///////////////////////////////////////////////////////////////////////////

  函数名称:Time_to_disbuffer

  函数功能:把要在数码管上显示的数值,进行取余、取整,即对数值进行分割,这样以

  便显示在分离的数码管

  参数介绍:无

  返回值: 无

  注意事项:无

  ///////////////////////////////////////////////////////////////////////////

  void Time_to_disbuffer()

  {

  uDis_buff[1]=cTime; //对cTime的数值取余,即就是取cTime的个位

  uDis_buff[0]=cTime/10; //对cTime的数值取整,即就是取cTime的十位

  }

  ///////////////////////////////////////////////////////////////////////////

  函数名称:Init_time1

  函数功能:配置定时器1,配置的模式是定时器1采用16位定时器模式,在定时器1的输入

  数值寄存器输入特定的数值,使其每次中断的周期为10ms,同时允许定时器1

  中断,并打开总中断

  参数介绍:无

  返回值: 无

  注意事项:无

  ///////////////////////////////////////////////////////////////////////////

  void Init_time1(void)

  {

  TMOD |= 0x10;

  TH1=(65535-10000)/256;

  TL1=(65535-10000)%6; //定时器0的,写入数值寄存器的低8位

  EA=1; //总中断打开

  ET1=1; //定时器T0允许中断

  TR1=1; //定时器T0开始工作

  }

  ///////////////////////////////////////////////////////////////////////////

  函数名称:Timer_Display

  函数功能:把显示缓冲区的数值显示在数码管上

  参数介绍:cNumber:记录for语句的循环次数

  返回值: 无

  注意事项:无

  ///////////////////////////////////////////////////////////////////////////

  void Timer_Display()

  {

  uchar cNumber;

  for(cNumber=0;cNumber《2;cNumber++)

  {

  One_DigitalTube_display(uDis_buff[cNumber],cNumber);

  DelayMs(2);

  }

  }

  ///////////////////////////////////////////////////////////////////////////

  函数名称:main

  函数功能:利用定时器1中断,在数码管上实现以一分钟为周期的计数器

  参数介绍:无

  返回值: 无

  注意事项:无

  ///////////////////////////////////////////////////////////////////////////

  void main()

  {

  Init_time1(); //初始化定时器1

  cTime=0;

  while(1)

  {

  if(cTime_1s_ok)

  {

  cTime_1s_ok=0;

  if(++cTime》=60) //每次自加一,同时判断是否到1分钟

  {

  cTime=0;

  }

  Time_to_disbuffer(); //新调整好的时间送入显示缓冲区

  }

  Timer_Display(); //更新显示内容

  }

  }

  ///////////////////////////////////////////////////////////////////////////

  函数名称:Interrupt_handler_time1

  函数功能:重新给寄存器TH1和TL1赋值,判断是否到达一秒,如果到一秒了,把相应的

  变量赋予正值,以方便其他的程序编写

  参数介绍:无

  返回值: 无

  注意事项:无

  ///////////////////////////////////////////////////////////////////////////

  void Interrupt_handler_time1(void) interrupt 3

  {

  uchar i;

  TH1=(65535-10000)/256;//定时10毫秒

  TL1=(65535-10000)%6;

  cTime_10ms_counter++;

  if(cTime_10ms_counter==Time_1s_Sign) //判断是否到达一秒

  {

  cTime_10ms_counter=0;

  cTime_1s_ok=1;

  }

  }

  STC89C52单片机的定时器2的实现时钟的程序

  ////////////////////////////////////////////////////////////////////////

  实现功能: 配置定时器2的相关寄存器,使其实现定时器中断功能,然后根据中断

  的周期频率实现准确的时钟系统,在数码管上显示实现

  实验板型号:BS-XYD-C52

  实验名称: 定时器2实现时钟系统

  /////////////////////////////////////////////////////////////////////////

  #include《reg52.h》

  #define uchar unsigned char //定义unsigned char 为 uchar

  #define uint unsigned int //定义unsigned int 为 uint

  uchar cTime_10ms_counter; //中断次数计数单元

  uchar cTime_1s_ok; //判断是否为1s的变量

  uchar uDis_buff[6]; //显示缓冲区,存放要显示的6个字符的段码值

  uchar cTime[3]; //时、分、秒计数单元

  #define Time_1s_Sign 100 //根据中断周期,判断是否到一秒的标志

  sbit led=P1^0;

  sbit Duan=P2^6; //定义数码管的段选使能端

  sbit Wei =P2^7; //定义数码管的位选使能端

  #define Digital_tube_Wei_Enable Wei=1; //开启控制数码管的位选使能端

  #define Digital_tube_Wei_Disable Wei=0; //关闭控制数码管的位选使能端

  #define Digital_tube_Duan_Enable Duan=1; //开启控制数码管的段选使能端

  #define Digital_tube_Duan_Disable Duan=0; //关闭控制数码管的段选使能端

  #define Digital_tube_Duan P0 //定义数码管数据端口

  uchar code Dis_table[]= //将BCD码转换成数码管扫描码的数组

  {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};

  uchar code Dis_Position[]= //定义数码管位选的数组

  {0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

  /////////////////////////////////////////////////////////////////////////

  函数名称:毫秒延时函数

  函数功能:实现毫秒级的延时

  参数介绍:Delay_MS: 定义需要延时的毫秒的数值

  iNumber: 记录Delay_MS的数值,以for语句实现所要求的延时

  iValue: 要延时毫秒所要进行的循环数值,本数值为实际测得

  返回值: 无

  注意事项:本实验是在所用晶振为12M的前提下实现的毫秒延时,本函数是通过循环的形

  式完成,所以如果改变了晶振的频率,请做相应的改变

  /////////////////////////////////////////////////////////////////////////

  void DelayMs(uint Delay_MS)

  {

  uint iNumber,iValue;

  for(iNumber=0;iNumber《Delay_MS;iNumber++) //用for语句实现单片机的延时

  {

  iValue=107; //107这个数值是通过测定而得

  while(iValue--);

  }

  }

  /////////////////////////////////////////////////////////////////////////

  函数名称:One_DigitalTube_display

  函数功能:完成在实验板上数码管指定显示,即在特定的数码管上显示特定的数字,比

  在第一个数码管上显示0

  参数介绍:cData:要显示的数字的BCD码数组

  cNumber:选择哪个数码管显示,即让某个特定数码管显示

  返回值: 无

  注意事项:实验板上的数码管是共阴极的数码管,如果使用共阳极的数码管,请注意不

  要弄反了

  /////////////////////////////////////////////////////////////////////////

  void One_DigitalTube_display(uchar cData,uchar cNumber)

  {

  Digital_tube_Duan_Enable; //使能数码管的段选

  Digital_tube_Duan=Dis_table[cData];//输入所要显示的数值

  Digital_tube_Duan_Disable; //关闭数码管的段选

  Digital_tube_Wei_Enable; //使能数码管的位选

  Digital_tube_Duan=Dis_Position[cNumber]; //点亮特定的数码管的公共端

  Digital_tube_Wei_Disable; //关闭数码管的位选

  DelayMs(1); //调整时序,以实现稳定显示

  }

  /////////////////////////////////////////////////////////////////////////

  函数名称:Time_to_disbuffer

  函数功能:把要在数码管上显示的数值,进行取余、取整,即对数值进行分割,这样以

  便显示在分离的数码管

  参数介绍:cNumber1: 记录时、分、秒计数单元数组的变量

  cNumber2:记录显示缓冲区数组的变量

  返回值: 无

  注意事项:无

  /////////////////////////////////////////////////////////////////////////

  void Time_to_disbuffer()

  {

  uchar cNumber1,cNumber2=0;

  for(cNumber1=0;cNumber1《=2;cNumber1++)

  {

  uDis_buff[cNumber2++]=cTime[cNumber1]/10; //对cTime的数值取整,即

  //就是取cTime的十位

  uDis_buff[cNumber2++]=cTime[cNumber1]; //对cTime的数值取余,即

  //就是取cTime的个位

  }

  }

  /////////////////////////////////////////////////////////////////////////

  函数名称:Init_time2

  函数功能:配置定时器2,配置的模式是定时器1采用16位定时器模式,在定时器1的输入

  数值寄存器输入特定的数值,使其每次中断的周期为10ms,同时允许定时器1

  中断,并打开总中断

  参数介绍:无

  返回值: 无

  注意事项:无

  /////////////////////////////////////////////////////////////////////////

  void Init_time1(void)

  {

  TH2=(65535-10000)/256;

  TL2=(65535-10000)%6; //定时器0的,写入数值寄存器的低8位

  EA=1; //总中断打开

  ET2=1; //定时器T0允许中断

  TR2=1; //定时器T0开始工作

  }

  /////////////////////////////////////////////////////////////////////////

  函数名称:Timer_Display

  函数功能:把显示缓冲区的数值显示在数码管上

  参数介绍:cNumber:记录for语句的循环次数

  返回值: 无

  注意事项:无

  /////////////////////////////////////////////////////////////////////////

  void Timer_Display()

  {

  uchar cNumber;

  for(cNumber=0;cNumber《6;cNumber++)

  {

  One_DigitalTube_display(uDis_buff[cNumber],cNumber);

  if(cNumber==1|cNumber==3)

  {

  Digital_tube_Duan_Enable; //使能数码管的段选

  Digital_tube_Duan=0x80; //输入所要显示的数值

  Digital_tube_Duan_Disable; //关闭数码管的段选

  Digital_tube_Wei_Enable; //使能数码管的位选

  Digital_tube_Duan=Dis_Position[cNumber]; //点亮特定的数码管的公共端

  Digital_tube_Wei_Disable; //关闭数码管的位选

  DelayMs(1);

  }

  }

  }

  /////////////////////////////////////////////////////////////////////////

  函数名称:main

  函数功能:利用定时器2中断,实现准确的时钟系统,然后在数码管上显示实现

  参数介绍:无

  返回值: 无

  注意事项:无

  /////////////////////////////////////////////////////////////////////////

  void main()

  {

  Init_time1(); //初始化定时器1

  cTime[0]=23,cTime[1]=58,cTime[2]=58;

  Time_to_disbuffer(); //把预设时间送入显示缓冲区

  while(1)

  {

  if(cTime_1s_ok) //判断是否到1秒了

  {

  cTime_1s_ok=0;

  if(++cTime[2]》=60) //每次自加一,同时判断是否到1分钟

  {

  cTime[2]=0;

  if(++cTime[1]》=60) //每次自加一,同时判断是否到1小时了

  {

  cTime[1]=0;

  if(++cTime[0]》=24) //每次自加一,同时判断是否到24点了

  {

  cTime[0]=0;

  }

  }

  }

  Time_to_disbuffer(); //新调整好的时间送入显示缓冲区

  }

  Timer_Display(); //更新显示内容

  }

  }

  /////////////////////////////////////////////////////////////////////////

  函数名称:Interrupt_handler_time2

  函数功能:重新给寄存器TH2和TL2赋值,判断是否到达一秒,如果到一秒了,把相应的

  变量赋予正值,以方便其他的程序编写

  参数介绍:无

  返回值: 无

  注意事项:无

  /////////////////////////////////////////////////////////////////////////

  void Interrupt_handler_time2(void) interrupt 5

  {

  TF2=0;

  TH2=(65535-10000)/256;//定时10毫秒

  TL2=(65535-10000)%6;

  cTime_10ms_counter++;

  if(cTime_10ms_counter==Time_1s_Sign) //判断是否到达一秒

  {

  cTime_10ms_counter=0;

  cTime_1s_ok=1;

  }

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分