专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

51单片机学习之2-流水灯

作者:佚名   来源:本站原创   点击数:  更新时间:2013年10月20日   【字体:

第五集

讲解了74HC573 使用方法,我在《51单片机复习笔记1(更新)》有记录。这里略。

讲解了Keil 的仿真方法。比较有用的内容是可以用它来测试一段代码所使用的时间,例如延时函数,在需要精确延时又不想使用定时器的时候可以使用该方法。至于其他的,个人认为还是直接下载到单片机中观察实际情况会比较直观。

 

第六集

51最小系统


 

 

复位原理:

51单片机是高电平脉冲复位,在RST引脚。复位脉冲的高电平宽度必须大于2个机器周期。为了方便计算,我们假设晶振频率为12M,那么它的时钟周期为1/12us(微秒)。它的一个机器周期是12*1/12=1us(微秒)。复位脉冲高电平宽度必须大于2个机器周期即2us,那么就要保证RST引脚高电平的时间大于2us单片机即可自动复位。

 

上电复位:

当通电时,开关是断开的,那么电流从VCC→电容→RSTR32GND。刚上电的时候,电容开始充电,充满电后相当于断路,在电容充电到充满的过程中电压逐渐从高到低(从5V0V)。也就是说一上电,RST端得到就是高电平,当这个时间超过2us时单片机复位,电容快充满到充满后RST得到是低电平,电源不断那么RST就一直是低电平而不会一直复位。RST高电平持续的时间取决于电容充电时间.(这个电容要取多大?怎么计算的?)

 

手动复位:

通电之后,RST会自动复位一次,当单片机在运行的过程中我们需要它复位时可以断电使之上电复位。或者按下SW0开关也能实现复位。当SW0开关按下时电流从VCCR33RSTR32GND形成回路。为方便计算R33假设为300欧即0.3K,我们可以先计算R33得到的电压是 5V* 0.3k/4.7k+0.3k))= 0.3V  R32得到的电压为 5V*4.7k/4.7k+0.3k))=4.7V  RST端的电压也为4.7V,那么4.7对于单片机来说也算高电平,当按下手动按下SW按钮到松开肯定超过2us,所以单片机自动复位。

 

晶振电路:

两个电容一定要相等,取值范围为20-50pf 越大启动越慢。

 

自己搭建最小系统要注意的地方:

EA引脚一定要接高电平即VCC,这是最容易忽略的。这个引脚是用来选择是用片内存储器还是用片外存储器。51内部存储器一般都够我们使用。在以前的单片机需要外扩存储器。我们烧录的程序就是存在片内存储器。

要将P0组引脚当普通IO用时,需要接10K的上拉电阻。P1-P3里面都有上啦电阻。

1  做地址/数据总线时和做输入I/O口时,p0口不用接上拉电阻。
但当做输出I/O口时,p0口必须要接上拉电阻才可以。

P0口是集电极开路输出,也就是OC这种结构没有输出高电平的能力就相当于一个一端接地的开关按下去就输出低电平0V,断开就没有电压是悬空状态
至于用不用上拉电阻取决于外部电路如果要输出高电平控制一个器件而这个器件本身又没有内置上拉就必须自己接一个上拉电阻如果要用低电平控制一个器件则可以不用加上拉

 

第七集

一、流水灯的设计

流水灯就是让八个小Led的依次亮灭。先看看流水灯的电路图。

 

 

 

 

 



这是我的实验板的流水灯电路图。其中
74HC573D输入引脚DB1DB8接在单片机的P1组引脚。74HC573LE接在P2.5引脚。

 

程序设计思路:

我实验板上有8Led灯,正极接在VCC,负极接在单片机的P1引脚(这里不使用74HC573锁存功能所以LE一直保存高电平,相当于Led直接接在单片机的IO口)。要让Led灯亮只需要把对应的端口设为低电平,那么Led灯亮。依次让P1的八个引脚给高低电平那么Led灯也会跟着暗亮。由于51单片机执行的速度很快,所以Led灯的闪烁速度也会很快,我们肉眼无法看到,所以要在电平切换时适当的延时一下。

流水灯的程序设计有很多种方法,如按位置位、数组、函数_cror_()_crol()等,我本来我是比较喜欢用函数的方法,但后来看了一下AVR的,貌似用的最多的是 与、或、非、异或这些运算符来操控IO口,所以我就用这种方式吧,练熟一些方便以后学习。

 

#include "reg52.h"
 

#define uchar unsigned char

#define uint unsigned int
 

 

// 用来延时

void delay ( uchar x)  

{

    uint y;

    for (; x > 0 ; x--  )

    for( y=500 ;y>0;y--);

}
 

 

void main()

{

   uchar Tmp;

   uchar i;

   while(1)

   {

      Tmp=0xFE;          //在流之前先让第一个灯亮 1111 1110 

      for(i=0; i<8; i++)

      {

         P1= Tmp;

         Tmp = Tmp<<1;     //左移动一位 0xFE=1111 1110 << 1 = 1111 1100

         Tmp = Tmp|0x01;   //将最后一位置1  1111 1100 | 0000 0001 = 1111 1101

         delay(100);       // 让灯亮一段时间

      }

   }
 
}

关闭窗口

相关文章