首页 > 其他分享 >第三章 数码管的显示原理及实现

第三章 数码管的显示原理及实现

时间:2023-05-09 09:57:04浏览次数:35  
标签:wela P0 定时器 第三章 中断 dula 数码管 计数器 原理

第三章 数码管的显示原理及实现

 

实验板上用了2片74HC573来驱动数码管,分别控制位选和段选信号。

  1. 让第一个数码管显示一个8字,代码如图1所示。

 

图1 数码管显示8

 

  1. 让6个数码管同时点亮,间隔0.5s,依次显示0-F。

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit wela=P2^6;

sbit dula=P2^7;

uchar num;

uchar code table[]={0x3f,0x06,0x5b,0x4f,

                              0x66,0x6d,0x7d,0x07,

                              0x7f,0x6f,0x77,0x7c,

                              0x39,0x5e,0x79,0x71};

void delayms(uint);

 

void main()

{

wela=1; // turn on u2 latch

P0=0xc0; // 6 bits on

wela=0; // turn off u2 latch

while(1)

{

for(num=0;num<16;num++)

{

dula=1; //turn on seg choose

P0=table[num];

dula=0; //turn off seg choose

delayms(500);

}

}

 

}

 

void delayms(uint xms)

{

uint i,j;

for(i=xms;i>0;i++)

  for(j=110;j>0;j++);

}

难点在于,位选只需要打开一次,就被锁存了,也就是这里的6的数码管都一直被选中了,然后用段选在6个数码管上同时显示0-f。这也是用74573锁存器的好处。

 

  1. 数码管动态显示。每个数码管依次显示不同的数字。

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^6;

sbit wela=P2^7;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void delayms(uint);

 

void main()

{

  while(1)

{

    dula=1;      //seg1 display

    P0=table[1];

    dula=0;

    P0=0xff;

    wela=1;

    P0=0xfe;

    wela=0;

    delayms(500);

 

dula=1;

    P0=table[2];

    dula=0;

    P0=0xff;

    wela=1;

    P0=0xfd;

    wela=0;

    delayms(500);

 

dula=1;

    P0=table[3];

    dula=0;

    P0=0xfb;

    wela=1;

    P0=0xfe;

    wela=0;

    delayms(500);

 

dula=1;

    P0=table[4];

    dula=0;

    P0=0xff;

    wela=1;

    P0=0xf7;

    wela=0;

    delayms(500);

 

dula=1;

    P0=table[5];

    dula=0;

    P0=0xff;

    wela=1;

    P0=0xef;

    wela=0;

    delayms(500);

 

dula=1;

    P0=table[6];

    dula=0;

    P0=0xff;

    wela=1;

    P0=0xdf;

    wela=0;

    delayms(500);

  }

}

 

void delayms(uint xms)

{

uint i,j;

for(i=xms;i>0;i--)

  for(j=110;j>0;j--);

}

这段代码依次控制6个数码管先锁存段选,再取消,然后锁存位选,再延时。其中,P0=0xff,是为了消隐。可以尝试把延时分别调至100ms,10ms,1ms,可以看到数码管可以越来越稳定的显示1-6,就像6个数码管同时显示一样。这就是动态显示效果。所谓动态显示,即轮流向各位数码管送出字形码和相应的位选,利用发光管的余晖和视觉暂留作用,使人觉得数码管好像在同时显示,而实际上是多位数码管一位一位显示,只是轮流的速度非常快,人眼已无法分辨出来。

 

  1. 中断概念

52单片机共有6个中断源:

INT0:外部中断0,由P3.2口引入,低电平或下降沿引起;

INT1:外部中断1,由P3.3口引入,低电平或下降沿引起;

T0:定时器/计数器0中断,由T0计数器计满回0引起;

T1:定时器/计数器1中断,由T1计数器计满回0引起;

T2:定时器/计数器2中断,由T2计数器计满回0引起;

TI/RI:串口中断,串口完成一帧字符发送/接收后引起。

单片机使用时,通常需要设置两个与中断有关的寄存器:中断允许寄存器IE和中断优先级寄存器IP。

中断允许寄存器:

EA:全局中断允许位,1开,0关;

ET2:定时器2/计数器2中断允许位;

ES:串口中断允许位;

ET1:定时器1/计数器1中断允许位;

EX1:外部中断1中断允许位;

ET0:定时器0/计数器0中断允许位;

EX0:外部中断0中断允许位。

中断优先级寄存器IP:

PS:串口中断优先级控制位,1高优先级;0低优先级;

PT1:定时器/计数器1中断优先级控制位;

PX1:外部中断1中断优先级控制位;

PT0:定时器/计数器0中断优先级控制位;

PX0:外部中断0中断优先级控制位。

 

3.5 定时器中断

   定时器/计数器的实质是加1计数器,由高8位和低8位两个寄存器组成。TMOD是其工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0,T1的启动,停止及设置溢出标志。

