当前位置: 首页 > news >正文

51单片机快速入门之定时器和计数器

51单片机快速入门之定时

断开外部输入

晶振振荡 假设为 12MHz

12分频之后,为1MHz 当其从0-65536 时,需要65536μs 微秒 也就是65.536ms 毫秒

溢出(值>=65536 时)>中断>执行中断操作

假设需要1ms后产生溢出,则需要设置初始值为64536

此时定时器会从  64536 开始计数 (1000μs 微秒 = 1 ms 毫秒 )    

51单片机快速入门之计数器

计算外部输入的脉冲信号
假设设置其为16位计数器,其最大计数值为 2^16=65536
溢出(值>=65536 时)>中断>执行中断操作

假设需要100个脉冲后产生溢出,则需要设置初始值为65436

此时计数器会从  65436 开始计数   

结构原理

由 两个8位 计数器构成的  16位 计数器
TCON 寄存器 控制 开(1) / 关(0)
TMOD 寄存器 设置 工作方式 (定时还是计数)

TMOD寄存器

以下图片来源于stc89c52官方数据手册:

 这个GATE用于IO口控制 定时器  使用(1) / 不使用(0)  如果需要IO口控制 需设置其为 1

C/T 设置是 定时器 断开引脚输入 还是 计数器 从引脚输入

M1 M0 为模式选择,有不同的搭配

0   0 时 为13位 模式 (由 两个8位 计数器构成的  16位 计数器)  一计数器低5位 | 二计数器全8位

低五位计数器溢出时,它会向高八位计数器提供一个进位信号,这个信号会使高八位计数器的值加1。此时,低五位计数器会自动复位为其最小值(通常为0)


低 5 位”通常是指一个二进制数的最右边的 5 个比特位 从右向左数

举例:16位二进制数 1010 1100 0101 1001 低五位 就为 10011


0  1 时 为16位 两个8位全用

1  0 时  为8位自动重载 第一个计数器溢出之后,先转移当前值到 第二个计数器中,再复位为0

每次溢出时,第二个计数器的值就会增加(或减少,取决于计数方向)

1   1 时 停止计数(暂停)

这里要注意数据手册上标注 当M1 M0 都为 1 时  定时器 0 的工作方式

第一个计数器可以设置成   8位定时器/计数器 受 定时器 0 控制

但是 第二个计数器 只能是 8位定时器 受 定时器 1 控制

TCON寄存器 

以下图片来源于stc89c52官方数据手册: 

 定时器1

TF1 溢出标志位 (溢出时其为 1 ,会向CPU 请求中断 ,CPU响应后 0) 可手动设置

TR1 运行控制位 (控制开/关 ) 这里要注意TMOD中 GATE 的设置


 定时器0

 TF0 溢出标志位 (溢出时其为 1 ,会向CPU 请求中断 ,CPU响应后 0) 可手动设置

 TR0 运行控制位 (控制开/关 ) 这里要注意TMOD中 GATE 的设置


IE1 / IE0  分别为 外部中断1 / 外部中断0 请求标志位

有请求时为1 处理后  由硬件自动清0(默认为0)


IT1 / IT0 分别为外部中断1 / 外部中断 0 触发方式控制位 为0 是低电平触发

程序设计时:在中断服务例程(ISR)的开始部分直接控制IO拉高(低电平触发时)

假设设置为 低电平 触发

低电平时 IE0或IE1 会被置位,即设置为1 表示有一个中断请求待处理

中断请求来时,以下步骤会发生:

  1. 中断请求使IE0或IE1置位(设置为1)。
  2. CPU响应中断请求,暂停当前的任务,并跳转到中断服务例程(ISR)。
  3. 在ISR中,你处理中断请求,完成相应的任务。
  4. 在ISR结束之前,你需要手动或自动 清零IE0或IE1,以表示中断请求已经被处理完毕。

定时器 程序设计 

例子:产生1kHz方波信号  时钟频率12MHz
分析:
        信号周期T=1/f  T=1/1000 =1ms 
        高低电平设计为0.5ms(500μs)
        定时初始值计算公式:2^16-定时值=2^16-500=65036
第一计数器 A 存储 初值 高八位,第二计数器 B 存储 初值 低八位

在计算机科学中,一个字节由8位二进制数字组成。这8位数字可以分为高四位和低四位,也可以称为高四位和低四位。

  • 高八位:指的是这个字节中最左边的8位,也就是最高位的那一部分。
  • 低八位:指的是这个字节中最右边的8位,也就是最低位的那一部分。

65036(10进制)转换成16进制为 0xFE0C   A存储FE  B存储0C

