徐浩宇

川师工学院电气2018级

2021.4.27


51单片机给我们提供了2个计时器中断,分别是计时器0和计时器1,他们对应的优先级分别是1和3,开启计时器并允许其中断后,计时器会从给定的初始值开始,每个指令周期加1,直到加到65535,再加一时计时器溢出,计时器此时会进入中断,并执行中断服务函数。

  • 虽然书上讲的很清楚了,但实际使用还是有些许差别,我自己是这样理解的

65536-50000的由来

  • 假设我使用的单片机的晶振为12MHZ,其机器周期是1us,即每1us产生一次计数
  • 如果设计一个1s的定时器,理论上是需要1*10^6个机器周期,但定时器T0只能对机器周期能进行最大65536次计数,很明显已经超过了,并不能直接采用T0的默认值
  • 转下思维模式,取个65535之内的整数值,经过简单倍数关系即可转换为1s。很明显,50ms符合要求。即一次中断5 * 104次,中断20次即为1s
  • 但根据中断原理,T0中断器溢出时计数1次,但5 * 104<65536,根本不会发生溢出。此时有需要转下思维模式,如果我给T0定时器附上初始值,使其从初试值开始计数,最终读数为65536发生溢出,中断一次。这个初始值就是65536和5 * 104的差值

/256 和 %256 的由来

  • T0中断器由两个8位构成,低8位,即28,满打满算也只能计数256个机械周期,当大于256个机械周期就必须采用高8位了。换而言之,高8位每增加1,低八位就装满一次。
  • 故用初始值除以256取整,存入高8位。取余,即小于256次数,放入低8位。
TH0=(65536-50000)/256;       // (65536-50000)/256=60.6875
TL0=(65536-50000)%256;
  • 这就是这两句话的由来

以下附上C51程序代码

#include<reg51.h>
#include<intrins.h>
int flag=0;
sbit LED = P2^0;
void main()
{TMOD=0x10;          //工作于方式1//0 0 方式0 13位计数器 TMOD=0x00//0 1 方式1 16位计数器 TMOD=0x01//1 0 方式2 自动重装8位计数器 TMOD=0x02//1 1 方式3 T0分为2个8位独立计数器,T1为无中断重装8位计数器 TMOD=0x03EA=1;              // 中断允许ET1=1;                      // 中断1打开TH1=(65536-50000)/256;         // (65536-50000)/256=60.6875TL1=(65536-50000)%256;      TR1=1;while(1){}
}
void timer1(void) interrupt 3
{ TH1=(65536-50000)/256;TL1=(65536-50000)%256;flag++;if (flag==20)         //达到1s{flag    =0;LED=~LED;}
}

实验原理图

  • 很简单,只是在P2^0口加入了LED灯



拓展一下

如果要求做成流水灯呢?
有两种流水灯

  • 一种是移位流水灯,采用移位方式,同时只能亮一个灯。
    思路:在定时1s完成后加上自增量,该自增量随着秒数累次增加,当达到设计计数时清零。
    代码如下:
#include<reg51.h>
#include<intrins.h>
int flag=0;
sbit ledPort = P2;void main()
{TMOD=0x10;          //工作于方式1EA=1;              // 中断允许ET1=1;                         // 中断1打开TH1=(65536-50000)/256;         // (65536-50000)/256=60.6875TL1=(65536-50000)%256;      TR1=1;while(1){}
}void timer1(void) interrupt 3
{ unsigned char i;TH1=(65536-50000)/256;TL1=(65536-50000)%256;flag++;if (flag==20)         //达到1s{ i++;flag =0;ledPort = ~(1<<i) ;i=(i+1)%8;}
}

原理图如下所示:



  • 另外一种是累计流水灯,采用累增方式,同时亮多个灯。
    思路:在定时1s完成后加上自增量,该自增量随着秒数累次增加,当达到设计计数时清零。同时设置多重判断,根据自增量的值判断执行哪一种循环。
  • 其实我这里的写法很蠢,像是没学过 c 的人,可惜实验的时间不够,就采用笨办法了,达到效果就行(狗头)。
  • 高效率的写法应该与C输出九九表类似,采用双重For循环嵌套构成。
    代码如下:
#include<reg51.h>
#include<intrins.h>
#define ledPort  P2
int flag = 0;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;
sbit LED6 = P2^5;
sbit LED7 = P2^6;
sbit LED8 = P2^7;
unsigned char i ;
void main()
{TMOD=0x10;          //工作于方式1EA=1;              // 中断允许ET1=1;                         // 中断1打开TH1=(65536-50000)/256;         // (65536-50000)/256=60.6875TL1=(65536-50000)%256;      TR1=1;i=0;               //用于控制流水灯跳转while(1){}
}void timer1(void) interrupt 3
{ TH1=(65536-50000)/256;TL1=(65536-50000)%256;flag++;if (flag==20)         //达到1s{i++;flag = 0;if(i==1){LED1=0;}if(i==2){LED1=0;LED2=0;}if(i==3){LED1=0;LED2=0;LED3=0;}                if(i==4){LED1=0;LED2=0;LED3=0;LED4=0;}                if(i==5){LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;}if(i==6){LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;LED6=0;}if(i==7){LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;LED6=0;LED7=0;}if(i==8){LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;LED6=0;LED7=0;LED8=0;}if(i==9){LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;LED6=0;LED7=0;LED8=1;}if(i==10){LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;LED6=0;LED7=1;LED8=1;}if(i==11){LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;LED6=1;LED7=1;LED8=1;}if(i==12){LED1=0;LED2=0;LED3=0;LED4=0;LED5=1;LED6=1;LED7=1;LED8=1;}                 if(i==13){LED1=0;LED2=0;LED3=0;LED4=1;LED5=1;LED6=1;LED7=1;LED8=1;}if(i==14){LED1=0;LED2=0;LED3=1;LED4=1;LED5=1;LED6=1;LED7=1;LED8=1;}if(i==15){LED1=0;LED2=1;LED3=1;LED4=1;LED5=1;LED6=1;LED7=1;LED8=1;}if(i==16){LED1=1;LED2=1;LED3=1;LED4=1;LED5=1;LED6=1;LED7=1;LED8=1;}if(i==17){i=0;}}
}
  • 实验效果图如下所示:

