单片机交流
直播中

唯爱萌meng

9年用户 1017经验值
擅长:可编程逻辑
私信 关注
[问答]

定时器中断及工作流程简析

定时器中断是什么?
定时器是怎样工作的?

回帖(1)

王媛媛

2021-10-20 15:17:59
  概述
  定时器中断是由单片机中的定时器溢出而申请的中断。
  51单片机中有两个定时器T0和T1:
  TF0:定时器T0溢出中断请求。当定时器TO产生溢出时,TO中断请求标志TF0置1,请求中断处理。
  TF1:定时器T1溢出中断请求。当定时器Tl产生溢出时,T1中断请求标志TF1置1,请求中断处理。
  Stm32共有11个定时器:
  1.两个高级定时器:TIM1、TIM8-------------------------APB2
  2.四个通用定时器:TIM2~TIM5-------------------------APB1
  3.两个基本定时器:TIM6、TIM7-------------------------APB1
  4.两个看门狗
  5.一个系统嘀嗒定时器(SysTick)
  定时/计数器
  定时/计数器T0和T1分别是由两个8位的专用寄存器组成,即定时/计数器T0由TH0和TL0组成,T1由TH1和TL1组成。此外,其内部还有2个8位的特殊功能寄存器TMOD和TCON,TMOD负责控制和确定T0和T1的功能和工作模式,TCON用来控制T0和T1启动或停止计数,同时包含定时/计数器的状态。 [1]
  TF1:定时器1溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除。或用软件清除。
  TF0:定时器0溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除,或用软件清除。
  工作流程
  定时器工作的流程可以按照这个顺序(以51为例用定时器0方式一产生10毫秒的定时)
  1、确定使用哪个定时器,使用哪种方式,这一步通过TMOD设置,TMOD的低四位是设置定时器0的,高四位是用来设置定时器1的,其中的M0,M1是用来设置定时器工作在哪种方式,GATE一般用不要设置,C/T是选择计数模式还是定时模式的,如:TMOD = 0X01,就说明定时器0工作在方式1。
  2、接下来就要设置定时的时间,用定时器定时50毫秒,可以用这种方式TH0 = (65535 - 10000) / 256,TL0 = (65535 - 10000) % 256;可以这样理解:因为这是定时器的初值,也就是说计数脉冲就是在这个数的基础上向上递增,到达65535后就溢出产生中断。
  3、第三步打开中断,使用IE寄存器,首先打开总中断EA = 1,这一步是所有中断所必须的,然后打开定时器0中断,ET0 =1。
  4、这时准备工作结束,启动定时器,使用TCON寄存器,TR0 = 1,实现了一个10毫秒的定时。
  代码如下:
  #include 《reg51.h》
  #define DataPort P1 // 宏定义,如果换接口,需要修改这里
  ***it Seg_Latch = P2^2; //段锁存
  ***it Bit_Latch = P2^3; //位锁存
  unsigned char code Seg_Code[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80}; //段码
  unsigned char code Bit_Code[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位码
  void Display(unsigned char m,unsigned char num,unsigned int n);
  static unsigned int n = 0;
  static unsigned int x = 0;
  static unsigned int y = 0;
  int main(void)
  {
  TMOD = 0x01;
  TH0 = 0xd8;
  TL0 = 0xf0;
  EA = 1; //开中断
  ET0 = 1;
  //因为只有一个中断,所以不用设置
  TR0 = 1; //开启定时器0,等待中断的到来
  while(1)
  {
  Display(7,8,n);
  Display(6,6,-1); //-1在数码管上显示‘ 。 ’
  Display(4,5,y);
  Display(3,3,-1);
  Display(1,2,x);
  }
  }
  void T0_ISR(void) interrupt 1
  {
  unsigned char i;
  EA = 0; //屏蔽其他中断
  TH0 = 0xd8; //重新赋值,保证每次都是10毫秒
  TL0 = 0xf0;
  i++;
  if(i == 1)
  {
  i = 0;
  if(n 《 99) //走毫秒
  {
  n++;
  }
  else
  {
  n = 0;
  if(y 《 59) //走秒
  {
  y++;
  }
  else
  {
  y = 0;
  if(x 《 59) //走分
  x++;
  else
  x = 0;
  }
  }
  }
  EA = 1;
  }
  void Display(unsigned char m,unsigned char num,unsigned int i) //m表示从第几个数码管开始,num表示到第num个数码管,i表示需要显示的数字
  {
  unsigned char j,a[10];
  if(i == -1)
  {
  DataPort = 0; //初始化
  Seg_Latch = 1;
  Seg_Latch = 0;
  DataPort = Bit_Code[m-1]; //送位码,锁定第m位
  Bit_Latch = 1; //位开门
  Bit_Latch = 0; //位关门
  DataPort = Seg_Code[10]; //送段码
  Seg_Latch = 1; //段开门
  Seg_Latch = 0; //段关门
  }
  else
  {
  a[m-1] = i / 10;
  a[num-1] = i % 10;
  for(j = m-1;j 《 num;j++)
  {
  DataPort = 0;
  Seg_Latch = 1;
  Seg_Latch = 0;
  DataPort = Bit_Code[j];
  Bit_Latch = 1;
  Bit_Latch = 0;
  DataPort = Seg_Code[a[j]];
  Seg_Latch = 1;
  Seg_Latch = 0;
  }
  }
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分