因 65036 数过大,计算比较费劲 所以要适当 缩小 

65036/256=取商得到  254

计数器值常需除以256,因计算机处理数据以字节为单位,每字节8位,可表256个值(0-255)。此操作适用于字节操作、防止溢出、图像处理中表示颜色深度、遵循数据格式及简化数学计算。

在计算机科学和电子工程中,计数器的值经常需要  除以256,这通常是因为以下几个原因:

1. 字节操作:

        计算机中的数据通常以字节(byte)为单位处理,而一个字节等于8位(bit)。由于256等于2的8次方(2^8),它刚好是一个字节可以表示的最大整数值(从0到255)。因此,当处理字节或进行位操作时,256是一个关键的参考点。


2. 溢出和模运算:

        计数器在增加过程中可能会超过其最大表示范围,导致溢出。如果一个计数器是用一个字节表示的,那么当它的值超过255时,就会从0开始循环。这种现象可以用模运算(即取余数)来描述,而模数通常是256。


3. 颜色深度:

        在图形和图像处理中,每个像素的颜色可能由若干个字节表示,比如RGB色彩模型中,每个颜色分量(红、绿、蓝)通常用一个字节表示,因此有256种可能的强度级别。


4. 协议和数据格式:

        某些通信协议或数据格式可能规定了特定的字段长度或计数范围,这时候使用256作为基数可以帮助确保兼容性和标准化。


5. 数学和算法:

        在一些数学算法和数据结构中,256因其与二进制系统的紧密关系,常常被用作基数或除数,以简化计算和逻辑操作。

总的来说,除以256的操作反映了计算机系统中对字节边界和模运算的常见需求。

65036%256=取余数 12

在计算机科学和数学中,取余数(模运算)是一种非常常见的操作。当我们对一个数进行除法运算时,余数是除不尽的部分。取余数的操作可以帮助我们解决以下几类问题:

  1. 溢出处理:在某些系统中,例如基于字节的操作,我们需要确保数值不会超过某个范围(如0到255)。通过取余数,我们可以使数值“循环”回这个范围内,避免溢出。

  2. 周期性事件:如果我们想要跟踪每隔一定数量的事件发生的情况(比如每256个事件),取余数可以帮助我们确定是否到达了这个周期的某个特定点。

  3. 密码学:在密码学中,模运算是基础操作之一,用于创建和解密密码系统。

  4. 数据校验和压缩:在数据传输和存储中,模运算可以用于生成和验证校验和,以检测错误。在某些压缩算法中,它也被用来减少数据的大小。

  5. 数学算法:许多数学算法和公式中会用到模运算,因为它可以简化计算,特别是在处理大数时。

对于65036除以256的情况,取余数的操作可以告诉我们65036在256的倍数之间的“剩余”部分是多少。

 定时器 程序代码

设置工作模式 :第一计数器 A 存储 初值 高八位,第二计数器 B 存储 初值 低八位

TMOD=0X01;
//0x01 是一个十六进制数,它代表的二进制数是 0000 0001
A=65036/256;//存储高八位
B=65036%256;//存储低八位
EA=1;//打开总中断
ET0=1;//允许定时器0中断
TR0=1;//打开定时器0

定时器 中断函数代码 

 void T0(void) interrupt 1 using 1

{

A=65036/256;//存储高八位   复位
B=65036%256;//存储低八位 复位

这里放入中断后需要做的操作

}

 代码解释:
  1. void T0(void):这是一个函数声明,表明函数 T0 不接受任何参数,并且不返回任何值。
  2. interrupt 1:这是关键字和参数,用于指定这个函数是一个中断服务例程,其中 1 表示中断号。不同的中断号对应不同的中断源.
  3. using 1:这是另一个关键字和参数,用于指定该中断服务例程使用的工作寄存器组。在一些微控制器中,允许程序员在中断服务例程中使用不同的工作寄存器组,以避免与主程序中的寄存器冲突。这里的 1 表示使用第1个工作寄存器组。
中断号解释:  interrupt
  1. 外部中断0 (INT0)         中断号0
  2. 定时器/计数器0 (T0)    中断号1
  3. 外部中断1 (INT1)         中断号2
  4. 定时器/计数器1 (T1)    中断号3
  5. 串行口中断 (串行I/O)   中断号4
寄存器组解释: using 参考链接icon-default.png?t=O83Ahttps://blog.csdn.net/cssdl/article/details/41674095?sharetype=blogdetail&sharerId=41674095&sharerefer=PC&sharesource=qq_43422073&sharefrom=from_link

