单片机原理及应用:定时器/计数器综合应用

本文是《单片机原理及应用》专栏中的最后一篇文章,笔者以编译器的安装配置——51单片机简介——LED和数码管外设——开关和按键控制功能切换——外部中断系统——定时器与计数器为知识大纲,介绍了C语言编程控制51单片机的入门教程。作为收尾,我们将一同学习三个定时器/计数器的实际应用,不同于之间灯光和按键的组合,在这三个应用中都加入了其他外设,更复杂也更有创意,希望大家对单片机的学习也能兴致盎然、不断进取。

定时器控制P1.0引脚产生1ms方波

首先选用系统时钟为12MHz的单片机, 要在P1.0上产生周期为2ms的方波,定时器应产生1ms的定时中断,定时时间到则在中断服务程序中对P1.0求反。在本案例我们使用定时器T0,方式1定时中断,GATE不起作用。此外对中断标志位采用查询法,查询法不经过中断程序,是最简单的I/O方式,数据在CPU和外设之间的传送完全靠计算机程序控制,外设和CPU之间是串行工作,CPU效率低。由于查询法效率低于中断函数,已经被逐渐淘汰,笔者此处仅作为知识补充。

#include <reg51.h>	  	
sbit P1_0=P1^0;			
void main(void)			
{
	TMOD=0x01;		 //设置T0为定时器工作方式1
	TR0=1;			 //允许T0中断
	while(1)		
	{
	TH0=0xfc;		 //赋初值,计数1000即溢出:X=65536-1000
	TL0=0x18;
	do{}while(!TF0); //使用查询法,TF0为0原地循环,为1则T0溢出,往下执行
	P1_0=!P1_0;		 //P1.0状态求反,高低电平转换
	TF0=0;			 //定时器T0溢出标志位TF0清零
	}
}

仿真如图所示,为了确认输出波形,在proteus中添加了虚拟示波器,添加方式是点击左侧菜单栏虚拟仪器模式,在弹出的窗口中选择OSCILLIOSCOPE即可。

另外请大家注意,左侧按键属于复位电路,对方波输出无影响。启动仿真后即可看到示波器图像,示波器右侧还有各类参数,大家可以自行调整。

 定时器控制发出1KHz音频

第二个应用是用定时器T1的中断控制P1.7引脚输出频率为1kHz方波音频信号,驱动蜂鸣器发声。单片机系统时钟为12MHz,音频信号周期1ms,因此T1的定时中断时间为0.5 ms,进入中断服务程序后,对P1.7求反。原理与应用一大致相同,区别在代码构架中采用了中断法,且在while循环中多次更改定时器初值。这几个应用或多或少都采用了与众不同的设计思路,更贴合实际使用场景。

#include<reg51.h>  			
sbit sound=P1^7;  			    //将蜂鸣器连接在P1.7引脚上
#define f1(a) (65536-a)/256		//宏定义输入计数值即按表达式输出初值
#define f2(a) (65536-a)%256    	
unsigned int i=500; 
unsigned int j=0; 
void main(void)
{
	 	EA=1;                  	//开启总中断允许.
  		ET1=1;                	//允许定时器T1中断 
		
   		TMOD=0x10; 		        //T设置定时器1工作方式1 
		TH1=f1(i);      		//初始化计数值i得到初值,此时i为500
   		TL1=f2(i);      	

   		TR1=1;                 	//启动定时器1
   		while(1)  
	{   /*i=500; 				//可以改变频率达到不同的声音效果
      	while(j<2000);
      	j=0;
      	i=1000; 
      	while(j<2000);
      	j=0;
		i=3000; 
      	while(j<2000);
      	j=0;*/					//返回第一种频率
    }
 }

void T1_int(void) interrupt 3 using 0	//定时器T1中断服务函数
{
    	TH1=f1(i);   		//重新赋初值.
    	TL1=f2(i);   		
	   	sound=~sound; 	    //对P1.7输出求反,形成方波
		j++;				//用于记录中断次数,也就是记录时间
}

