历史上的今天
返回首页

历史上的今天

今天是:2024年10月21日(星期一)

正在发生

2021年10月21日 | 【自学51单片机】5 --- 定时器、数码管、逻辑运算、

2021-10-21 来源:eefocus

定时器介绍、数码管静态显示、逻辑运算符和逻辑电路符号


1、逻辑运算和逻辑电路

引入逻辑概念:在生活中,逻辑存在 ‘真’ 和 ‘假’ 两个逻辑值,而逻辑对应到C语言和数字电路中, ‘真’ 对应C语言或数字电路中的一切 ‘非0值’,而 ’假‘ 对应为 ’0值‘。


1.1 C语言逻辑运算符

假定两个字节变量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 = 0b00111100,B = 0b11011101,则结果 F 就等于0b00011100。

| 按位或: F = A | B,例如 A = 0b00111100,B = 0b11011101, F 就等于 0b11111101。

~ 按位取反: F = ~A,就是将 A 字节内的每一位进行非运算(就是取反),例如 A = 0b00111100, F 就等于 0b11000011;

^按位异或:异或的意思是,如果运算双方的值不同(即相异)则结果为真,双方值相

同则结果为假。F = A ^ B,A = 0b00111100,B = 0b11011101 , 结果 F 就等于 0b11100001。


1.2 逻辑电路符号

以下图为数字电路常用电路符号,重点认识国外流行符号,通过查阅来记住即可。

2、定时器学习(重点非难点)

2.1 时钟周期和机器周期的介绍

时钟周期:是时序中最小的时间单位,计算方法:时钟周期 = 1 / 时钟源频率。(注:1. 单位为秒  2.时间源频率就是单片机的晶振,博主STC89C52RC的晶振电路晶振为:11.0592M)


机器周期:单片机完成一个操作的最短时间。标准架构下的51单片机的一个机器周期等于12个时钟周期(12 / 时钟周期 S),有的增强型51单片机一个机器周期等于4个时钟周期或等于1个时钟周期,以下讲解标准框架下的51单片机。


2.2 定时器的介绍

单片机中定时器和计数器是内部的同一模块,计数器功能读者自己去了解,我们来介绍定时器功能。


定时器:用于定时,标准51单片机有T0和T1两个定时器。定时器内部有一个寄存器,该寄存器的值每通过一个机器周期自动加1,可以把机器周期理解为定时器的计数周期,如同钟表,每经过一秒,数字自动加1,而寄存器每通过12/11059200秒,数值自动加1。当钟表加到60秒后,秒自动跳为0,这种情况在单片机和计算机中叫溢出,定时器不同工作模式,溢出的情况也不同,假如16位定时器,加到65535后,再加1就溢出,溢出后值直接变为0。


2.2.1 定时器寄存器介绍

定时器这模块有6个寄存器,下面来一一介绍,读者用到这些寄存器查手册即可。


定时值存储寄存器

表5-1中有四个寄存器,用于存储定时器的计数值,其中TH0和TL0用于定时器0,TH1和TL1用于定时器1。


TCON–定时器控制寄存器

(注:可位寻址指的是可以对该寄存器的每个位单独操作,比如该寄存器的一位TR1,可以直接用程序进行TR1 = 1操作)

(注:只要写到硬件置 1 或者清 0 的,就是指一旦符合条件,单片机将自动完成的动作,只要写软件置 1 或者清 0 的,是指我们必须用程序去完成这个动作)


表 5-2 是定时器控制寄存器 TCON 的位分配,表 5-3 是则是对每一位的具体含义的描述。TCON寄存器中TF0和TR0用于定时器0,TF1和TR1用于定时器1。我们以定时器1为例讲解,定时器0同理,TR1等于1,定时器值每过一个机器周期加1,若等于0,则停止加1。 TF1的作用是告诉们定时器溢出了,比如定时器16位模式下,每经过一个机器周期会使TL1加1,加到255后,再加1后,TL1变为0,而TH1加1,如此循环,待TL1和TH1为255后,再加1就会溢出,此时TL1和TH1变为0,TF1自动变成1,提供给读者一个溢出信号。