用C51单片机的外部中断设计1s定时器相关推荐

  1. 快速复习51单片机的外部中断、计数/定时器中断和串行口中断,加代码实现

    目录 1.中断系统的概念 1.1中断的概念 1.2中断系统的概念 1.3中断系统的优点 1.4我们要说的三种中断源 2.外部中断 2.1 外部中断0 代码示范 2.2 外部中断 分析 3.计数/定时器 ...

  2. 51单片机之外部中断拙见

    外部中断需要注意的点 1. 外部中断其实是包含在中断系统中的,STC89Cx系列单片机提供4个外部中断:外部中断0(INT0),外部中断1(INT1),外部中断2(INT2),外部中断3(INT3) ...

  3. 51单片机:外部中断实现流水灯

    51单片机:外部中断实现流水灯 作业要求: 按照给定的实验板电路图编程实现外部中断控制流水灯,初始上电时,实验板右下侧的流水灯区域只有最右侧LED灯亮,其他灯全都熄灭,每按下一次按键,流水灯从右向左流 ...

  4. PIC16F877A单片机 (外部中断)

    PIC16F877A单片机 (外部中断) 1 基本原理 2 实现代码 1 基本原理 2 实现代码 /*----------------函数功能:外部中断RB0/INT按下按键(即产生一个中断),此时L ...

  5. Proteus 8仿真以及C51单片机广告灯的设计(C语言)实例

    Proteus 8仿真以及C51单片机广告灯的设计(C语言)实例 一. 广告灯程序编译 二. Proteus8 仿真 三. 开发板调试 四. 注意事项 一. 广告灯程序编译 打开Keil uVisio ...

  6. 单片机的外部中断(二)

    前言:单片机的中断系统(一) 80C51单片机提供两个外部中断口:  INT0(P3.2)和INT1(P3.3)引脚输入.这两个引脚是功能复用引脚,既可以作为普通V0口,也可作为外部中断输入引脚.下面 ...

  7. 【51单片机】外部中断

    51的 外部中断 与 定时器(内部中断) 有一个共同特点,那就是与主程序是并行工作的,就是主程序在运行的时候,中断也在等待触发条件,当中断被触发的时候会暂停主程序转而执行中断服务程序,只有中断服务程序 ...

  8. 51单片机之外部中断方式 ——— INT0 中断

    51单片机具有5个中断源,其中有两个外部中断,这次我们以下降沿触发Int0为例. 在B站跟个up主中断教程, 传送门 https://space.bilibili.com/483942191/vide ...

  9. 瑞萨单片机之外部中断实现频率采集(三)

    很多低端MCU没有像STM32 那样拥有强大脉冲捕获测频率,那么MCU只能依靠自身有的资源来实现这个功能,比较通用的方法是使用了外部中断+定时器来实现,该方法经过我在实际项目中的使用来看,频率50/6 ...

最新文章

  1. fastq质量值_fastq格式文件处理大全(四)
  2. 强势推荐8个顶级好用的软件,堪称神器
  3. “几何深度学习”受爱因斯坦启示:让AI摆脱平面看到更高的维度
  4. Vue蚂蜂窝Vue-cli+webpack做的
  5. 机器学习基本概念-阿里云大学
  6. Spring Retry 重试机制实现及原理
  7. setuptools include_package_data
  8. 《大教堂与市集》读后感
  9. 可以掉落和滑动的星星
  10. 虚幻学习4---制作实时逼真的毛发【笔记】
  11. [ 物联网篇 ] ESP32 开发板测试亚马逊语音助手Alexa
  12. CISCO APIC-M2无法安装APIC软件故障解决
  13. 求最大公约数及求多个数的最大公约数
  14. docx4j操作word文档之生成页码、合并多个文档
  15. RecyclerView调用notifyDataSetChanged()不起作用
  16. PTA 7-63 黑白子交换棋局
  17. Syncthing文件同步方案完全攻略(亲测有效)
  18. uni-app 上架应用商店踩坑过程
  19. 【DL】第 3 章:高级卷积网络
  20. git合并多个远程commit并提交

热门文章

  1. 狗哥和度娘的差距,就是一次点击
  2. 提高文章阅读量的最新技巧
  3. VR全景照片拍摄小技巧分享
  4. gdb 笔记(02)— gdb 调试执行(启动调试、添加参数、附加到进程、调试 core 文件)
  5. linux修改mac地址
  6. 2021山丹一中高考成绩查询,2019年张掖中考分数线,张掖中考录取分数线(出炉)
  7. 安卓IMS 原理解析(二、IMS之InputReader事件获取)
  8. xampp linux 命令,centos 下XAMPP 常用命令
  9. 发表论文被拒?只因你没注意这几点
  10. 盖茨、马斯克都遵循的终身学习法则:知识不是由学科划分的