51单片机基础05 定时器

目录

一、为什么要定时器

二、定时器中断

1、定时器中断参数

2、定时器中断程序

3、定时器计数


一、为什么要定时器

        前文提到,比如进行流水灯等操作,都是直接写了delay_ms这类操作。

        但是在51单片机中,其一般就是靠双for进行的循环时延,单片机会浪费这部分时间而不能做其他的事

        其次如果程序很多的情况下,就得根据其他代码执行的时间来调整时延,这非常麻烦。

        那有没有既可以定时、又不影响其他程序的进行呢?        

        比如,通过两个按键控制,按下按键后两个LED延时1s切换状态,如果通过以下代码进行,那么在延时的时候,按键按下另一个KEY就会完全没有反应。

if(KEY0==0)
{
    delay_ms(10);
    if(KEY0==0)
    {
        delay_ms(1000);
        LED0=~LED0;
    }
}
if(KEY1==0)
{
    delay_ms(10);
    if(KEY1==0)
    {
        delay_ms(1000);
        LED1=~LED1;
    }
}

二、定时器中断

1、定时器中断参数

中断编号中断名中断源
1定时器0溢出中断TF0
3定时器1溢出中断TF1

        可以看到定时器0和定时器1的中断编号分别为1、3,因此T1的中断优先级没有T0高。

中断寄存器功能实现
ET0定时器/计数器T0的溢出中断允许控制位

1:允许T0中断

0:禁止T0中断

ET1定时器/计数器T1的溢出中断允许控制位

1:允许T1中断

0:禁止T1中断

        该寄存器控制了是否允许中断。

中断触发控制位功能实现
TF0定时/计数器T0溢出中断请求标志位

1:进入T0中断

0:未进入T0中断

TF1定时/计数器T1溢出中断请求标志位

1:进入T1中断

0:未进入T1中断

        该寄存器在计数溢出后自动置位为1并进入中断服务函数,需要用户手动清零。

定时器开关控制功能实现
TR0打开或关闭定时器T0

1:打开

0:关闭

TR1打开或关闭定时器T1

1:打开

0:关闭

        配套初始化。

        如下为TMOD的控制,其中D0~D3为定时器0配置,D4~D7为定时器1配置。

D3D2D1D0
GATEC/TM1M0

0:仅要求TR0=1开启定时器

1:同时要求T0引脚为高电平才可以开启定时器

0:定时

1:计数

00:13位计数器8192

01:16位计数器65536

10:8位计数器256,可自动重新装载

11:两组独立8位计时器256,不可同时用

TMOD寄存器,必须直接对整个地址操作,而不像TCON,其可以单位操作。

        定时时间TH0、TL0控制,以定时器01模式为例

        TH0=(65536-XX)/256

        TL0=(65536-XX)%256

        其中XX表示多少us,例如XX=50000,就是50ms,由此可以看出,单次定时时间最大为65536ms,最小为1us。

2、定时器中断程序

举例,还以上面按键控制LED闪烁为例

unsigned int count0=0;
unsigned int count1=0;
char flag0 = 0;
char flag1 = 0;
void main()
{
   EA=1;            //开启总中断
   TMOD =0x01;
   TH0=(65536-50000)/256;    //50ms
   TL0=(65536-50000)%256;
   TR0=1;         //打开定时器T0
   ET0=1;         //允许中断

   while(1)
   {
       if(key0==0)
        {
            delay_ms(10)
            if(key0==0) 
                flag0=1;
        }
       if(key1==0)
        {
            delay_ms(10)
            if(key1==0) 
                flag1=1;
        }
   }
}
void time0() interrupt 1
{
   TF0=0;          //清除触发位,实现再次计数
   TH0=(65536-50000)/256;    //50ms 装初值
   TL0=(65536-50000)%256;
   if(flag0==1)
       count0+=1;
   if(count0>=20)
   {
      led0=~led0;
      count0=0;
   }
   if(flag1==1)
       count1+=1;
   if(count1>=20)
   {
      led1=~led1;
      count1=0;
   }
 }

        可以看到定时器50ms的中断,判断到按键按下后,在中断额外进行计数,达到20,说明达到了1秒,从而进行LED反转,不影响main内的有关代码执行。

3、定时器计数

前文提到,T0引脚是定时器的引脚,但是前面的定时代码怎么都和T0无关呢。

        当51单片机的定时器工作在计数模式时,它会通过外部引脚(如T0或T1引脚)接收外部输入的脉冲信号。这时,I/O口就有直接关系了。外部设备产生的脉冲通过这些引脚输入到单片机,定时器/计数器累加这些脉冲来实现计数功能。举例来说,假如你需要用定时器0来测量输入信号的频率,你可以将信号输入到T0引脚,然后配置定时器0为计数模式,它会根据输入脉冲增加计数值。

        计数模式C/T=1,16位M1M0=01,即TMOD=0101=0X05;