仿真如下,为了更直观地看到频率的变化,在蜂鸣器旁并联了一个示波器,虽然会降低幅值,但是不影响频率。

定时器控制蜂鸣器发出1KHz音频

 蜂鸣器声音较大,大家在观看视频演示时需要注意调节音量。

定时器测量INT1引脚正脉冲宽度

第三个应用是计数器测量INT1引脚正脉冲宽度,利用门控位GATE1可使T1启动计数受INT1控制:当GATE1=1,TR1=1时,只有INT1引脚输入高电平时,T1才被允许计数。利用该功能,可测量引脚正脉冲宽度,并在6位数码管上以机器周期数显示,能通过旋转信号源旋钮调整频率。

在中断处理上再次使用了查询法,另外需要注意INT1作为外部中断1的引脚,并未像之前我们介绍的那样设置TCON用于外部中断允许。作为最后一个应用,可能有些难以理解,大家了解相关原理内容就好。

#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit P3_3=P3^3;			//读取INT1引脚电平
uchar count_high; 		//定义计数变量,用来读取TH0
uchar count_low;		//定义计数变量,用来读取TL0
uint num;
uchar shiwan, wan, qian, bai, shi, ge;	  //定义各数码管显示数位
uchar flag;				//控制刷新频率
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  //数组记录共阴极数码管段码

void delay(uint z)			//自变量延时函数
{
	uint x,y;
	for(x=z;x>0;x--)
	for(y=110;y>0;y--);
}
void display(uint a,uint b,uint c,uint d,uint e,uint f)
                                                                 
{
	P2=0xfe; 	P0=table[f];	delay(2);		  //数码管段选,位选,消影
	P2=0xfd;	P0=table[e];	delay(2);		  //六个数位对应留个双管
	P2=0xfb;	P0=table[d];	delay(2);
	P2=0xf7;	P0=table[c];	delay(2);
	P2=0xef;	P0=table[b];	delay(2);
	P2=0xdf;	P0=table[a];	delay(2);
}
void read_count() 			//读取定时寄存器的内容
{
	do
 	{
 		count_high=TH1;		 //读取高字节
 		count_low=TL1;		 //读取低字节
 	}while (count_high!=TH1);//读取完成后继续往下执行	
	num=count_high*256+count_low; //将16位数据恢复为十进制数字
                             
}
void main( )
{
	while(1)
	{
		flag=0;
 		TMOD=0x90;		//设置定时器T1工作方式1,门控位为1,当INT1为高电平时定时器才开始工作
		TH1=0;			//计数初值为零
		TL1=0;
		while(P3_3==1); 	//等待INT1变为低电平
		TR1=1;		        //如果INT1为低电平,启动定时器器T1,此时未真正开始计数
		while(P3_3==0); 	//等待INT1变为高电平,变高后T1真正开始计数
		while(P3_3==1); 	//等待INT1变为低电平,变低后T1停止计数
		TR1=0;
		read_count(); 		//调用函数,读取定时寄存器内容的函数
		shiwan=num/100000;	//数据分割,每一位数码管显示对应数位
		wan=num%100000/10000;
		qian=num%10000/1000;
		bai=num%1000/100;
		shi=num%100/10;
		ge=num%10;
		while(flag!=100)	//运行100次显示数值后再读取下一次数值 			
			{
			flag++;
			display(ge,shi,bai,qian,wan,shiwan); //调用display函数,传入相应参数
			}
    }
}

仿真如下,为避免接线混乱,采用了之前介绍的总线接法;P0端口使用了上拉电阻,此时端口为准双向口,不存在高阻抗的悬浮状态;和示波器一样,信号发生器也在虚拟仪器界面,选择SIGNAL GENERATOR即可。

 

