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测试结果没问题;
    在这里插入图片描述

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

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

相关文章

Golang 开发实战day08 - Multiple Return values

Golang 教程08 - Multiple Return values 1. Multiple return values 1.1 如何理解多个返回值&#xff1f; Go语言中的多返回值&#xff0c;就像你听了一首歌曲yellow&#xff0c;可以从歌曲里反馈出忧郁和害羞&#xff01;Goland的多个返回值就类似于如此&#xff0c;设定一…

C++版本GDAL3.5无法找到proj.db文件

问题&#xff1a;C版本的GDAL无法找到proj.db文件 自己编译过的gdal3.5版本在自己电脑上使用坐标转换没有问题&#xff0c;而将库文件和头文件迁移到别的笔记本上转换坐标出实现问题&#xff1a; ERROR 1: PROJ: proj_create_from_database: Cannot find proj.db ERROR 1: PRO…

C语言第四十一弹---猜数字游戏

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 猜数字游戏 1、随机数生成 1.1、rand 1.2、srand 1.3、time 1.4、设置随机数的范围 2、猜数字游戏的分析和设计 2.1、猜数字游戏功能说明 2.2、猜数字游戏…

新人硬件工程师往哪个方向更有前途?

如果是比较沉默寡言&#xff0c;不擅长交际的&#xff0c;那么可以走技术路线。我这里有一套自动化入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习自动化&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我…

让chatGPT控制物理设备

作为自动控制行业的工程师&#xff0c;我们也许最关心的是如何使chatGPT 控制物理设备。我发现许多人仍然停留在传统程序设计的思维阶段&#xff0c;比如让大模型编写一段PLC 代码&#xff0c;或者是生成一些信息模型。 其实大模型具备判断与思考的能力&#xff0c;AI …

数字乡村:科技引领新时代农村发展

随着信息技术的迅猛发展和数字化浪潮的推进&#xff0c;数字乡村作为新时代农村发展的重要战略&#xff0c;正日益成为引领农村现代化的强大引擎。数字乡村不仅代表着农村信息化建设的新高度&#xff0c;更是农村经济社会发展的重要支撑。通过数字技术的深入应用&#xff0c;农…

【C#】读取指定XML节点

&#x1f4f0;XML文件 <?xml version"1.0" encoding"utf-8"?> <configuration><userSettings><Internal.Settings type"Desktop"><setting name"StatsDisplayCount" serializeAs"String">…

【每周精选资讯 | 第 4 期】2024-04-01 ~ 2024-04-08

文章目录 前言阿里巴巴&#xff1a;推出Qwen1.5-32B 模型文心一言&#xff1a;定制自己的 AI 声音动画线条图自动填色SWE-agent&#xff1a;AI程序员OpenAI&#xff1a;收集高质量训练数据Stability AI 发布 Stable Audio 2.0OpenAI&#xff1a;开放GPT3.5&#xff0c;无需注册…

百度富文本编辑器配置(vue3)

今天分享一下我做的项目里面的一个百度富文本的配置问题&#xff0c;安装配置流程以及如何解决的 1.首先是安装组件 # vue-ueditor-wrap v3 仅支持 Vue 3 npm i vue-ueditor-wrap3.x -S # or yarn add vue-ueditor-wrap3.x 2. 下载 UEditor UEditor 并不支持通过 npm 的方式…

Matlab进阶绘图第49期—气泡堆叠图

气泡堆叠图是堆叠图与气泡图的组合—在堆叠图每根柱子上方添加大小不同的气泡&#xff0c;用于表示另外一个数据变量&#xff08;如每根柱子各组分的平均值&#xff09;的大小。 本文利用自己制作的BarBubble工具&#xff0c;进行气泡堆叠图的绘制&#xff0c;先来看一下成品效…

c语言:操作符

操作符 一.算术操作符: + - * % / 1.除了%操作符之外,其他的几个操作符可以作用与整数和浮点数,如:5%2.0//error. 2.对于操作符,如果两个操作数都为整数,执行整数除法而只要有浮点数执行的就是浮点数除法。 3.%操作符的两个操作数必须为整数。 二.移位操作符:<&…

如何在 Windows上安装 Python

系列文章目录 作者&#xff1a;i阿极 作者简介&#xff1a;数据分析领域优质创作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&#x1f4c1;评论&#x1f4d2;…

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

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

C语言数组:数据的集合艺术(续)

前言 在上一篇文章中&#xff0c;我们深入探讨了C语言数组的基本概念、操作以及多维数组的应用。今天&#xff0c;我们将继续探索数组的更多高级特性&#xff0c;包括动态内存分配、指针与数组的关系以及数组在实际编程中的应用案例。 一、动态内存分配与数组 在C语言中&…

2024/4/2—力扣—不用加号的加法

代码实现&#xff1a; 思路&#xff1a;位运算&#xff0c;利用了异或和与的特性&#xff0c;异或操作与加操作的区别在于异或操作在二进制状态下两个数同1不进位&#xff0c;只是置为0&#xff0c;其他均相同&#xff0c;那么使用与运算计算进位值&#xff0c;补齐异或操作的缺…

算法 - 符号表-上

&#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 算法 - 符号表前言初级实现1. 链表实现无序符号表2. 二分查找实现有序符号表 二叉查找树1. get()2. put()3. 分析4. floor()5. rank()6. min()7. deleteMin()8. delete()9. keys()10. 分析 算法 - 符号表 前言 符号表&am…

Latex表格制作详细教程(table, tabular, multirow, multicolumn)

一、简单表格制作 Latex表格需要用到 table 和 tabular 环境。其中 table 环境里写表格的标题(caption&#xff09;、表格的位置之类的。 tabular 环境则是绘制表格的内容。一个简单的表格绘制代码如下所示&#xff1a; \documentclass{article}\begin{document}\begin{table…

怎么保证缓存与数据库的最终一致性?

目录 零.读数据的标准操作 一.Cache aside Patten--旁路模式 二.Read/Write Through Pattern--读写穿透 三.Write Back Pattern--写回 四.运用canal监听mysql的binlog实现缓存同步 零.读数据的标准操作 这里想说的是不管哪种模式读操作都是一样的&#xff0c;这是一种统一…

2 万字 42 道Java经典面试题总结(2024修订版)- Java集合篇

目录 1、Java中常用的集合有哪些&#xff1f;2、Collection 和 Collections 有什么区别&#xff1f;3、为什么集合类没有实现 Cloneable 和 Serializable 接口&#xff1f;4、数组和集合有什么本质区别&#xff1f;5、数组和集合如何选择&#xff1f;6、list与Set区别7、HashMa…

力扣刷题 102.二叉树的层序遍历

目录 题干 解题思路 总结与反思 题干 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9…