加1计数器输入的计数脉冲有两个来源,一个是由系统的时钟振荡器输出脉冲经12分频后送来;另一个是由T0或T1引脚输入的外部脉冲源。每来一个脉冲,计数器加1,当加到计数器全为1时,再输入一个脉冲,就使计数器回零,且计数器的溢出,使TCON寄存器的TF0或TF1置1,向CPU发出中断请求(定时器/计数器中断允许时)。如果定时器/计数器工作于定时模式,则表示定时时间已到。如果工作于计数模式,则表示计数已满。

由此可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t。

设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0、T1引脚电平。当某周期采样到一高电平输入,下一周期又采样到一低电平时,则计数器加1。更新的计数值在下一机器周期S3P1期间装入计数器。由于检测一个从1-0下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12M时,最高计数频率不超过1/2M,即计数脉冲周期要大于2us。

TMOD的高4位用于设置定时器1,低4位用于设置定时器0。

GATE-门控制位;

GATE=0,定时器/计数器的启动、停止仅受TCON中的TRX控制。

GATE=1,定时器/计数器的启动、停止受TRX和外部中断引脚INT0,INT1上的电平共同控制。

C/T:0-计数器模式;1-定时器模式;

M1M0:工作方式选择位。00-13位定时器/计数器;01-16位定时器/计数器;10-8位初值自动重装的8位定时器/计数器;11-仅适用于T0,分成两个8位计数器,T1停止计数。

TCON用来控制启停,标志溢出和中断情况。

TF1-定时器1溢出标志位。当定时器1计满溢出时,由硬件使TF1置1,并申请中断。进入中断服务程序后,由硬件自动清0.

TR1-定时器1运行控制位。

TF0-定时器0溢出标志位。

TR0-定制器0运行控制位。

IE1-外部中断1请求标志。

IT1-外部中断1触发方式选择。

IE0-

IT0-

定时器初值的计算方法:当用定时器方式1时,设机器周期为Tcy,定时器产生一次中断的时间为t,那么需要计数的个数N=t/Tcy,装入THX和TLX中的数分别为

THX=(65536-N)/256;

TLX=(65536-N)%256;

在写单片机定时器程序时,在程序开始处需要对定时器及中断寄存器做初始化设置,通常定时器初始化过程如下:

对TMOD赋值,以确定T0和T1的工作方式;

计算初值,并将初值写入TH1,TL1或TH0,TL0;

中断方式时,对IE赋值,开放中断;

使TR0,TR1置位,启动定时器/计数器定时或计数。

 

//发光管以1秒间隔闪烁

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit led1=P1^0;

uchar num;

void main()

{

TMOD=0x01;  //设置定时器0为工作方式1(M1M0为01)

TH0=(65536-45872)/256; //装初值11.0592M晶振定时50ms数为45872

TL0=(65536-45872)%256; //

EA=1;  //开总中断

ET0=1; //开定时器0中断

TR0=1; //启动定时器0

while(1); //程序停在这里等待中断发生

}

 

void T0_time() interrupt 1

{

TH0=(65536-45872)/256;  //重装初值

TL0=(65536-45872)%256;

num++;   //num每加1次判断是否到达20次

if(num==20) //如果到了20次,说明1秒时间到

{

num=0;  //把num清0重新计20次

led1=~led1; //让发光管状态取反

}

}

 

分析:进入主程序后,首先是对定时器和中断有关的寄存器初始化,我们按照上面讲到的通常初始化过程来操作。定时50ms,初值为45872.启动定时器后,主程序停在while(1)处,中断是如何执行呢?一旦开启定时器,定时器便开始计数,当计数溢出时,自动进入中断服务程序。执行完中断服务程序,回到原来处继续执行,也就是继续等待。

用定时器0的方式1实现第1个发光二极管以200ms间隔闪烁。用定时器1的方式1实现数码管前两位59s循环计时。

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^6;

sbit wela=P2^7;

sbit led1=P1^0;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void delayms(uint);

void display(uchar,uchar);

uchar num,num1,num2,shi,ge;

void main()

{

TMOD=0x11; //定时器0和1工作方式

TH0=(65536-45872)/256; //装初值

TL0=(65536-45872)%256;

TH1=(65536-45872)/256; //装初值

TL1=(65536-45872)%256;

EA=1; //开总中断

ET0=1; //开定时器0中断

ET1=1; //开定时器1中断

TR0=1; //启动定时器0

TR1=1; //启动定时器1

while(1)

{

display(shi,ge);

}

}

 

void display(uchar shi,uchar ge) //显示子函数

{

dula=1;

P0=table[shi]; //送段选数据

dula=0;

P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时

         //原来段选数据通过位选锁存器造成混乱

wela=1;

P0=0xfe; //送位选数据

wela=0;

delayms(5); //延时

 

dula=1;

P0=table[ge];

dula=0;

P0=0xff;

wela=1;

P0=0xfd;

wela=0;

delayms(5);

}

 

