51单片机入门_江协科技_17~18_OB记录的笔记

17. 定时器

  • 17.1.
    定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成,无需占用CPU外围IO接口;

    定时器作用:
    (1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作;
    (2)替代长时间的Delay,提高CPU的运行效率和处理速度,因为delay程序占用CPU资源,同时导致CPU无法处理外部诸如按键的操作;
    (…)

  • 17.2. STC89C52 定时器相关扩展阅读:STC89C52的介绍手册
    官方链接地址: https://www.stcmcu.com/datasheet/stc/STC-AD-PDF/STC89C51RC-RD+_GUIDE-CHINESE.pdf

  • 17.3. STC89C52定时器资源
    •定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源
    •注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的

  • 17.4. 51单片机定时器内部工作原理
    •定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔“一秒”,计数单元的数值就增加一,当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生“响铃提醒”,使程序跳转到中断服务函数中执行
    在这里插入图片描述

  • 17.5. 定时器工作模式:
    •STC89C52的T0和T1均有四种工作模式:
    模式0:13位定时器/计数器
    模式1:16位定时器/计数器(常用)
    模式2:8位自动重装模式
    模式3:两个8位计数器
    •工作模式1框图:
    在这里插入图片描述

    •SYSclk:系统时钟,即晶振周期,本开发板上的晶振为12MHz

  • 17.6. 中断系统

    • 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。
    • 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。微型机的中断系统一般允许多个中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU总是先响应优先级别最高的中断请求。
    • 当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。这样的中断系统称为多级中断系统,没有中断嵌套功能的中断系统称为单级中断系统。
  • 17.7. 中断程序流程:
    在这里插入图片描述

  • 17.8. 中断资源:
    •中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、定时器2中断、外部中断2、外部中断3)
    •中断优先级个数:4个
    •中断号:
    在这里插入图片描述

•注意:中断的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等

  • 17.9. 定时器和中断系统;
    在这里插入图片描述

  • 17.10. 定时器相关寄存器:

在这里插入图片描述

18. 按键控制LED流水灯模式&定时器时钟

  • 18.1. 计时器子函数与中断子函数测试程序:
#include <REGX52.h>void TimerR0_Init() //定时器初始化子函数
{//TMOD=0x01; //0000 0001;如果同时使用T0与T1则此TMOD赋值方式有问题//TMOD=TMOD&0xf0;//把TMOD低4位清0,高4位不变;与清0;//TMOD=TMOD|0x01;//把TMOD最低位置1,高4位不变;或置1;TMOD&=0xf0;//上述简写TMOD|=0x01;//上述简写TF0=0;TR0=1;TH0=64535/256; //高8位数值,从64535到65535需要1000us,超出65535后溢出TL0=64535%256; //低8位数值ET0=1;EA=1;PT0=0;
}void main() //主程序
{TimerR0_Init();while(1){}}unsigned int T0_Count;
void TimerR0_Routine() interrupt 1 //中断子函数
{TH0=64535/256; //重新赋予初值,防止从0开始计数TL0=64535%256; //重新赋予初值,防止从0开始计数	T0_Count++;if(T0_Count>=1000){T0_Count=0;P2_0=~P2_0;}
}
  • 18.2. STC-ISP中定时器的相关配置
    上述程序与STC-ISP中的示例定时器计算器中的程序有1us的差距,同时需要注意STC-ISP中的软件的配置:
    在这里插入图片描述

此时的C代码为:

void Timer0_Init(void)		//1毫秒@12.000MHz
{//AUXR &= 0x7F;			//定时器时钟12T模式,新版本问题此语句删除TMOD &= 0xF0;			//设置定时器模式TMOD |= 0x01;			//设置定时器模式TL0 = 0x18;				//设置定时初始值 计算后与64535%256=17不同;TH0 = 0xFC;				//设置定时初始值 计算后与64535/256相同; TF0 = 0;				//清除TF0标志TR0 = 1;				//定时器0开始计时
}
  • 18.3. 示例18.1中的程序更新后如下:
#include <REGX52.h>void TimerR0_Init() //定时器0初始化子函数
{TMOD&=0xf0;//上述简写TMOD|=0x01;//上述简写TF0=0;TR0=1;TH0=0xfc; //高8位数值,从64535到65535需要1000us,超出65535后溢出TL0=0x18; //低8位数值ET0=1;EA=1;PT0=0;
}void main() //主程序
{TimerR0_Init();while(1){}}unsigned int T0_Count;
void TimerR0_Routine() interrupt 1 //中断子函数
{TH0=64535/256; //重新赋予初值,防止从0开始计数TL0=64535%256; //重新赋予初值,防止从0开始计数	T0_Count++;if(T0_Count>=1000){T0_Count=0;P2_0=~P2_0;}
}
  • 18.4. 定时器函数模块化(模块化定时器的初始化程序)
  • TimeR0.c
