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

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

控制发光二极管由上至下,再由下至上的反复循环点亮的流水灯,原理电路如图3-3所示。为了电路图简洁,电路中省去了时钟电路和复位电路,47400-00-68-1引脚与+5V电源的连接也可省略,Proteus已经默认,不影响仿真效果。

图3-3 单片机控制的流水灯点亮原理电路

下面采用3种方法来实现题目要求,具体如下。

1. 数组的字节操作实现

本方法是建立1个字符型数组,将控制8个LED显示的8位数据作为数组元素,依次送到P1口来实现。

参考程序如下。

  #include <reg51.h>
  #define uchar unsigned char   
  uchar tab[ ]={ 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe }; 
                       //前8个数据为由上至下的点亮数据,后8个为由下至上的点亮数据 
   
  void  delay(  )
  {  
       uchar i,j; 
       for(i=0; i<255; i++) 
       for(j=0; j<255; j++); 
  } 
   
  void  main(  )             //主函数
  {  
      uchar i; 
      while (1)              //反复循环 
      { 
          for(i=0;i<16; i++) 
          {
             P1=tab[i];         //向P1口送出点亮数据的数组元素 
             delay( );          //延时,即点亮一段时间 
          } 
      } 
  }

2. 通过移位运算符实现控制

本方法是使用C51编程语言中的移位运算符“>>”“<<”,把送到P1口的显示控制数据移位,从而实现发光二极管的依次点亮。

参考程序如下。

  #include <reg51.h>
  #define uchar unsigned char   
   
  void  delay(  )               //延时函数 
  {  
      uchar i,j; 
      for(i=0; i<255;i++) 
      for(j=0; j<255;j++); 
  } 
   
  void  main(  )                //主函数 
  {  
      uchar i,temp; 
      while (1) 
       {  
          temp=0x01;            //左移初值赋给temp 
          for(i=0;i<8;i++) 
          {  
             P1=~temp;          //temp中的数据取反后送P1口 
             delay(  );         //延时 
             temp=temp<<1;      //temp中的数据左移一位 
          }  
          temp=0x80;            //将右移初值赋予temp 
          for(i=0;i<8;i++) 
          {  
             P1=~temp;          //temp中的数据取反后送P1口  
             delay(  );         //延时 
             temp=temp>>1;      //temp中的数据右移一位 
          } 
      } 
  }

程序说明如下。

本例使用了左移、右移移位运算符。注意使用移位运算符“>>”“<<”与C51中的库函数循环左移函数“_crol_”和循环右移函数“_cror_”的区别。左移移位运算“<<”是将高位丢弃,低位补0;右移移位运算“>>”是将低位丢弃,高位补0。循环左移函数“_crol_”是将移出的高位再补到低位,即“循环”移位。同理,循环右移函数“_cror_”是将移出的低位再补到高位。

3. 用循环左、右移位函数实现

本方法是使用C51中提供的库函数,即循环左移n位函数和循环右移n位函数,控制发光二极管的点亮。

参考程序如下。

  #include <reg51.h>
  #include <intrins.h>        //包含循环左、右移位函数的头文件 
  #define uchar unsigned char   
  
  void  delay(  ) 
  {  
      uchar i,j; 
      for(i=0;i<255;i++) 
      for(j=0;j<255;j++); 
  } 
  void  main(  )                    // 主函数 
  {  
      uchar i,temp; 
      while (1) 
      {  
          temp=0xfe;                // 初值为11111110B 
          for(i=0;i<7;i++)    
          {  
             P1=temp;               // temp中的点亮数据送P1口,控制点亮显示 
             delay(  );             // 延时 
             temp=_crol_(temp,1);   // 执行左移函数,temp中的数据循环左移1位
          } 
          for(i=0;i<7;i++)  
          {  
             P1=temp;               // temp中的数据送P1口输出 
             delay(  );             // 延时 
             temp=_cror_( temp,1);  // 执行循环右移函数,temp中的数据循环右移1位
          } 
      } 
  }