#include <reg51.h>

// 定义定时器的控制位
sbit T0_PIN = P3^4; // T0口作为输入信号(定时器0外部输入)

// 定义全局变量
unsigned int count = 0; // 计数器计数值
unsigned long frequency = 0; // 测得的频率值

void Timer1_Init(void) {
    TMOD |= 0x10; // 设置定时器1为模式1(16位定时模式)
    TH1 = 0x3C; // 高字节初值(1秒定时器)
    TL1 = 0xB0; // 低字节初值
    ET1 = 1;   // 使能定时器1中断
    EA = 1;    // 总中断使能
    TR1 = 1;   // 启动定时器1
}

void Timer0_Init(void) {
    TMOD |= 0x05; // 设置定时器0为模式5(16位计数模式)
    TR0 = 1;      // 启动计数器0
}

void Timer1_ISR(void) interrupt 3 {
    TR1 = 0; // 关闭定时器1

    // 计算频率
    count = (TH0 << 8) | TL0; // 读取定时器0的计数值
    TH0 = 0; // 清零高字节
    TL0 = 0; // 清零低字节
    frequency = count;
    count = 0; // 计数值清零

    // 重装载定时器1初值
    TH1 = 0x3C;
    TL1 = 0xB0;
    TR1 = 1; // 重启定时器1
}

void main(void) {
    Timer0_Init(); // 初始化定时器0(计数器模式)
    Timer1_Init(); // 初始化定时器1(定时器模式)

    while (1) {
        
        // 这里可以添加代码来显示频率值frequency,如通过串口输出
    }
}

        注意:中断服务函数理应不要放太多的代码,尤其是延时是要完全避免的,否则会影响相关的精度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/917370.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习日志011--模块,迭代器与生成器,正则表达式

一、python模块 在之前学习c语言时&#xff0c;我们学了分文件编辑&#xff0c;那么在python中是否存在类似的编写方式&#xff1f;答案是肯定的。python中同样可以实现分文件编辑。甚至还有更多的好处&#xff1a; ‌提高代码的可维护性‌&#xff1a;当代码被分成多个文件时…

【提高篇】3.3 GPIO(三,工作模式详解 上)

目录 一,工作模式介绍 二,输入浮空 2.1 输入浮空简介 2.2 输入浮空特点 2.3 按键检测示例 2.4 高阻态 三,输入上拉 3.1 输入上拉简介 3.2 输入上拉的特点 3.3 按键检测示例 四,输入下拉 4.1 输入下拉简介 4.2 输入下拉特点 4.3 按键检测示例 一,工作模式介绍…

Excel单元格中自适应填充多图

实例需求&#xff1a;在Excel插入图片时&#xff0c;由于图片尺寸各不相同&#xff0c;如果希望多个图片填充指定单元格&#xff0c;依靠用户手工调整&#xff0c;不仅费时费力&#xff0c;而且很难实现完全填充。如下图中的产品图册&#xff0c;有三个图片&#xff0c;如下图所…

@Autowired 和 @Resource思考(注入redisTemplate时发现一些奇怪的现象)