#include <REGX52.H>
/*** @brief 定时器初始化子函数,1ms,12MHz* @param 无* @retval 无*/void TimeR0_Init() //定时器初始化子函数
{//AUXR &= 0x7F;			//定时器时钟12T模式TMOD &= 0xF0;			//设置定时器模式TMOD |= 0x01;			//设置定时器模式TL0 = 0x18;				//设置定时初始值TH0 = 0xFC;				//设置定时初始值TF0 = 0;				//清除TF0标志TR0 = 1;				//定时器0开始计时ET0=1;EA=1;  //PT0=0; //中断优先级
}//以下程序全部注释方便后续调用,定时器中断函数模板
//
//void TimeR0_Routine() interrupt 1 //中断子函数
//{
//	static unsigned int T0Count //设置静态子函数用T0Count,防止T0Count丢失
//	TL0=0x18;				//设置定时初始值
//	TH0=0xFC;				//设置定时初始值
//	T0Count++;
//	if(T0Count>=1000)
//	{
//		T0Count=0;
//		
//	}
//}
  • TimeR0.h
#ifndef _TIMER0_H_ 
#define _TIMER0_H_  void TimeR0_Init();#endif
  • 18.5. 4个独立按键的模块化程序:
  • Four_Key.c
#include <REGX52.h>
#include "delay_xms.h"
/*** @brief 4个独立按键按下判断程序,按键松手返回KeyNum* @param 无* @retval KeyNum 的返回值,0~4,无按键按下时返回值为0*/unsigned char Four_Key()
{unsigned char KeyNum=0;if(P3_1==0){delay_xms(20);while(P3_1==0);delay_xms(20);KeyNum=1;}if(P3_0==0){delay_xms(20);while(P3_0==0);delay_xms(20);KeyNum=2;}if(P3_2==0){delay_xms(20);while(P3_2==0);delay_xms(20);KeyNum=3;}if(P3_3==0){delay_xms(20);while(P3_3==0);delay_xms(20);KeyNum=4;}return KeyNum;
}
  • Four_Key.h
#ifndef __H_ 
#define __H_  unsigned char Four_Key();#endif
  • 针对建立好的模块化程序进行简单测试,按下相应按键,P2的相应的LED灯亮起;
#include <REGX52.h>
#include "TimeR0.h"
#include "Four_Key.h"unsigned char keynum;
void main() //主程序
{TimeR0_Init();while(1){keynum=Four_Key();if(keynum){if (keynum==1){P2_0=!P2_0;}if (keynum==2){P2_1=!P2_1;}if (keynum==3){P2_2=!P2_2;}if (keynum==4){P2_3=!P2_3;}		}}}void TimerR0_Routine() interrupt 1 //中断子函数
{static unsigned int T0Count; //设置静态子函数用T0Count,防止T0Count丢失TL0=0x18;				//设置定时初始值TH0=0xFC;				//设置定时初始值T0Count++;if(T0Count>=1000){T0Count=0;}
}
  • 测试程序Proteus中测试没有问题,按键按一下相应LED灯亮起,再按一下熄灭;同时测试了独立按键检测程序和中断函数模块程序没有问题。
    在这里插入图片描述

  • 18.6. LED流水灯控制的实现

  • 通过包含 INTRINS.h的函数库中的_cror_与_crol_循环左移与循环右移函数来实现;

