这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 基础知识每日一题——第四十六题

共11条 2/2 1 2 跳转至
高工
2014-08-13 10:46:30     打赏
11楼

51 单片机本身资源较少,而使用延时函数是一种极其耗费资源的事情。

  使定时器则可以大大提高资源的利用率。

  用延时函数实现:

  电路图:


  /*==========================================================

  * 开发人员:XXX

  * 当前版本:V1.0

  * 创建时间:11/19/2013

  * 修改时间:

  * 功能说明:让 8 个数码管同时显示数字 1-8,显示方式为动态显示

  *==========================================================*/

  /*================(1)头文件、宏定义、变量定义及声明=======*/

  #include //头文件,在"reg52.h"处右击可查看头文件的内容

  /*数码管的相关变量和数组*/

  sbit duxu=P3^4;                        //段选信号    

  sbit wexu=P3^5;                       //位选信号

  unsigned char code table[]=

  {

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

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

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

  0x39,0x5e,0x79,0x71

  };

  unsigned char code table1[]=

  {

  0xfe,0xfd,0xfb,0xf7,

  0xef,0xdf,0xbf,0x7f

  };

  /*================(2)函数声明===========================*/

  void delay(unsigned int);

  /*================(3)主函数===========================*/

  void main()

  {

  unsigned char i;     //定义循环变量

  i=0;

  while(1)           //让程序不停地执行次此循环

  {

  wexu=1;

  P1=table1[i];   //送位选数据

  wexu=0;

  P1=0xff;     //在送段选数据前关闭所有的显示,防止打开选时

  duxu=1;         //原来的位选数据通过锁存器造成乱码

  P1=table[i+1]; //如果写成 table[i]的话,会显示 0-7

  duxu=0;

  delay(60);

  i++;

  if(i==8) i=0;

  //注意不要写成 if(i==7)

  }

  }

  /*================(4)子函数声明===========================*/

  /**************************************************

  *名称:delay(uint xms)

  *功能:延时函数,用来延迟时间

  *入口参数:xms

  *出口参数:无

  *说明:通过不断地执行空语句,来延迟时间(延时可以用延时语句,也可以用定时器产生

  中断来延迟时间,此例属于延时语句)

  *范例:void delay(uint xms);

  **************************************************/

  void delay(unsigned int xms)                    //xms 为形式参数

  {

    unsigned int i;                              //循环变量,此处定义成 unsigned int 或者 unsigned char

  均可,但是要注意变量的范围,如 unsigned char 为 0-255

  for(i=xms;i>0;i--);                   //通过不断地执行空语句,来延迟时间

  }

      (2)用定时器实现:

  电路图:

  /*==========================================================

  * 开发人员:XXX

  * 当前版本:V1.0

  * 创建时间:11/21/2013

  * 修改时间:

  * 功能说明:用定时器中断实现数码管的动态扫描,大家可以对比用普通的 delay()函

  数来实现动态扫描有什么区别

  *==========================================================*/

  #include    //52 单片机头文件

  sbit dula = P3^4;   //段选

  sbit wela = P3^5;   //位选

  unsigned char num1;   //定义一个变量,用来对定时器中断进行计数

  unsigned char code table1[]=   //数码管(共阴)的段选编码,范围是 0-F

  {

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

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

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

  0x39,0x5e,0x79,0x71

  };

  unsigned char code table2[]=    //数码管的位选编码,范围是 1-8

  {

  0xfe,0xfd,0xfb,0xf7,   //例如 0xfe=1111 1110 点亮第一个数码管

  0xef,0xdf,0xbf,0x7f

  };

  /*==========================================================

  *函数名称:Init()

  *功  能:对定时器进行初始化

  *入口参数:

  *出口参数:

  *说  明:定时器 0,工作方式为 1

  *==========================================================*/

  void Init()

  {

  TMOD = 0x01;  // 定时器工作方式为 1

  TH0 = 63536/256;  //赋初值,此处设定的中断时间为 2ms,(65536-2000)/256

  TL0 = 63536%256;

  EA = 1;   //开总中断

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

  TR0 = 1;  //开启定时器

  }

  //主函数

  void main()

  {

  Init();  //初始化

  while(1);  //平时执行空循环

  }

  /*==========================================================

  *函数名称:Timer0()

  *功  能:定时器中断服务内容

  *入口参数:

  *出口参数:

  *说  明:

  *==========================================================*/

  void Timer0() interrupt 1  //中断序号为 1

  {

  TH0 = 63536/256;  //每次中断发生后,先进行赋初值

  TL0 = 63536%256;  //以下部分为数码管的显示部分

  P1=table1[num1+1];  //段选信号,将这一语句放在前面有消影的作用

  dula=1;

  dula=0;

  P1=table2[num1];  //位选信号

  wela=1;

  wela=0;

  num1++; //对定时器的中断进行计数,每中断一次,数码管更换一次内容

  if(num1==8)

  num1=0;


共11条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]