R0-R7在数据存储器里的实际地址是由特殊功能寄存器PSW里的RS1、RS0位决定的。

using 0时
        设置 RS1=0,RS0 =0,用第0组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(00H)....R7(07H)


using 1时
        设置 RS1=0,RS0 =1,用第1组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(08H)....R7(0FH)


using 2时
        设置 RS1=1,RS0 =0,用第2组寄存器,R0--R7的在数据存储区里的实际地址是08H-0FH。R0(10H)....R7(17H)


using 3时
        设置 RS1=1,RS0 =1,用第3组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(18H)....R7(1FH)

计数器为什么要复位 :

在单片机编程中,特别是涉及到定时器/计数器的中断服务例程时,经常会看到这样的情况:在中断服务例程的开始部分,会将一些寄存器的值重新赋值给计数器。

1. 防止溢出:

        定时器/计数器在达到最大值后会溢出并从零开始计数。如果不重新赋值,计数器可能会继续从溢出点开始计数,导致不正确的结果。通过在中断服务例程中重新赋值,可以确保计数器从预期的值开始计数。


2. 实现精确的定时:

        在一些应用中,需要实现非常精确的定时。通过在中断服务例程中重新赋值计数器,可以调整定时器的计数值,从而实现更精确的定时。


3. 初始化计数器:

        在中断服务例程中,可能需要对计数器进行初始化,以便从一个已知的状态开始。这在处理复杂的定时任务或多任务环境中尤为常见。


4. 实现周期性任务:

        如果中断服务例程需要周期性地执行某些任务,可以通过重新赋值计数器来实现这一点。例如,如果中断服务例程每1毫秒执行一次,可以在中断服务例程的开始部分将计数器设置为一个适当的值,以确保下次中断发生在1毫秒后。


5. 处理中断嵌套:

        在多中断环境下,可能会出现中断嵌套的情况。在这种情况下,需要确保每次中断服务例程执行时,计数器的值是正确的。通过在中断服务例程中重新赋值计数器,可以确保这一点。


中断相关资料 

EX0:EX0=1,允许外部中断0中断;EX0=0,禁止中断
ET0:ET0=1,允许T0中断;ET0=0,禁止中断
EX1:EX1=1,允许外部中断1中断;EX1=0,禁止中断
ET1:ET1=1,允许T1中断;ET1=0,禁止中断
ES:ES=1,允许串行口中断;ES=0,禁止中断

EA:EA=1,CPU开放中断;EA=0,CPU禁止所有的中断请求

中断相关 参考链接icon-default.png?t=O83Ahttps://blog.csdn.net/weixin_43398418/article/details/121916218?sharetype=blogdetail&sharerId=121916218&sharerefer=PC&sharesource=qq_43422073&sharefrom=from_link


 TMOD=0X01;
//0x01 是一个十六进制数,它代表的二进制数是 0000 0001

 这里操作的是 定时器0  按位带入以下图片中 可以知道定时器0 的 M1=0 M0=1

M1=0 M0=1 时 为16位 两个8位全用


计数器程序代码 

例子: 50kHz方波信号  时钟频率12MHz

