综合技术交流
直播中

ss

6年用户 8762经验值
擅长:电源/新能源 制造/封装 RF/无线
私信 关注
[经验]

采用单片机制作的秒表

  秒表
  单片机也有中断功能,它也会中断单片机主程序正常运行。今天设计的秒表是利用单片机内部资源——定时/计数器中断,前面讲过延时1秒(s),是让单片机空耗一段时间,并且延时时间不是精确的,但是定时器中断获得时间单位就比较精确,精确程度与单片机外接晶振质量有关。
  常见的单片机一共有5个中断,即外部中断0、外部中断1、定时/计数中断0、定时/计数中断1、串口中断。
  一、制作一个秒表
  程序设计
  #include《reg52.h》//头文件
  #define uchar unsigned char//宏定义
  #define uint unsigned int
  uchar table []={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴数码管数组
  uchar num,num1,shi,ge;//定义变量
  void delay(uchar a)//延时函数
  {
  uint i,j;
  for(j=a;j》0;j--)
  for(i=110;i》0;i--);
  }
  void display(uchar shi,uchar ge)//显示函数
  {
  P0=table[shi];
  P1=0XFE;//1111 1110选中数码管第一位
  delay(5);
  P0=table[ge];
  P1=0XFd;//1111 1101选中数码管第二位
  delay(5);
  }
  void t0init()//初始化
  {
  TMOD=0X01;//0000 0001//定时器0工作方式1
  TH0=0X3C;//装入初值,50毫秒
  TL0=0XB0;//装入初值
  EA=1;//打开总中断开关
  ET0=1;//打开定时器0中断开关
  TR0=1;//启动定时器0
  }
  void main()//主函数
  {
  t0init();
  while(1)//无限循环
  {
  display(shi,ge);
  }
  }
  void timer0()interrupt 1 //中断函数
  {
  TH0=0X3C;//装入初值
  TL0=0XB0;//装入初值
  num++;//变量累加
  if(num==20)//1秒
  {
  num=0;
  num1++;
  shi=num1/10;//取十位
  ge=num1%10;//取个位
  if(num1==60)
  {
  num1=0;
  }
  }
  }
  3.程序解释
  (1)采用定时器中断必要的语句。
  TMOD=0X01;
  TMOD是选择定时器工作方式。0X01是定时/计数中断0工作方式1,如果是0X10是定时/计数1工作方式1。
  TH0=0X3C;//装入初值
  TL0=0XB0;//装入初值
  如果单片机外接晶振是12M,它的时钟周期是1/12μs(微妙),12个时钟周期是一个机器周期即1μs,定时/计数0工作方式1,最大值能定时65536μs(2的16次方),约等于65ms。如果需要定时50ms,也就是计数不是从0开始,而是从15536(65536-50000)开始,15536(十进制)换算为16进制为3CB0,即“TH0=0X3C;TL0=0XB0;”,需要计时1s,只需程序中断20次。
  EA=1;//打开总中断开关
  EA是总开关,好比总电闸。
  ET0=1;//打开定时器0中断开关。它是定时器0的开关,好比客厅总电源开关。
  TR0=1;//启动定时器0。启动定时器0好比客厅的吊灯开关。
  以上语句需要写在主函数中,或者作为函数,在主函数中调用。
  (2)void display(uchar shi,uchar ge)//显示函数显示部分用函数形式体现,在主函数循环调用。
  (3)中断函数
  既然中断产生了,那么中断以后做什么?
  void timer0()interrupt 1 //中断函数
  {
  做什么工作;
  }
  “timer0”自己起的名字,代表定时/计数0中断,“interrupt”不能写错,关键是它后面的数字千万也不能搞错。中断源与序号如表3-14-1。需要注意,采用工作方式1,需要在中断函数中重新装入初值。

更多回帖

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