void delayms(uint xms)

{

uint i,j;

for(i=xms;i>0;i--)

  for(j=110;j>0;j--);

}

 

void T0_time() interrupt 1

{

TH0=(65536-45872)/256; //重装初值

TL0=(65536-45872)%256;

num1++;

if(num1==4) //200ms

{

num1=0;

led1=~led1;

}

}

 

void T1_time() interrupt 3

{

TH1=(65536-45872)/256;

TL1=(65536-45872)%256;

num2++;

if(num2==20) //1s

{

num2=0;

num++;

if(num==60) //这个数送显,到60后归0

num=0;

shi=num/10;

ge=num%10;

}

}

本例用了2个中断函数,进入哪个中断,是靠interrupt后面的序号决定。

 

 

 

标签:wela,P0,定时器,第三章,中断,dula,数码管,计数器,原理
From: https://www.cnblogs.com/halflife/p/17383998.html

相关文章

  • 第三章数据链路层
    1.数据链路层的概述1.0地位数据链路层在网络体系结构中所处的地位链路(Link)就是从一个结点到相邻结点的一段物理线路,而中间没有任何其他的交换结点。数据链路(DataLink)是指把实现通信协议的硬件和软件加到链路上,就构成了数据链路。数据链路层以帧为单位传输和处理数据。......
  • 解Android系统的进程间通信原理(二)----RPC机制(转)
    解Android系统的进程间通信原理(二)----RPC机制理解Android系统中的轻量级解决方案RPC的原理,需要先回顾一下JAVA中的RMI(RemoteMethodInvocation)这个易于使用的纯JAVA方案(用来实现分布式应用)。有关RMI的相关知识,可以通过下图来归纳:Android中的RPC也是参考了JAVA中......
  • 第三章-Java的基本程序设计结构
     3.1一个简单的Java语言程序 这是程序虽然很简单,但是所有的Java程序都具有这种结构,因此还是值得花一些时间来研究的。首先,Java区分大小写。如果出现了大小写拼写错误(例如:将main拼写成Main),程序将无法运行。下面逐行的查看这段源代码。关键字pubilc称为访问修饰符(accessmodi......
  • 索引原理与慢查询优化
    索引原理与慢查询优化一我们要搞明白的问题让我们带着以下问题展开对索引的探索1、为何索引叫key2、索引是如何加速查询的,它的原理是啥?索引模型/结构从二叉树-》平衡二叉树-》b树最后到b+树,每种树到底有什么问题最终演变成到了b+树3、为何b+树不仅能够加速等值查询,还能加速......
  • MySQL索引原理
    一初识索引为什么要有索引?一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。说起加速查询,就不得不提到索引了。什么是索引?索引在MyS......
  • 机器学习算法原理——逻辑斯谛回归
    文章目录逻辑斯谛回归二项逻辑斯谛回归模型极大似然估计多项逻辑斯谛回归模型总结归纳逻辑斯谛回归写在前面:逻辑斯谛回归最初是数学家Verhulst用来研究人口增长是所发现的,是一个非常有趣的发现过程,b站有更详细的背景及过程推导,在此不再赘述:https://www.bilibili.com/video/BV1N......
  • Kerberos协议原理
    本文主要介绍Kerberos认证协议的原理以及解决了什么问题Kerberos是什么Kerberos是计算机网络世界中的一种身份认证协议。身份认证是我们日常生活中经常进行的活动,比如我们要去银行取自己账户的钱,就必须先向银行证明你声明想要取钱的账户确实是你自己的。银行采取的认证方法是......
  • 了解Redis过期策略及实现原理
    大约阅读4分钟如果你使用过redis,那你一定知道过期策略这个命令吧,如果让你设计一个过期键接口,你有什么想法?我们在使用redis时,一般会设置一个过期时间,当然也有不设置过期时间的,也就是永久不过期。当我们设置了过期时间,redis是如何判断是否过期,以及根据什么策略来进行删除的。redi......
  • 学习5月8日位图与布隆过滤器原理以及实现
        现在大多主流计算机的内存差不多在16个g左右,然而互联网的用户体量很大数据动不动就是用亿来计算的,对这些数据进行查找或者从中提取一些有用的信息,若能用一般的数据结构比如哈希或者树形结构需要占据很大的内存,按一个整形4字节那么40一个整形需要占用近15g左右空间,比如......
  • SpringBoot自动配置原理
    SpringBoot自动配置原理一、什么是SpringBoot的自动配置?SpringBoot的最大的特点就是简化了各种xml配置内容,还记得曾经使用SSM框架时我们在spring-mybatis.xml配置了多少内容吗?数据源、连接池、会话工厂、事务管理···,而现在SpringBoot告诉你这些都不需要了,一切交给它的自动......