百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

一文读懂:单片机数字逻辑门电路和定时器

yund56 2025-03-28 16:27 6 浏览

基本数字逻辑门电路

不管是数字电路,还是C语言,我们都会经常遇到逻辑运算和逻辑电路。

首先,在“逻辑”这个概念范畴内,存在真和假这两个逻辑值,而将其对应到数字电路或C语言中,就变成了“非0值”和“0值”这两个值,即逻辑上的“假”就是数字电路或C语言中的“0”这个值,而逻辑“真”就是其它一切“非0值”。

然后,来具体分析一下几个主要的逻辑运算符。假定有2个字节变量:A和B,二者进行某种逻辑运算后的结果为F。以下逻辑运算符都是按照变量整体值进行运算的,通常就叫做逻辑运算符:

  • &&:逻辑与,F = A && B,当A、B的值都为真(即非0值,下同)时,其运算结果F为真(具体数值为1,下同);当A、B值任意一个为假(即0,下同)时,结果F为假(具体数值为0,下同)。
  • ||:逻辑或,F = A || B,当A、B值任意一个为真时,其运算结果F为真;当A、B值都为假时,结果F为假。
  • ! :逻辑非,F = !A,当A值为假时,其运算结果F为真;当A值为真时,结果F为假。
  • 以下逻辑运算符都是按照变量内的每一个位来进行运算的,通常就叫做位运算符:

    • & :按位与,F = A & B,将A、B两个字节中的每一位都进行与运算,再将得到的每一位结果组合为总结果F,例如A = 0b11001100,B = 0b11110000,则结果F就等于0b11000000。
    • | :按位或,F = A | B,将A、B两个字节中的每一位都进行或运算,再将得到的每一位结果组合为总结果F,例如A = 0b11001100,B = 0b11110000,则结果F就等于0b11111100。
    • ~ :按位取反,F = ~A,将A字节内的每一位进行非运算(就是取反),再将得到的每一位结果组合为总结果F,例如,A = 0b11001100,则结果F就等于0b00110011;这个运算符我们在前面的流水灯实验里已经用过了,现在再回头看一眼,是不是清楚多了。
    • ^ :按位异或,F = A ^ B,异或的意思是,如果运算双方的值不同(即相异)则结果为真,双方值相同则结果为假。在C语言里没有按变量整体值进行的异或运算,所以我们仅以按位异或为例,F = A ^ B,A = 0b11001100,B = 0b11110000,则结果F就等于0b00111100。

    要看资料或芯片手册的时候,会经常遇到一些电路符号,表1就是数字电路中的常用符号,知道这些符号有利于我们理解器件的逻辑结构,尤其重点认识以下表中的“国外流行图形符号”。在这里我们先简单看一下,后边遇到了知道到这里查阅就可以了。

    定时器

    定时器是单片机的重点中的重点,但不是难点,大家一定要完全理解并且熟练掌握定时器的应用。

    • 时钟周期:时钟周期T是时序中最小的时间单位具体计算的方法就是1/时钟源,如果大家用的晶振是11.0592M,那么对于这个单片机系统来说,时钟周期=1/11059200秒。
    • 机器周期:我们的单片机完成一个操作的最短时间。机器周期主要针对汇编语言而言,在汇编语言下程序的每一条语句执行所使用的时间都是机器周期的整数倍,而且语句占用的时间是可以计算出来的,而C语言一条语句的时间是不可计算的。51单片机系列,在其标准架构下一个机器周期是12个时钟周期,也就是12/11059200秒。现在有不少增强型的51单片机,其速度都比较快,有的1个机器周期等于4个时钟周期,有的1个机器周期就等于1个时钟周期,也就是说大体上其速度可以达到标准51架构的3倍或12倍。

    这两个概念了解即可,下边就来重头戏,定时器和计数器。定时器和计数器是单片机内部的同一个模块,通过配置SFR(特殊功能寄存器)可以实现两种不同的功能,大多数情况下是使用定时器功能,计数器功能大家自己了解下即可。

    顾名思义,定时器就是用来进行定时的。定时器内部有一个寄存器,让它开始计数后,这个寄存器的值每经过一个机器周期就会加1一次,因此,可以把机器周期理解为定时器的计数周期。秒表每经过一秒,数字加1,而这个定时器就是每过一个机器周期的时间,也就是12/11059200秒,数字加1。

    还有一个特别注意的地方,就是秒表是加到60后,秒就自动变成0了,这种情况在单片机和计算机里称之为溢出。那定时器加到多少才会溢出呢?定时器有几种模式,假如是16位的定时器,也就是2个字节,最大值就是65535,那么加到65535后,再加1就算溢出,如果有其他位数的话,道理是一样的,对于51单片机来说,溢出后,这个值会直接变成0。从某一个初值,经过计算确定的时间后溢出,这个过程就是其定时的含义。

    定时器的寄存器描述

    标准的51里边只有定时器0和定时器1这两个定时器,现在很多单片机也有多个定时器的,在这里先讲定时器0和1。前边提到过,对于单片机的每一个功能模块,都是由他的SFR,也就是特殊功能寄存器来控制。而和定时器有关的特殊功能寄存器,有以下几个,大家不需要去记忆这些寄存器的名字和作用,你只要大概知道就行,用的时候,随时可以查手册,找到每个寄存器的名字和每个寄存器所起到的作用。

    表2 定时值存储寄存器

    • 表2中的寄存器,是存储计数器的计数值的,两个字节的用于定时器1,两个字节用于定时器0。

    表3 TCON--定时器/计数器控制寄存器的位分配(地址:88H)

    表3中有TF1、TR1、TF0、TR0这4位需要理解清楚。两位定时器1的,两位定时器0的,只解释定时器1的,定时器0的同理。先看TR1,当我们程序中写TR1 = 1以后,定时器值就会每经过一个机器周期加1,当程序中写TR1 = 0以后,定时器值就会保持不变化。TF1,这个是一个标志位,它的作用是告诉定时器溢出了。
    比如定时器设置成16位的定时器,那么每经过一个机器周期,TL1加1一次,当TL1加到255后,再加1,TL1变成0,TH1会加1一次,如此一直加到TH1和TL1都是255(即TH1和TL1组成的16位整型数为65535)以后,再加1一次,那么就会溢出,TH1和TL1同时都变为0,只要一溢出,TF1马上自动变成1,告诉定时器溢出了,仅仅是提供给一个信号,让知道定时器溢出了,它不会对定时器是否继续运行产生任何影响。

    表4 TCON--定时器/计数器控制寄存器的位描述

    • 注意在表4中的描述中,只要写到硬件置1或者清0的,就是指一旦符合条件,单片机自动完成的动作,只要写软件置1或者清0的,是指用程序去完成这个动作。

    表5 TMOD--定时器方式控制寄存器的位分配(地址:89H)

    TCON是“可位寻址”,TMOD是“不可位寻址”。这个地方的意思就是比如TCON有一位TR1,我们可以在程序中直接进行TR1 = 1,这样操作。但是(T1)M1 = 1,这样的操作就是错误的,操作就必须一次操作一个字节,就是必须一次性对TMOD所有位操作,不能对其中某一位单独进行操作。

    表7 TMOD--定时器方式控制寄存器M1/M0工作模式

    以上这4种模式的配置,其中模式0是为了兼容老的8048单片机而设的,现在的51几乎不会用到这种模式,而模式3根据应用经验,他的功能模式2完全可以取代,所以基本上也是不用,重点就学习模式1和模式2。

    • 模式1:就是THn和TLn组成了一个16位的定时器,取值范围是0到65535,溢出后,只要不对THn和TLn重新赋值,则从0开始计数。
    • 模式2:的功能是自动装载,就是TLn溢出后,TFn就直接置1了,并且THn的值直接赋给TLn,然后TLn从新赋值的这个数字开始计数,这个功能可以用来产生串口的通信波特率。

    理解定时器原理

    为了加深大家理解这个定时器原理,来看一下模式1的电路示意图1。

    图1 定时器/计数器模式1示意图

    分析一下这个示意图,OSC框表示时钟频率,因为1个机器周期等于12个时钟周期,所以那个d就等于12。下边GATA右边的那个门是一个非门电路,再右侧是一个或门,再往右是一个与门电路。

    图上可以看出来,下边部分电路是控制了上边部分,那我们先来看下边是如何控制的,我们以定时器0为例。

    • TR0和下边或门电路的结果要进行与门运算,TR0如果是0的话,与运算完了肯定是0,所以确定如果要让定时器工作,TR0 = 1。
    • 与门结果要想是1,那或门出来的信号必须也得是1才行。在GATE位为1的情况下,经过一个非门变成0,或门电路结果要想是1的话,那INT0即P3.2引脚必须是1的情况下,这个时候定时器才会工作,而INT0引脚是0的情况下,定时器不工作,这就是GATE位的作用。
    • 当GATE位为0的时候,经过一个非门变成1,不管INT0引脚是什么电平,经过或门电路后则肯定是1,定时器就会工作。
    • 要想让定时器工作,就是加1,从图上看有两种方式,第一种方式是那个开关打到上边的箭头,就是C/T = 0的时候,一个机器周期TL就会加1一次,当开关打到下边的箭头,即C/T =1的时候,T0引脚即P3.4引脚来一个脉冲,TL就加1一次,这也就是计数器功能。(INT0引脚是P3.2,INT1引脚是P3.3,T0引脚是P3.4,T1引脚是P3.5。)

    定时器程序应用

    了解了定时器相关的寄存器,那么我们下面就来做一个定时器的程序,巩固一下我们学到的内容。我们这节课的程序先使用定时器0,在使用定时器的时候,需要以下几个步骤:

    1. 设置特殊功能寄存器TMOD,配置好工作模式;
    2. 设置计数寄存器TH0和TL0的初值;
    3. 设置TCON,通过打开TR0位来让定时器开始计数。
    4. 判断TCON寄存器的TF0位,监测定时器溢出情况。

    写程序之前,要先来学会计算如何用定时器定时时间。以晶振是11.0592M为例讲解,时钟周期就是1/11059200,机器周期就是12/11059200,假如要定时20ms就是0.02秒,要经过x个机器周期得到0.02秒,算一下x*12/11059200 = 0.02,得到x = 18432。

    那么现在16位的定时器溢出值是65536,可以这样,先给TH0和TL0一个初值,让他们经过18432个机器周期后刚好溢出,溢出后可以通过检测TF0位得知,就刚好是0.02秒。这个初值y = 65536 - 18432 = 47104,转成16进制就是0xB800,那么就是TH0 = 0xB8,TL0 = 0x00。

    那0.02秒已经定时出来了,细心的同学会发现,如果初值直接给一个0x0000,一直到65536溢出,定时器定时值最大也就是71ms左右,那么想定时更长时间怎么办呢?用你小学学过的逻辑,倍数关系就可以解决此问题。

    本程序实现的结果是小灯点亮持续一秒,熄灭持续一秒,也就是以0.5HZ的频率进行闪烁。那好了,我们下面就用程序来实现以下这个功能。

    #include //包含寄存器的库文件

    sbit LED = P0^0;

    sbit ADDR0 = P1^0;

    sbit ADDR1 = P1^1;

    sbit ADDR2 = P1^2;

    sbit ADDR3 = P1^3;

    sbit ENLED = P1^4;

    void main()

    {

    unsigned char counter = 0;

    ENLED = 0; ADDR0 = 0; ADDR1 = 1;

    ADDR2 = 1; ADDR3 = 1; LED = 1; //74HC138和LED灯初始化部分

    TMOD = 0x01; //设置定时器0为模式1

    TH0 = 0xB8;

    TL0 = 0x00; //定时值初值

    TR0 = 1; //打开定时器0

    while(1)

    {

    if(1 == TF0) //判断定时器0是否溢出

    {

    TF0 = 0;

    TH0 = 0xB8; //一旦溢出后,重新赋值

    TL0 = 0x00;

    counter++;

    if(50 == counter) //判断定时器0溢出是否达到50次

    {

    counter = 0; //counter清0,重新计数

    LED = !LED; //LED取反操作,0-->1,1-->0

    }

    }

    }

    }

    程序都有注释,不难理解,这里要解释一个地方,就是两次if判断,细心的同学会发现,if(1 == TF0)这句,1写前边,因为如果写if(TF0 == 1),作为新手来说,不小心丢掉一个’=’号后,写成if(TF0 = 1),这样实际上在语法上是可以通过的,用的Keil4还会出一个警告说明一下,Keil以前的版本以及一些其他软件,可能根本不会出任何错误或者警告提示,但是这样产生的Hex文件下载到单片机里边,程序就错了,大家可以改改试试看。

    相关推荐

    仍需打磨:首款Windows 10X模拟器上手

    今天,微软发布了适用于Windows10X的首款模拟器,以便于开发人员初步了解适用于双屏设备的操作系统调整。微软希望在SurfaceNeo今年年底正式发售之前,让开发人员对应用程序进行优化。因此...

    Windows10 编译OpenCV4.5源码

    在OpenCV4.5+VisualStudio2017开发环境配置中,介绍了OpenCV4.5的下载和安装,待扩展内容OpenCV源码编译,在本文中做补充。研究源码无疑是学习OpenCV的一...

    微软7年磨一剑,Windows 10X抢先上手体验

    2月22日消息,微软在去年10月正式推出了Windows10X系统,该系统除了可用于传统的电脑外,同样适用于双屏设备或者折叠屏设备,拥有更好的触控操作体验。Windows10X在操作系统底层、命令...

    Office重新设计了图标,你觉得如何?

    微软重新设计了Office的应用图标,在接下来的几个月里,这些图标将从移动端和网页端开始陆续推广至各大平台。距离Office图标的最近一次更新还是在2013年,那时鲍尔默时代的产物,那时微软还在纠结是...

    微软发布 Win10 Build 21376 内测版:重新设计默认用户界面字体

    IT之家5月7日消息今年早些时候,微软意外地确认正在为Windows10进行UI改进,并在预览版中发现了相关的非活动代码。微软今天宣布向开发渠道中的内测用户发布Windows1...

    前端开发需要了解常用7种JavaScript设计模式

    作者|Deven译者|王强策划|小智转发链接:https://mp.weixin.qq.com/s/Lw4D7bfUSw_kPoJMD6W8gg前言JavaScript中的设计模式指的是...

    「Qt入门第二篇」基础(二)编写Qt多窗口程序

    导语程序要实现的功能是:程序开始出现一个对话框,按下按钮后便能进入主窗口,如果直接关闭这个对话框,便不能进入主窗口,整个程序也将退出。当进入主窗口后,我们按下按钮,会弹出一个对话框,无论如何关闭这个对...

    在吴中 ,哪里有学网页设计的培训班?

    网页设计介绍Web2.0标准布局之网页长期签约就业班(全日制)课程收费:7680元课程周期:5-6个月(45分钟/课)使用教材:《教师自编教材》考核发证:Adobe《网页设计师》培训内容第一部份:...

    Qt快速入门(工程的创建、UI界面布局、多线程、项目)

    本文档将介绍QT工程的创建、UI界面布局,并以计数器为例了解QT中多线程的用法,最终完成一个基础的QT项目。1创建QT工程文件在安装好QT之后,能够在其安装组件中找到QtCreator,点击设置项...

    应用崩溃有救啦!Windows新更新将解决应用崩溃问题

    【CNMO新闻】对于不少上班族来说,当自己的电脑在运行某个应用程序时,突然出现应用程序崩溃问题,常常会让人十分苦恼。尤其是对于设计师或者编辑,当自己的作品未能及时保存应用崩溃全部消失的时候,简直就是痛...

    Python Qt GUI设计:窗口布局管理方法【强化】(基础篇—6)

    在PythonQtGUI设计:窗口布局管理方法【基础篇】(基础篇—5)文章中,聊到了如何使用QtDesigner进行窗口布局管理,其实在QtDesigner中可以非常方便进行窗口布局管理设计,...

    思考:如何设计游戏业务框架

    虽然现在连主机游戏都纷纷加入了网战部分,不过其身份主要充当状态同步,矛盾点集中在同步即时性上。以大量数值逻辑为主的业务功能侧重点则不同。如果说写代码就是用状态的操作给问题建模,那么编程范式和设计模式种...

    用.NET设计一个假装黑客的屏幕保护程序

    本文主要介绍屏幕保护程序的一些相关知识,以及其在安全方面的用途,同时介绍了如何使用.NET开发一款屏幕保护程序,并对核心功能做了介绍,案例代码开源:https://github.com/sangy...

    光的艺术:灯具创意设计

    本文转自|艺术与设计微信号|artdesign_org_cn“光”是文明的起源,是思维的开端,同样也是人类睁眼的开始。每个人在出生一刻,便接受了光的照耀和洗礼。远古时候,人们将光奉为神明,用火来...

    Python Qt GUI设计:将UI文件转换Python文件三种妙招(基础篇—2)

    在开始本文之前提醒各位朋友,Python记得安装PyQt5库文件,Python语言功能很强,但是Python自带的GUI开发库Tkinter功能很弱,难以开发出专业的GUI。好在Python语言的开放...