TMOD=0X20;
//0X20 是二进制 0010000 控制的是定时器1
//结合上图M1=1 M0=0为8位自动重载 第一个计数器A1溢出之后,先转移当前值到 第二个计数器B1中,再复位为0
A1=246;//设置初始值 溢出相关
B1=246;//设置初始值
//246-256 需要10μs 
EA=1;//打开总中断
ET1=1;//打开定时器1中断
TR1=1;//启动定时器1
void T1(void) interrupt 3 using 1
{
//因为是8位重载所以不用初始化计数器
//这里放入需要做的操作}

注意:以上代码省略了main()主函数

相关文章:

51单片机快速入门之定时器和计数器

51单片机快速入门之定时器 断开外部输入 晶振振荡 假设为 12MHz 12分频之后,为1MHz 当其从0-65536 时,需要65536μs 微秒 也就是65.536ms 毫秒 溢出(值>65536 时)>中断>执行中断操作 假设需要1ms后产生溢出,则需要设置初始值为64536 此时定时器会从 64536 开始计…...

【计算机网络 - 基础问题】每日 3 题(一)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…...

Unity全面取消Runtime费用 安装游戏不再收版费

Unity宣布他们已经废除了争议性的Runtime费用,该费用于2023年9月引入,定于1月1日开始收取。Runtime费用起初是打算根据使用Unity引擎安装游戏的次数收取版权费。2023年9月晚些时候,该公司部分收回了计划,称Runtime费用只适用于订阅…...

IDEA测试类启动报 “java: 常量字符串过长” 解决办法

目录标题 问题描述问题分析解决办法其他办法 问题描述 问题分析 字符串长度过长,导致 idea 默认使用的 javac 编译器编译不了。 查询资料发现,原因是javac在编译期间,常量字符串最大长度为65534。 解决办法 Javac 编译器改为 Eclipse 编译…...

计算机科学基础 -- 访存单元

访存单元(Memory Access Unit)的概念 访存单元(Memory Access Unit) 是处理器中的一个关键模块,负责处理指令中的内存访问操作,包括从内存中读取数据和将数据写入内存。由于内存访问速度通常比处理器执行速…...

Linux压缩、解压缩、查看压缩内容详解使用(tar、gzip、bzip2、xz、jar、war、aar)

在Linux环境中,你可以使用各种命令来压缩、解压缩和查看不同类型的压缩包。以下是常用的命令和操作说明,包括tar、gzip、bzip2、xz、jar、war、aar等类型的包文件。 1. tar命令:压缩、解压、查看tar包 压缩: tar -cvf archive.…...

StreamReader 和 StreamWriter提供自动处理字符编码的功能

FileStream、StreamReader 和 StreamWriter 都用于文件操作,但它们的设计目标和使用方式有所不同。下面是它们之间的主要差异以及如何结合使用的说明: 1. FileStream 用途:提供对文件的字节流访问,用于读写二进制数据。特点&…...

Gitlab备份、迁移、恢复和升级(Gitlab Backup, migration, recovery, and upgrade)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…...

MySQL:INSERT command denied to user

异常: INSERT command denied to user 解决办法: 请检查一下 MySQL 帐号是否有相应的权限...

【Android安全】Ubuntu 16.04安装GDB和GEF

1. 安装GDB sudo apt install gdb-multiarch 2. 安装GEF(GDB Enhanced Features) 官网地址:https://github.com/hugsy/gef 2.1 安装2021.10版本 但是在Ubuntu 16.04上,bash -c "$(curl -fsSL https://gef.blah.cat/sh)"等命令不好使&…...

ISO 21434与网络安全管理系统(CSMS)的协同作用

ISO/SAE 21434与CSMS(网络安全管理系统)之间的关系主要体现在以下几个方面: 提供指导框架:ISO/SAE 21434《道路车辆—网络安全工程》是一项国际标准,它为汽车行业提供了实施网络安全管理系统的国际认可的方法和最佳实…...

Vue 67 vuex 四个map方法的使用

mapState方法:用于帮助我们映射state中的数据为计算属性 computed: {//借助mapState生成计算属性:sum、school、subject(对象写法)...mapState({sum:sum,school:school,subject:subject}),//借助mapState生成计算属性:…...

Unity自带脚本之GameObject脚本

目录 GameObject基本成员变量 静态方法 创建自带几何体 1.查找对象 通过tag来查找对象 2查找多个对象 实例化对象(克隆对象)的方法 删除对象的方法 过场景不移除 Unity中的Object和C#中的万物之父的区别 成员方法 创建空物体 为对象 动态添加…...

软件测试面试题-自测

一、测试流程 1.项目测试流程你是怎么开展的? ①首先,需求分析阶段,分析需求点,需求确定以后进入测试计划阶段,参考需求规格说明书进行测试计划编写 ②接着,进入测试设计阶段,依据需求文档及原…...

深度学习-神经网络

文章目录 一、基本组成单元:神经元二、神经网络层三、偏置与权重四、激活函数1.激活函数的作用2.常见的激活函数1).Sigmoid2).Tanh函数3).ReLU函数 五、优点与缺点六、总结 神经网络(Neural Network, NN)是一种模拟人类大脑工作方式的计算模型…...

Redis - 集群篇 - 集群模式

