51单片机典型项目实战全能一本通(C语言版)(视频版)
上QQ阅读APP看书,第一时间看更新

第3章 单片机I/O口应用——点亮发光二极管与开关检测

例3-1 单片机控制点亮发光LED案例1

由于P0口大多作为总线端口使用,但是点亮发光二极管时,是作为通用I/O口使用的,必须接上拉电阻。由于P1~P3口内部已有30kΩ左右的上拉电阻,因此要注意P0口作为通用I/O口使用时,与P1~P3口的差别。下面讨论P1~P3口与LED发光二极管的连接驱动问题。

使用单片机并行端口P1~P3直接驱动发光二极管,有两种连接方法,电路如图3-1所示。P1、P2、P3口与P0口相比,P1~P3口每一位的驱动能力只有P0口的一半,即每位驱动4个LSTTL负载。当P1~P3口的某位为高电平时,可提供200µA的拉电流;当某位为低电平(0.45V)时,可提供1.6mA的灌电流,为什么拉电流要比灌电流小许多,这是因为P1~P3口内部有30kΩ左右的上拉电阻,如果为图3-1(a)所示的高电平输出,则从P1、P2和P3口输出的拉电流Id仅为几百µA,驱动能力较弱,亮度较差。如果端口引脚为低电平,能使灌电流Id从单片机的外部流入内部,将大大增加流过的灌电流值,如图3-1(b)所示。所以,8051单片机任何一个端口要想获得较大的驱动能力,要采用低电平输出。如果一定要高电平驱动,可在单片机与发光二极管之间加驱动电路,如74LS04、74LS244等。

图3-1 发光二极管与单片机并行口P1~P3的连接

制作一个流水灯,原理电路如图3-2所示,8个发光二极管LED0~LED7经限流电阻分别接至P1口的P1.0~P1.7引脚上,阳极共同接高电平VCC。编写程序来控制发光二极管由上至下反复循环,把流水灯点亮,每次点亮一个发光二极管。

图3-2 单片机控制的流水灯电路

本例参考程序如下。

  #include <reg51.h>
  #include <intrins.h>        //包含移位函数_crol_(  )的头文件intrins.h 
  #define uchar unsigned char     
  #define uint unsigned int   
  void  delay(uint i)          //延时函数 
  { 
      uchar t; 
      while (i--) 
      {  
          for(t=0;t<120;t++);  
      } 
  } 
   
  void  main(  )               //主程序 
  {  
      P1=0xfe;                 //向P1口送出点亮P1.0的数据 
       while (1)               //反复循环 
       {     
          delay( 500 );        //500 为延时参数,可根据实际需要调整 
          P1=_crol_(P1,1) ;    //函数_crol_(P1,1)把P1中的点亮数据循环左移1位 
       } 
  }

程序说明如下。

(1)关于while(1)的两种用法。

• “while(1);”:while(1)后面如果有个分号,表示程序停留在这条指令上。

• “while(1){……;}”:是反复循环执行花括号内的程序段,这是本例的用法,

即控制流水灯反复循环显示。

(2)本例中用到了C51函数库中的循环移位函数,循环移位函数包括循环左移函数“_crol_”和循环右移函数“_cror_”。本例使用的是循环左移函数“_crol_(P1,1)”,括号中第1个参数为循环左移的对象,即对P1中的内容循环左移;第2个参数为左移的位数,即左移1位。在编程中一定要把移位函数的头文件intrins.h包含在内,例如,程序中的第2行“#include <intrins.h>”。