#include <REGX52.h>
#include "TimeR0.h"
#include "Four_Key.h"
#include <INTRINS.h>unsigned char keynum,LED_Mode; //增加LED_Mode变量控制LED灯模式void main() //主程序
{TimeR0_Init();P2=0xfe; //P2口LED灯赋予初始值,保证至少1个LED灯亮起;while(1){keynum=Four_Key();if(keynum){if (keynum==1) //当S1按下松开后{LED_Mode++; //LED_Mode数值自动更新if (LED_Mode>=2) LED_Mode=0;}}}}void TimerR0_Routine() interrupt 1 //中断子函数
{static unsigned int T0Count; //设置静态子函数用T0Count,防止T0Count丢失TL0=0x18;				//设置定时初始值TH0=0xFC;				//设置定时初始值T0Count++;if(T0Count>=500){T0Count=0;if (LED_Mode==0)P2=_crol_(P2,1);//通过_crol_(P2,1)函数控制LED左移if (LED_Mode==1)P2=_cror_(P2,1);//通过_cror_(P2,1)函数控制LED右移}
}
  • 18.7. 通过LCD1602来制作一个定时器时钟程序
  • 定时器时钟程序如下:
#include <REGX52.h>
#include "LCD1602.h"
#include "TimeR0.h"unsigned char sec=55,min=59,hour=23;
void main()
{TimeR0_Init();LCD_Init();LCD_ShowString(1,1,"Clock:");//1行1列显示Clock:LCD_ShowString(2,1,"  :  :");//2行中需要显示的分割冒号while(1){LCD_ShowNum(2,7,sec,2);//秒显示LCD_ShowNum(2,4,min,2);//分钟显示LCD_ShowNum(2,1,hour,2);//小时显示}}void TimeR0_Routine() interrupt 1 //中断子函数
{static unsigned int T0Count; //设置静态子函数用T0Count,防止T0Count丢失TL0=0x18;				//设置定时初始值TH0=0xfc;				//设置定时初始值T0Count++;if(T0Count>=1000){T0Count=0;sec++;if(sec>=60){sec=0;min++;if(min>=60){min=0;hour++;if(hour>=24){hour=0;}}}}}
  • proteus测试结果没问题;
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

漫谈:“标准”是一种幻觉 C++语言标准的意义

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 “标准”这个词很迷惑&#xf…

适合户外运动的开放式耳机选哪款?五款开放式耳机推荐

开放式蓝牙耳机由于其开放式设计&#xff0c;适合在户外运动、工作场所等需要保持警觉的场合使用。在户外活动中&#xff0c;能够听到周围环境的声音对于安全和警惕性非常重要。同时&#xff0c;这种耳机在运动或工作时不容易产生不适感&#xff0c;也不会阻碍佩戴者与他人的交…

SQL Server语法基础:入门到精通

博客前言 在数据库管理的世界中&#xff0c;SQL Server无疑是一个重要的角色。无论是初学者还是经验丰富的数据库管理员&#xff0c;都需要对SQL Server的查询语法有深入的理解。本文将带领大家深入解析SQL Server的查询语法&#xff0c;并分享一些实用的技巧&#xff0c;帮助…

智能网联汽车自动驾驶数据记录系统DSSAD数据元素

目录 第一章 数据元素分级 第二章 数据元素分类 第三章 数据元素基本信息表 表1 车辆及自动驾驶数据记录系统基本信息 表2 车辆状态及动态信息 表3 自动驾驶系统运行信息 表4 行车环境信息 表5 驾驶员操作及状态信息 第一章 数据元素分级 自动驾驶数据记录系统记录的数…

后端nginx使用set_real_ip_from获取用户真实IP

随着nginx的迅速崛起&#xff0c;越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速&#xff0c;但是随之也遇到一个问题&#xff1a;nginx如何获取用户的真实IP地址. 前言&#xff1a;Nginx ngx_http_realip_module…

C++ 之 【类与对象】从入门到精通一条龙服务 入门篇

不要觉的自己很没用&#xff0c;其实你还可以给家人带来温暖&#xff0c;比如爸妈看到你就来火 目录&#xff1a; 一、面向过程和面向对象初步认识 二、类的引入 三、类的定义 四、类的访问限定符及封装 1.访问限定符 2.封装 五、类的作用域 六、类的实例化 七、类的…

Ubuntu 22.04安装新硬盘并启动时自动挂载

方法一 要在Ubuntu 22.04系统中安装一个新硬盘、对其进行格式化并实现启动时自动挂载&#xff0c;需要按以下步骤操作&#xff1a; 1. 安装硬盘 - 确保你的硬盘正确连接到计算机上&#xff08;涉及硬件安装&#xff09;。 2. 发现新硬盘 - 在系统启动后&#xff0c;打开终端…

IntelliJ IDEA 2024.1 更新亮点汇总:全面提升开发体验

IntelliJ IDEA 2024.1 更新亮点汇总&#xff1a;全面提升开发体验 文章目录 IntelliJ IDEA 2024.1 更新亮点汇总&#xff1a;全面提升开发体验摘要引言 IntelliJ IDEA 2024.1 的新增功能主要亮点全行代码完成 最终的支持 Java 22 功能新航站楼 贝塔编辑器中的粘滞线 人工智能助…

【数字图像处理matlab系列】空间域处理之亮度变换(imadjust函数使用)

【数字图像处理matlab系列】空间域处理之亮度变换(imadjust函数使用) 在空间域中&#xff0c;图像处理就是直接对图像的像素进行操作 imadjust 是 MATLAB 中用于调整图像强度值或颜色图的函数。它可以改变图像的对比度&#xff0c;使得图像更清晰或更易于分析。以下是 imadju…

从零到部署指南:Ubuntu上安装Boost和Crow库

1.安装boost 在安装Crow之前&#xff0c;需要确保您的系统中已经安装了Boost库。以下是Boost库安装步骤&#xff1a; 首先&#xff0c;从Boost官方网站或通过特定的链接下载Boost的源码&#xff0c;boost源码具体可参看这个链接&#xff1a; https://blog.csdn.net/duan199201…

LangChain-13 Memory 通过 ConversationBufferMemory 记录会话的上下文 并在对话中自动检索

问题背景 平常我们的任务都是一次性会话&#xff0c;大模型是不会记录你的上下文的。如果我们要进行持续会话&#xff0c;或者希望大模型有记忆的话&#xff0c;我们需要对上下文进行管理。但这个过程是比较复杂的&#xff0c;LangChain 提供了一系列的工具来帮助我们简化过程…

golang web 开发 —— gin 框架 (gorm 链接 mysql)

目录 1. 介绍 2. 环境 3. gin 3.1 gin提供的常见路由 3.2 gin的分组 main.go router.go 代码结构 3.3 gin 提供的Json方法 main.go route.go common.go user.go order.go 3.4 gin框架下如何获取传递来的参数 第一种是GET请求后面直接 /拼上传递的参数 第二种是…