大家可以更改信号发生器的参数,包括频率、电压和波形,观察数码管示数的变化,详细的操作教程可以参考51单片机数字频率计开发

定时器测量INT1引脚正脉冲宽度


到此为止,这个专栏就算圆满落幕了,这部分单片机课程笔者也是学习了一月有余,对于非电子专业的同学来说这些知识足够了。以后如果有进一步的机会,或许会重启这个专栏。总之感谢陪伴我一同学习的每一个人,祝愿大家在新的一年里都能百尺竿头更进一步,谢谢大家,我们下个专栏再见。

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

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

相关文章

SQL性能分析-整理

昨日对MySQL的索引整理了一份小文档&#xff0c;对结构/分类/语法等做了一个小总结&#xff0c;具体文章可点击&#xff1a;MySQL-索引回顾&#xff0c;索引知识固然很重要&#xff0c;但引入运用到实际工作中更重要。 参考之前的文章&#xff1a;SQL优化总结以及参考百度/CSDN…

java方法的定义和使用

方法 今日目标&#xff1a; 能够知道方法的好处 能够根据两个明确分析方法的参数和返回值 能够编写方法完成授课案例&#xff0c;并在主方法中完成方法的调用 能够知道方法重载及其特点 1&#xff1a;方法的定义和使用 1.1 方法概述 方法(method)&#xff1a;就是完成特…

C++进阶--AVL树

AVL树 一、AVL树的概念二、AVL树节点的定义三、AVL树的插入四、AVL树的旋转4.1 左单旋4.2 右单旋4.3 左右双旋4.4 右左双旋 五、AVL树的验证六、AVL树的删除七、AVL树的性能 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退…

第8章-第6节-Java中字符流的缓冲流

1、在说正题之前&#xff0c;先说一个小细节&#xff0c;不管是字节流还是字符流都要注意这个细节&#xff0c;具体看这篇博文&#xff1a;关于Java的IO流里面的方法read()的小细节 2、字符流的缓冲流&#xff1a; 1&#xff09;、BufferedWriter 方法名说明void newLine()写…

MySQL题目示例

文章目录 1.题目示例 1.题目示例 09&#xff09;查询学过「张三」老师授课的同学的信息 SELECT s.*, c.cname, t.tname, sc.score FROM t_mysql_teacher t, t_mysql_course c, t_mysql_student s, t_mysql_score sc WHERE t.tid c.tid AND c.cid sc.cid AND sc.sid s.sid …

网页的介绍

目录 什么是网页&#xff1a; 网页的组成&#xff1a; 什么是HTML&#xff1a; 网页的总结&#xff1a; 浏览器&#xff1a; web标准&#xff1a; 为什么需要Web标准&#xff1a; web标准的构成&#xff1a; 什么是网页&#xff1a; 1.网站是指在因特网上根据一定的规…

FreeRtos Queue (一)

本篇主要讲队列的数据结构和初始化 一、队列的数据结构 二、队列初始化完是什么样子的 队列初始化的函数调用关系&#xff1a;xQueueGenericCreate->prvInitialiseNewQueue->xQueueGenericReset 所以&#xff0c;最终初始化完的队列是这样的 假设申请了4个消息体&…

Linux QT以太网配置及相关知识

Linux QT以太网配置及相关知识 平台和内容概述安装Qt Creator设计用户界面编辑源代码自定义LineEdit创建槽函数以太网逻辑功能实现静态配置ui逻辑:功能概述代码实现DNS退出程序输入框中的ip规范保存数据和读取数据构建文件编译运行平台注意点开机自动配置以太网总结平台和内容…

小鼠的滚动疲劳仪-转棒实验|ZL-200C小鼠转棒疲劳仪

转棒实验|ZL-200C小鼠转棒疲劳仪用于检测啮齿类动物的运动功能。通过测量动物在滚筒上行走的持续时间&#xff0c;来评定**神经系统*病或损坏以及药物对运动协调功能和疲劳的影响。 疲劳实验中&#xff0c;让小鼠在不停转动的棒上运动&#xff0c;肌肉会很快进入疲劳状态&#…