TMOD–定时器模式寄存器

(注:不可位寻址指的是不可以对该寄存器的每个位单独操作,对 TMOD 里的位比如M1 (T1)= 1 这样的操作就是错误的。我们要操作就必须一次操作这整个字节,也就是必须一次性对 TMOD 所有位操作)


上表为TMOD的位分配。

表5-5为TMOD的位描述,GATE位读者自行了解,C/T位为选择定时器或计数器功能,C/T=0为选择定时器功能,C/T=1为选择计数器功能。

表5-6为TMOD4中模式介绍,模式0和3现在很少应用,读者自行了解,下面介绍模式1和2。


模式1: 是 THn 和 TLn 组成了一个 16 位的定时器,计数范围是 0~65535,溢出后,只要不对 THn 和 TLn 重新赋值,则从 0 开始计数。


模式2: 是 8 位自动重装载模式,只有 TLn做加 1 计数,计数范围 0~255,THn 的值并不发生变化,而是保持原值,TLn 溢出后,TFn就直接置 1 了,并且 THn 原先的值直接赋给 TLn,然后 TLn 从新赋值的这个数字开始计数。 比如该模式下,TH1 = 0x66,TL1=0x00,每经过一个机器周期TL1加1,当TL1=0xFF时,再加1后TF1就会变为1,并且TL1会被赋值为TH1的值后计数,即TL1从0x66开始计数,而TH1的值保持不变。


2.2.2 定时器模式工作电路逻辑图

定时器模式一工作电路逻辑图

讲解:以定时器1为讲解,定时器0同理,OSC为时钟源频率,d为单片机机器周期对于时钟周期的倍数。


当C/T = 0打开定时器功能,C/T = 1打开计数器功能。

要达到控制效果,TR1和或门构成的电路要进行与运算,与运算两个为真才为真,所以TR1要为1,并且或门构成的电路进行或运算后结果要为1,

或门输出为1的方式有两种9:(1).当INT1引脚为1时,不过GATA位为什么,或运算后结果都为1,定时器1模式1开启。(2). 当GATA为0时,经过非运算后为1,不管INT1为什么,进行或运算结果都为1,定时器1模式1开启。


定时器模式二工作电路逻辑图

讲解: 模式二的电路逻辑图和模式一的相似,就不进行详细讲解,此模式下定时器作为可自动重装载的8位计数器(TLn), TLn的溢出,不仅置为TFn,而且将THn的内容重新装载到TLn,THn内容由软件预置,重装时THn内容不变。


2.3 定时器的应用

2.3.1 使用定时器的步骤

下面以使用定时器0为例,定时器1同理。


设置定时器模式寄存器TMOD,选择好定时器工作模式。

设置计数寄存器TH0和TL0的初值。

设置定时器控制寄存器TCON,使TR0 置1让定时器开始计数。

通过判断TCON中的TF0位,监测定时器的溢出情况。


2.3.2计算如何用定时器定时时间

我们知道标准51单片机机器周期为12个时钟周期,以STC89C52RC单片机为例,它的机器周期为:12/11059200秒,如果定时0.02s,设要经过x个机器周期,那么 x* (12/11059200) =0.02, 通过计算x等于18432,因16位定时器溢出值为65536,那么先让TH0和TL0等于初值y,经过18432个机器周期后溢出,这样就实现了定时0.02s,y值通过65536- 18432计算出为47104,转换为十六进制就是0xB800(链接:进制转换方法),即TH0 = 0xB8,TL0 = 0x00。


2.3.3通过定时器控制小灯的闪烁

控制小灯进行0.5HZ频率闪烁的程序

#include


sbit LED = P0^7;

sbit ADDR3 = P1^3;

sbit ADDR2 = P1^2;

sbit ADDR1 = P1^1;

sbit ADDR0 = P1^0;

sbit ENLED = P1^4;


void main()