1. 前置知识 Configuration public class RedisConfig {Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template new RedisTemplate<>();template.setConnectionFactory(facto…

从零开始学习 sg200x 多核开发之 milkv-duo256 编译运行 sophpi

sophpi 是 算能官方针对 sg200x 系列的 SDK 仓库 https://github.com/sophgo/sophpi &#xff0c;支持 cv180x、cv81x、sg200x 系列的芯片。 SG2002 简介 SG2002 是面向边缘智能监控 IP 摄像机、智能猫眼门锁、可视门铃、居家智能等多项产品领域而推出的高性能、低功耗芯片&a…

防火墙----iptables

防火墙是位于内部网和外部网之间的屏障&#xff0c;他按照系统管理员预先定义好的规则来控制数据包的进出 一、iptables简介 防火墙会从以上至下的顺序来读取配置的策略规则&#xff0c;在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为&#xff08;即放行或阻止&…

【CSS】absolute定位的默认位置

position: absolute; 属性会使元素脱离正常的文档流&#xff0c;并相对于最近的非 static 定位祖先元素进行定位。如果没有这样的祖先元素&#xff0c;则相对于初始包含块&#xff08;通常是视口&#xff09;进行定位。 但是当top和left没有指定具体值时&#xff0c;元素的在上…

(一)机器学习、深度学习基本概念简介

文章目录 机器学习、深度学习基本概念简介一、什么是机器学习&#xff08;一&#xff09;举例&#xff08;二&#xff09;不同类型的函数&#xff08;三&#xff09;机器是怎么找这个函数的&#xff08;1&#xff09;Function with Unknown Parameters&#xff08;2&#xff09…

CentOS8 启动错误,enter emergency mode ,开机直接进入紧急救援模式,报错 Failed to mount /home 解决方法

先看现场问题截图&#xff1a; 1.根据提示 按 ctrld 输入 root 密码&#xff0c;进入系统。 2. 在紧急模式下运行&#xff1a;journalctl -xe &#xff0c;查看相关日志&#xff0c;找到关键点&#xff1a; Failed to mount /home 3.接着执行修复命令&#xff1a; xfs_repa…

mysql 大数据查询

基于 mysql 8.0 基础介绍 com.mysql.cj.protocol.ResultsetRows该接口表示的是应用层如何访问 db 返回回来的结果集 它有三个实现类 ResultsetRowsStatic 默认实现。连接 db 的 url 没有增加额外的参数、单纯就是 ip port schema 。 @Test public void generalQuery() t…

智能零售柜商品识别

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

【ArcGIS微课1000例】0128:ArcGIS制作规划图卫星影像地图虚化效果

文章目录 一、效果展示二、加载数据三、效果制作四、注意事项一、效果展示 二、加载数据 订阅专栏后,从csdn私信查收完整的实验数据资料,从中选择并解压,加载0128.rar中的卫星影像及矢量范围数据,如下所示: 三、效果制作 1. 创建掩膜图层 新建一个矢量图层,因为主要是…

【Goland】——Gin 框架简介与安装

文章目录 1. Gin 框架概述1.1 什么是 Gin 框架&#xff1f;1.2 为什么选择 Gin&#xff1f;1.3 使用场景 2. 安装 Go 与 Gin 框架2.1 安装 Go 语言环境2.2 初始化 Go 项目2.3 安装 Gin 框架 3. 编写第一个 Gin 应用3.1 Gin 最小化示例代码代码解读3.2 运行程序3.3 测试服务 4. …

【新华妙笔-注册/登录安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【SpringBoot】公共字段自动填充

问题引入 JavaEE开发的时候&#xff0c;新增字段&#xff0c;修改字段大都会涉及到创建时间(createTime)&#xff0c;更改时间(updateTime)&#xff0c;创建人(craeteUser)&#xff0c;更改人(updateUser)&#xff0c;如果每次都要自己去setter()&#xff0c;会比较麻烦&#…

对称加密与非对称加密:密码学的基石及 RSA 算法详解

对称加密与非对称加密&#xff1a;密码学的基石及 RSA 算法详解 在当今数字化的时代&#xff0c;信息安全至关重要。对称加密和非对称加密作为密码学中的两种基本加密技术&#xff0c;为我们的数据安全提供了强大的保障。本文将深入探讨对称加密和非对称加密的特点、应用场景&…

用go语言后端开发速查

文章目录 一、发送请求和接收请求示例1.1 发送请求1.2 接收请求 二、发送form-data格式的数据示例 用go语言发送请求和接收请求的快速参考 一、发送请求和接收请求示例 1.1 发送请求 package mainimport ("bytes""encoding/json""fmt""ne…

微服务day09

DSL查询 快速入门 GET /items/_search {"query": {"match_all": {}} } 叶子查询 GET /items/_search {"query": {"match_all": {}} }GET /items/_search {"query": {"multi_match": {"query": "脱…

鸿蒙NEXT应用示例:切换图片动画

【引言】 在鸿蒙NEXT应用开发中&#xff0c;实现图片切换动画是一项常见的需求。本文将介绍如何使用鸿蒙应用框架中的组件和动画功能&#xff0c;实现不同类型的图片切换动画效果。 【环境准备】 电脑系统&#xff1a;windows 10 开发工具&#xff1a;DevEco Studio NEXT B…

(02)ES6教程——Map、Set、Reflect、Proxy、字符串、数值、对象、数组、函数

目录 前言 一、Map Maps 和 Objects 的区别 Map的迭代 forEach() Map对象的操作 二、Set Set 中的特殊值 三、Reflect 四、Proxy 五、字符串 六、数值 七、对象 八、数组 九、函数 参考文献 前言 一、Map Map 对象保存键值对。任何值(对象或者原始值) 都可以…