odoo17 | Qweb模板简介

前言 到目前为止&#xff0c;我们的房地产模块的界面设计还相当有限。构建列表视图很简单&#xff0c;因为只需要字段列表。表单视图也是如此&#xff1a;尽管使用了几个标签&#xff0c;如 <group>标签或 <page>标签 &#xff0c;但在设计方面几乎没什么可做的。…

【模型评估 05】Holdout、交叉检验、自助法

机器学习中&#xff0c;我们通常把样本分为训练集和测试集&#xff0c;训练集用于训练模型&#xff0c;测试集用于评估模型。在样本划分和模型验证的过程中&#xff0c;存在着不同的抽样方法和验证方法。 1. 在模型评估过程中&#xff0c;有哪些主要的验证方法&#xff0c;它们…

STM32单片机实现简单的声音和光的采样

原理分析&#xff0c;找到对应管脚。 如我的单片机相关对应的管脚是PB0和PB1&#xff0c;使用ADC&#xff08;模数转换器&#xff09;。 配置使能 ADC时钟的配置不能太高&#xff0c;这里设置为12&#xff0c;配置完成之后CTRLs生成代码 添加实现代码 在adc.c文件中添加下面的…

水果音乐编曲软件 FL Studio v21.2.2.3914 中文免费版(附中文设置教程)

FL studio21中文别名水果编曲软件&#xff0c;是一款全能的音乐制作软件&#xff0c;包括编曲、录音、剪辑和混音等诸多功能&#xff0c;让你的电脑编程一个全能的录音室&#xff0c;它为您提供了一个集成的开发环境&#xff0c;使用起来非常简单有效&#xff0c;您的工作会变得…

OpenCV-23中值滤波

一、概念 中值滤波原理比较简单&#xff0c;假设有一个数组[1556789],取其中的中间值&#xff08;即中位数&#xff09;作为卷积后的结果即可&#xff0c;中值滤波对胡椒噪音&#xff08;也叫椒盐噪音&#xff09;效果明显。 对下面带胡椒噪声的图片进行处理。 注意点&#x…

RSIC-V“一芯”学习笔记(一)——概述

考研的文章和资料之后想写的时候再写怕趴 文章目录 一、阶段设计二、环境、开发语言和工具三、最重要的两个观念四、处理器芯片设计五、处理器芯片设计包含很多软件问题六、处理器芯片的评价指标七、复杂系统的构建和维护八、专业世界观九&#xff0c;提问的艺术(提问模板)十、…

PHP信息分类网源码带手机端和文档

PHP信息分类网源码带手机端和文档 安装简易说明&#xff1a; 上传 → 安装 → 进入后台 → 恢复数据 → 修改cookie记录值&#xff08;第3点有说明&#xff09; 1.上传程序到网站根目录,访问http://域名/install/index.php 进行安装,不要直接打开网址&#xff0c;先直接安装&am…

MySQL启动

启动与停止 法一 winR 然后输入services.msc 会进入Windows系统 法二 如果在安装过程中勾选&#xff0c;则mysql默认是开机自动启动的 启动&#xff1a;net start mysql80 停止&#xff1a;net stop mysql80 cmd以管理员身份运行 客户端连接 方式一&#xff1a;MySQL提…

博途PLC和HMI协同设计工作(PLC设备数据代理)

我们在做S7-1200/1500PLC项目时,往往由于项目比较大,工作量比较多。此时我们的PLC程序和HMI程序由不同的工程师分别完成。这时候往往我们的PLC工程和HMI工程都不在同一个工程下,我们的HMI工程师如何和我们的PLC工程协同工作完成数据通信和工程设计呢,这里我们介绍PLC的&quo…

【面试突击】生产部署面试实战

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

Markdown编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…