面试的时候被人问到集群的问题,搬砖仔哪懂这么多,继续整理一下知识点 Redis 集群模式 Redis集群就是将多个Redis节点连接在一起, 让Redis在不同的节点上同时提供服务。 Redis集群主要有三种模式: 主从复制模式(mast…...

Robot Operating System——线速度和角速度

大纲 应用场景1. 移动机器人控制场景描述具体应用 2. 无人机控制场景描述具体应用 3. 机械臂运动控制场景描述具体应用 4. 自动驾驶车辆控制场景描述具体应用 5. 机器人仿真场景描述具体应用 6. 机器人传感器数据处理场景描述具体应用 定义字段解释 案例 geometry_msgs::msg::T…...

量化投资策略_因子打分选股的案例实现

一:因子打分选股的介绍 因子打分选股是一种量化投资策略,它通过选取多个与股票收益率相关的因子,对股票进行综合评分,然后根据评分来选择股票构建投资组合。以下是构建多因子打分选股模型的一般步骤: 数据预处理&…...

架构师知识梳理(七):软件工程-工程管理与开发模型

软件工程概述 软件开发生命周期 软件定义时期:包括可行性研究和详细需求分析过程,任务是确定软件开发工程必须完成的总目标,具体可分成问题定义、可行性研究、需求分析等。软件开发时期:就是软件的设计与实现,可分成…...

bp的模块被隐藏了

看我们现在没有代理那个模块了 我们点击查看 这里有被我们隐藏的模块,比如代理等,把前面的眼睛点一下 这个模块就出来了,如果想把他固定在任务栏里 拖动这个位置 就好了,如果有其他问题可以留言,看到可进我的努力给你…...

C++学习笔记(21)

243、条件变量-生产消费者模型 条件变量是一种线程同步机制。当条件不满足时,相关线程被一直阻塞,直到某种条件出现,这些线 程才会被唤醒。 C11 的条件变量提供了两个类: condition_variable:只支持与普通 mutex 搭配&…...

Ubuntu系统入门指南:常用命令详解

Ubuntu系统入门指南:常用命令详解 引言 Ubuntu是一个基于Linux内核的开源操作系统,由Canonical公司和社区共同开发和维护。它以易用性、稳定性和广泛的软件支持而著称,广泛应用于个人电脑、服务器和云计算环境。对于新手来说,掌…...

keep-alive缓存不了iframe

最近做了个项目&#xff0c;其中有个页面是由 iframe 嵌套了一个另外的页面&#xff0c;在运行的过程中发现 KeepAlive 并不生效&#xff0c;每次切换路由都会触发 iframe 页面的重新渲染&#xff0c;代码如下&#xff1a; <router-view v-slot"{ Component }">…...

Gradio快速部署构建AIGC的web应用 ,python

Gradio快速部署构建AIGC的web应用 &#xff0c;python Gradio开源项目链接&#xff1a; https://github.com/gradio-app/gradiohttps://github.com/gradio-app/gradio &#xff08;1&#xff09;python的pip安装&#xff1a; pip install gradio &#xff08;2&#xff09;写…...

《职教论坛》

《职教论坛》投稿须知 《职教论坛》为全国中文核心期刊。为进一步提高期刊的规范化和标准化&#xff0c;也可使作者投搞有规可循&#xff0c;特对来稿提出如下要求&#xff1a; 一、稿件应有创新内容&#xff0c;应观点明确、资料准确、结构严谨、表述清楚、文字简明&#xff…...

JZ2440开发板——S3C2440的时钟体系

参考博客 &#xff08;1&#xff09;S3C2440-裸机篇-05 | S3C2440时钟体系详解&#xff08;FCLK、PCLK、HCLK&#xff09; 一、三种时钟&#xff08;FCLK、HCLK、PCLK&#xff09; 如下图所示&#xff0c;S3C2440的时钟控制逻辑&#xff0c;给整个芯片提供三种时钟&#xff1…...

[数据集][目标检测]男女性别检测数据集VOC+YOLO格式9769张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;9769 标注数量(xml文件个数)&#xff1a;9769 标注数量(txt文件个数)&#xff1a;9769 标注…...

static 初始化报错

在 C 或 C 中&#xff0c;当你在函数中使用 static 关键字初始化一个局部变量时&#xff0c;编译器要求初始化器&#xff08;initializer&#xff09;是编译时常量。如果你尝试用动态计算的值初始化 static 变量&#xff08;如函数参数或运行时生成的值&#xff09;&#xff0c…...

3D Gaussian Splatting 论文学习

概述 目前比较常见的渲染方法大致可以分为2种&#xff1a; 将场景中的物体投影到渲染平面&#xff1a;传统的渲染管线就是这种方式&#xff0c;主要针对Mesh数据&#xff0c;可以将顶点直接投影成2D的形式&#xff0c;配合光栅化、深度测试、Alpha混合等就可以得到渲染的图像…...

MySQL 安全机制全面解析

‍ 在如今的数字化时代&#xff0c;数据库安全 变得越来越重要。为了防止对数据库进行非法操作&#xff0c;MySQL 定义了一套完整的安全机制&#xff0c;包括用户管理、权限管理 和 角色管理。本文将为你深入浅出地介绍这三大安全机制&#xff0c;帮助你轻松掌握MySQL的安全管…...