{

unsigned char cnt = 0;//定义一个计数变量,记录T1的溢出次数

ENLED = 0;

ADDR3 = 1;

ADDR2 = 1;

ADDR1 = 1;

ADDR0 = 0;

TMOD = 0x10;//配置T1的工作模式

TH1 = 0xB8;

TL1 = 0x00;//为T1赋初值

TR1 = 1;//启动T1


while(1)

{

if(TF1 == 1)//判断T1是否溢出

{

cnt++;// 计数值自加1

TF1 = 0;//T1溢出后,清零中断标志

TH1 = 0xB8;//并在重新赋初值

TL1 = 0x00;

if(cnt >= 50)//判断是否溢出50次

{

LED = ~LED;//LED取反,1--->0、0--->1

cnt = 0;//达到50次后计数值清零

}

}

}


}


通过定时器控制左右流水灯程序

#include


sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;


void main()

{

unsigned char cnt = 0;//定义计数变量,记录溢出次数

unsigned char dir = 0;//定义移位方向变量,用于改变流水灯流向

unsigned char shift = 0x01;//定义循环移位变量shift,并赋初值0x01

ENLED = 0;//使能U3

ADDR3 = 1;

ADDR2 = 1;

ADDR1 = 1;

ADDR0 = 0;

TMOD = 0x10;//设置T1为模式一

TH1 = 0xB8;//为T1赋初值

TL1 = 0x00;

TR1 = 1;//开启T1


while(1)//主循环,程序无限执行该循环

{

P0 = ~shift;//P0等于循环移位变量shift取反,控制8个LED小灯

while(TF1 == 0);//当TF1=0时循环执行空语句,直到定时器溢出

TF1 = 0;//TF1清零

TH1 = 0xB8;//重新为T1赋初值

TL1 = 0x00;

cnt++;//每溢出一次,cnt加一

if(cnt >= 10)//判断是否溢出10次

{

cnt = 0;//溢出次数置零

if(dir == 0)//移位方向变量为0时,左移

{

shift = shift << 1;//循环移位变量shift左移一位

if(shift == 0x80) //左移到最左端,改变移位方向变量

{

dir = 1;

}

}else //移位方向变量不为零时,右移

{

shift = shift >> 1;//循环移位变量右移一位

if(shift == 0x01) //右移到最右端,改变移位方向变量

{

dir = 0;

}

}

}


}


3、数码管学习

3.1 数码管介绍

一个数码管由8个LED小灯组成。数码管分为共阳数码管和共阴数码管,共阳数码管的8个LED小灯阳极连在一起, 阳极为公共端,由阴极控制单个小灯亮灭。共阴数码管同理,数码管内部结构见下图5-4。

下图5-3为数码管的原理图

com引脚为公共端,图中有两个com公共端,为什么有两个公共端呢? 一方面,为了起对称效果,刚好10个引脚,另一方面,因并联电流之和等于总电流,可以降低单条线路承受的电流。


3.2 数码管静态显示原理

下图为KST-51开发板中数码管电路图

从上图可以知道数码管每个LED小灯阳极都接在5v(VCC)上,所以上图6个数码管都是共阳数码管,下面讲解数码管点亮原理。


首先根据分析点亮数码管要先导通数码管对应连接的三极管,即让每个三极管的基极b输出低电平,也就是控制三八译码器将对应Y编号的引脚输出为低电平即能导通三极管,我们第三章中已经介绍了如何应用三八译码器,使用时查看芯片手册即可,就不再介绍。

P0的所有引脚对应连接DB编号引脚,控制P0引脚的输出电平,即可让数码管显示不同的数值。比如让数码管显示8,那么P0要为0b10000000,转换为十六进制就为0x80(链接:进制转换方法)。


3.3数码管真值表

数码管的 8 个段,我们直接当成 8 个 LED 小灯来控制,那就是 a、b、c、d、e、f、g、dp 一共 8 个 LED 小灯。我们控制这8个小灯来让数码管显示不同数值,而数码管显示的数字字符对应给 P0 的赋值,我们叫做数码管的真值表。 数码管真值表见下表5-7。

3.4 数码管的应用

让数码管静态显示字符程序

#include


sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;


void main()

{

ENLED = 0;//使能U3,导通三极管Q9,

ADDR3 = 1;

ADDR2 = 0;

ADDR1 = 1;

ADDR0 = 1;

P0 = 0x80;//点亮数码管DS4的a、b、c、d、e、f和g段,让数码管显示字符8

while(1);//让数码管DS4一直显示字符8

}


数码管静态显示秒表先计时后倒计时程序

先介绍C51中的关键字code,前面定义变量时使用关键字unsigned char或unsigned int,这样定义的变量都是放在单片机RAM中,并且程序中可以随意更改这些变量的值,而运用code关键字修饰下定义的变量,则可以存储到程序空间FLASH中,大大节省单片机RAM空间,但程序中不能更改这些变量的值。下面我们来看看运用了code关键字的程序。


#include


sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;


//用数组存储数码管真值表,数组将在下一章详细介绍

unsigned char code Ledchar[] = {

0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,

0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E

};


void main()

{

unsigned char cnt = 0;//定义溢出计数变量,记录溢出次数

signed char sec = 0;//记录经过的秒数

unsigned char dir = 0;//定义选择变量,0代表秒表,1代表倒计时


ENLED = 0;//使能U3,导通三极管Q8,准备点亮数码管DS5

ADDR3 = 1;

ADDR2 = 1;

ADDR1 = 0;

ADDR0 = 0;


TMOD = 0x01;//配置T0为工作模式一

TH0 = 0xB8;//为T0赋初值

TL0 = 0x00;

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


while(1)

{

if(TF0 == 1)//判断T0是否溢出

{

TF0 = 0;//软件将溢出标志清零

TH0 = 0xB8;//为T0重新赋值

TL0 = 0x00;

cnt++;//计数值自加1,

if(cnt >= 50)//判断T0是否溢出50次

{

cnt = 0;//达到50次后计数值清零

if(dir == 0)//选择变量dir等于0,实现秒表功能

{

P0 = Ledchar[sec];//当前秒数对应的真值表中的值送到P0口

sec++;//秒数记录自加一

if(P0 == 0x8E)//当P0值使数码管显示字符F时,

{

dir = 1;//将选择变量置为1,准备实现倒计时功能

sec = 14;//将秒数置为14

}

}else //实现倒计时功能

{

P0 = Ledchar[sec];//当前秒数对应的真值表中的值送到P0口

sec--;//秒数记录自减一

if(sec < 0)//当秒数小于0后

{

dir = 0;//将选择变量置为0,准备实现秒表功能

sec = 1;//将秒数置为1

}

}

}


}

}


}

推荐阅读

史海拾趣

世纪金光(CENGOL)公司的发展小趣事

世纪金光(CENGOL)公司自创立之初,就立志要在半导体领域实现自主创新。经过无数次的实验与尝试,公司的研发团队成功攻克了高纯碳化硅粉料提纯技术。这一突破不仅使世纪金光在碳化硅材料领域取得了领先地位,更为后续产品的研发奠定了坚实基础。随着技术的不断完善,世纪金光成功推出了6英寸碳化硅单晶,并实现了量产,这一成就标志着公司在碳化硅材料领域取得了重要进展。

AMI Semiconductor公司的发展小趣事

自成立以来,世纪金光始终注重科研实力的积累。公司积极承担国家科研任务,已转接和直接承担国家科研任务80多项。在这些科研项目中,世纪金光取得了丰硕的成果,其中12项成果处于国内同类技术领先水平,5项成果达到国际先进水平。这些成果的取得不仅提升了公司的技术水平,也为公司在半导体领域的竞争提供了有力支撑。

Comair Rotron公司的发展小趣事

1947年,James Van Ryan在美国纽约伍德斯托克创立了Comair公司,初期主要专注于风扇和风机产品的制造。当时,电子行业正处于起步阶段,对散热和空气流动的需求日益增长。Comair凭借其出色的技术和产品质量,很快在电子行业中崭露头角,为早期的电子设备提供了可靠的散热解决方案。

GCi Technologies公司的发展小趣事
可能是由于外部电阻设置不当或IC内部故障导致。
Allied Electronic & Semiconductor Technology Inc公司的发展小趣事

随着国内市场的饱和,AE&ST公司开始将目光投向全球。公司积极寻找国际合作伙伴,拓展海外市场。在一次国际电子展上,AE&ST与一家欧洲知名电子公司达成了战略合作协议。双方共同研发了一款针对欧洲市场的特色产品,并成功打开了欧洲市场的大门。此后,AE&ST公司不断深化与国际伙伴的合作,逐步实现了全球化布局。

Decawave公司的发展小趣事

在2015年的微软室内定位大赛中,Decawave的UWB技术大放异彩。公司凭借其高精度、低误差的UWB定位解决方案,在激烈的竞争中脱颖而出,荣获最佳无线电定位解决方案奖。这一荣誉不仅证明了Decawave在UWB技术领域的领先地位,也为其在市场上的推广和应用奠定了坚实的基础。

问答坊 | AI 解惑

电压不足期间支持电信电源的小电容

本设计实例介绍如何在短暂电压不足期间使电信设备保持正常工作。首先必须了解电信设备专用电源的几个细节。向电信设备馈电的电源的共模电压为-48V,尽管实际电压范围可能是-42.5V ~ -56V、-40V ~ -60V,甚至超出这些范围。公共电源——“砖块”DC/D ...…

查看全部问答>

SABER与控制系统仿真

SABER与控制系统仿真…

查看全部问答>

学生求助CE串口开发问题

大家好,学生以前接触的硬件类比较多,这次需要在2440板子下跑wince,用串口读数据,我找了很多资料,发现都是直接给代码的,学生求助,是在什么环境下编译?PB吗?如果是PB的话,就是改PB里哪里的程序呢???学生很疑惑,学生其实是想用VS2005中 ...…

查看全部问答>

68013A端点EP6OUT的BULK写失败求助,急!!

68013A端点EP6OUT的BULK写失败求助,急!! 易用专业的PCI、USB、LED方案正在对68013A采用slavefifo方式进行bulk读写操作 我用EP2做in端点,1024字节,2从缓冲 用EP6做OUT端点,512字节,4从缓冲 我写好了68013A的固件,用CYPRESS的开发工具 ...…

查看全部问答>

Shell组件的选择问题??

   用PB编制系统镜像,由于用到SHFileOperation复制文件,但是显示进度框上没有取消按钮 别的版本的机器则可以...不知道这个跟什么组件选择还有关系,还有就是ceshell.dll是怎么生成的 新手请教各位大虾!!…

查看全部问答>

电源变压器

本帖最后由 paulhyde 于 2014-9-15 09:34 编辑 …

查看全部问答>

我的新书《ARM Cortex-M0从这里开始》,已经上市

我的新书《ARM Cortex-M0从这里开始》已经出版,即将上市,希望大家多多支持。在这里先谢谢大家了。。。。。。。。。。。。。     前言和目录:     已经上市   北航:http://www.buaapress.com.cn/bookdetai ...…

查看全部问答>

电机控制 - 无刷直流 (BLDC) 电机主推产品

本帖最后由 dontium 于 2015-1-23 13:10 编辑 器件型号:RDK_BLDC                     DRV8312-C2-KIT (电机控制评估套件)    &nbs ...…

查看全部问答>

易電源學習心得

易電源學習心得剛剛參加了玩遊戲,體驗易電源。正如題所示,通過遊戲來體驗易電源的通俗學習方式,通過學習易電源,深深體會IT設計工程師的初衷,特別在介紹個單位器件時詳細說明。遊戲中,大大啓發我們對電子的好奇心。想想原來如此簡單的電路在操 ...…

查看全部问答>

ls -bash: ls: command not found .

原因:在设置环境变量时,编辑profile文件没有写正确,导致在命令行下ls等命令不能够识别。 解决方案: exportPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin…

查看全部问答>