51单片机入门教程(2)——实现流水灯

发布者:心灵飞翔最新更新时间:2020-03-09 来源: eefocus关键字:51单片机  入门教程  流水灯 手机看文章 扫描二维码
随时随地手机看文章

一、搭建流水灯电路

在Proteus中搭建流水灯电路如图

在这里插入图片描述

二、流水灯程序

我们可以把流水灯看作依次点亮若干个灯。

程序如下:


#include

sbit led1 = P2^0;

sbit led2 = P2^1;

sbit led3 = P2^2;

sbit led4 = P2^3;

sbit led5 = P2^4;

sbit led6 = P2^5;

sbit led7 = P2^6;

sbit led8 = P2^7;


void main()

{

    //点亮第一个灯

    led1 = 1;

    led2 = 0;

    led3 = 0;

    led4 = 0;

    led5 = 0;

    led6 = 0;

    led7 = 0;

    led8 = 0;

    //点亮第二个灯

    led1 = 0;

    led2 = 1;

    led3 = 0;

    led4 = 0;

    led5 = 0;

    led6 = 0;

    led7 = 0;

    led8 = 0;    

    //点亮剩余的灯

    //省略……

    while(1);

}


编译并下载程序到仿真中,观察现象发现只有第二个灯是亮的???

什么鬼???


2.1 延时程序

单片机的执行指令速度非常快,一个晶振是12MHz的单片机执行一条指令的速度是微秒级的,所以点亮第一个灯的时间太短了,以至于我们根本没有察觉。

因此我们需要一个延时的语句。

实现延时的方法就是循环执行很多次空指令。程序如下:


//延时一秒的程序

int i,j;

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

{

  for(j = 0; j < 1000; ++j)

  {

    ;//什么也不做

  }

}


然后我们就可以把流水灯的程序改成这样的:


#include

sbit led1 = P2^0;

sbit led2 = P2^1;

sbit led3 = P2^2;

sbit led4 = P2^3;

sbit led5 = P2^4;

sbit led6 = P2^5;

sbit led7 = P2^6;

sbit led8 = P2^7;


void main()

{

    int i,j;

   //点亮第一个灯

    led1 = 1;

    led2 = 0;

    led3 = 0;

    led4 = 0;

    led5 = 0;

    led6 = 0;

    led7 = 0;

    led8 = 0;

    //延时1秒 

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

{

  for(j = 0; j < 1000; ++j)

  {

    ;//什么也不做

  }

}

    //点亮第二个灯

    led1 = 0;

    led2 = 1;

    led3 = 0;

    led4 = 0;

    led5 = 0;

    led6 = 0;

    led7 = 0;

    led8 = 0;    

    //点亮剩余的灯

    //省略……

    while(1);

}


编译并下载程序到仿真中,观察现象发现首先第一个灯亮,过了一会儿第二个灯亮。


2.2 延时函数

我们剩下的任务就是依次点亮每个灯,但是每次点亮一个灯就需要写一段延时程序,很麻烦!

为了程序的可读性(toulan),可以把延时程序写成一个子函数,随时供我们使用。

C语言中子函数的定义方式如下


返回值类型 函数名 (参数1,参数2,……)

{

  函数体;

}


这样我们就可以把延时函数写成这样:


void delay1s()

{

  int i,j;

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

  {

    for(j = 0; j<1000;++j)

    {

      //什么也不做

    }

  }

}


几点说明:


void:因为该延时函数不需要返回值,所以写为void

delay1s:该函数的函数名,命名需要符合C语言的标识符命名规则。

(): 不需要传入参数,所以括号中为空

至此我们可以把流水灯程序写为以下形式:

#include


sbit led1 = P2^0;

sbit led2 = P2^1;

sbit led3 = P2^2;

sbit led4 = P2^3;

sbit led5 = P2^4;

sbit led6 = P2^5;

sbit led7 = P2^6;

sbit led8 = P2^7;


//延时1s

void delay1s()

{  

    int i ,j;

    for(i = 0;i<110; ++i){

  for(j = 0;j<1000;++j){

    ;

  }

}

}


void main()

{

    //点亮第一个灯

    led1 = 1;

    led2 = 0;

    led3 = 0;

    led4 = 0;

    led5 = 0;

    led6 = 0;

    led7 = 0;

    led8 = 0;


//延时1s

delay1s();


    //点亮第二个灯

    led1 = 0;

    led2 = 1;

    led3 = 0;

    led4 = 0;

    led5 = 0;

    led6 = 0;

    led7 = 0;

    led8 = 0;    

    //点亮剩余的灯

    //省略……

    while(1);

}


2.3 按字节寻址

我们可以看到,上面的代码十分冗长,每次点亮一个灯需要8条语句,那么如何简化?

比如把

led1 = 1;led2 = 0; led3 = 0; led4 = 0; led5 = 0; led6 = 0; led7 = 0; led8 = 0;

这8条语句替代为P2 = 0000 0001???

答案是可以的。代码如下


unsigned char a = 0x01;  //0x01是0000 0001的16进制形式

P2 = a;//相当于led1 = 1;led2 = 0; led3 = 0;  led4 = 0; led5 = 0; led6 = 0; led7 = 0; led8 = 0;


至此,我们可以把流水的代码优化为如下形式:


#include


//延时1s

void delay1s()

{  

    int i ,j;

    for(i = 0;i<110; ++i){

  for(j = 0;j<1000;++j){

    ;

  }

}

}


void main()

{

unsigned char a1 = 0x01 ;    // 0000 0001

unsigned char a2 = 0x02;    // 0000 0010

    //点亮第一个灯

P2 = a1;


//延时1s

delay1s();


    //点亮第二个灯

P2 = a2;    

    //点亮剩余的灯

    //省略……

    while(1);

}


2.4 逻辑移位

依次点亮8个灯,每点亮一个灯都需要一句赋值语句还是很麻烦 。

所以可以使用逻辑移位语句,每次赋值后,将数值左移一位。

C语言逻辑左移代码如下:


unsigned char a = 0x01;  //a = 0000 0001

unsigned char b = a<<1;  // b = 0000 0010

usingned char c = a<<3;   //c = 0000 1000


至此,我们可以把流水灯的代码优化如下:


#include

//延时1s

void delay1s()

{  

    int i ,j;

    for(i = 0;i<110; ++i){

  for(j = 0;j<1000;++j){

    ;

  }

}

}


void main()

{

    //初始化

unsigned char a = 0x01;

    while(1)

{

  //循环点亮流水灯

  P2 = a;   

  a = a<<1;

  delay1s();

}

}


编译并下载程序到仿真中,观察现象发现8个灯依次亮过之后不再亮了。


2.5 条件判断

因为在移位操作中,当变量a的值为1000 0000时,再次执行左移操作,a 中的1就溢出了,因此a的值变为0000 0000,此时我们需要加一个判断,使a再次恢复为0000 0001

C语言中,if条件判断使用方式如下


if(判断条件)

{

  //语句

}


当判断条件为真时,执行{ }中的语句。

至此,流水灯代码可改成如下形式:


#include


//延时1s

void delay1s()

{  

    int i ,j;

    for(i = 0;i<110; ++i){

  for(j = 0;j<1000;++j){

    ;

  }

}

}


void main()

{

unsigned char a = 0x01;

    while(1)

{

  if(a == 0x00)   //如果高位溢出

  {

    a = 0x01;      //则恢复

  }

  //循环点亮led灯

  P2 = a;

  a = a<<1;

  delay1s();

}

}

关键字:51单片机  入门教程  流水灯 引用地址:51单片机入门教程(2)——实现流水灯

上一篇:51单片机入门教程(0)—— 开发环境配置
下一篇:1课:单片机简叙

推荐阅读最新更新时间:2024-11-03 15:44

8051单片机的存储器组织采用何种结构
问题: 8051单片机的存储器组织采用何种结构?存储器地址空间如何划分围和容量如何?使用上和容量如何?使用上有何特点? 解答:(1)80C51在结构上的特点 80C51采用将程序存储器和数据存储器截然分开,分别寻址的结构,称为Harvard结构。 (2)在物理和逻辑上的地址空间 存储器上设有4个存储器空间:片内程序存储器、片外程序存储器、片内数据存储器、片外数据存储器。 在逻辑上有3个存储器地址空间:片内、片外统一的64KB程序存储器地址空间,片内256B数据存储器地址空间,片外64KB的数据存储器地址空间。 (3)访问格式 访问片内RAM采用MOV格式 访问片外RAM采用MOVX格式
[单片机]
51单片机产生PWM软件延时和定时器产生两种方法
89C51芯片没有自带PWM发生器,如果要用51来产生PWM波就必须要用软件编程的方法来模拟。方法大概可以分为软件延时和定时器产生两种方法。下面将逐一介绍。 1 软件延时法 利用软件延时函数,控制电平持续的时间,达到模拟pwm的效果。 程序如下: #include sbit pwm=P1^0; main() { while(1) { pwm=1; delayus(60);//置高电平后延时60us,占空比60% pwm=0; delayus(40); } } void delayus(uint x) { while(x--); } proteus软件仿真结果如下: 可见,用这种延时函数的方法就能简单地模拟出pwm输出。但是
[单片机]
<font color='red'>51单片机</font>产生PWM软件延时和定时器产生两种方法
构造一个51单片机的实时操作系统
摘 要:从Keil C51的内存空间管理方式入手,着重讨论实时操作系统在任务调度时的重入问题,分析一些解决重入的基本方式与方法:分析实时操作系统任务调度的占先性,提出非占先的任务调度是能更适合于Keil C51的一种调度方式。为此,构造这一实时操作系统,并有针对性地介绍此系统的堆管理方法、任务的建立以厦任务的切换等。 关键词:51单片机 实时操作系统 任务重八调度 目前,大多数的产品开发是在基于一些小容量的单片机上进行的。51系列单片机,是我国目前使用最多的单片机系列之一,有非常广大的应用环境与前景,多年来的资源积累,使51系列单片机仍是许多开发者的首选。针对这种情况,近几年涌现出许多基于51内核的扩展芯片,功能越来越齐全,速
[单片机]
51单片机控制步进电机和直流减速电机
51单片机控制步进电机和直流减速电机。 用这个电路图可以实现多个电机的联动,易于写程序控制。 使用多个L298驱动芯片,安全高效。 以下是正文: L298驱动芯片介绍: L298工作电压高达46V 总DC电流达4A 低饱和电压 L298具有过温保护功能 file:///C:/Users/HUAWEI/AppData/Local/Temp/msohtmlclip1/01/clip_image005.png 接下来看看protues的仿真图。 按图示接法,驱动芯片的in口和out口电平状态完全对应一致。但不会有过大电流流过单片机。因此安全可靠。 驱动方法: 直流电机,直接电机的连线上,给予一高一低的两个电平即
[单片机]
<font color='red'>51单片机</font>控制步进电机和直流减速电机
基于51单片机设计的TFT液晶显示
   0 引言   51单片机作为一种常见的通用单片机, 虽然其内部资源, 处理速度等都无法与新型高速单片机相提并论, 但其低廉的价格, 极低的入门难度以及适用于简单场合应用等特点, 依然是开发者的常用选择之一。   用51单片机驱动液晶模块通常都使用1602和12864等极为简单的液晶模块, 这里介绍用51单片机驱动QVGA分辨率的TFT液晶模块, 以实现彩色和更为复杂的内容显示的方法。同时, 本文还将使用DS1302芯片和DS18B20芯片来实现在液晶屏上显示实时时钟和温度。    1 硬件设计   本系统硬件电路的设计主要包括单片机最小系统电路, TFT液晶显示电路, 时钟电路, 设置电路以及温度采集电路。其系统工作
[单片机]
基于<font color='red'>51单片机</font>设计的TFT液晶显示
51单片机——DS18B20
DS18B20——温度传感器,单片机可以通过 1-Wire 和 DS18B20 进行通 信,最终将温度读出。1-Wire 总线的硬件接口很简单,只需要把 18B20 的数据引脚和单片 机的一个 IO 口接上就可以通信。最高12为的温度存储值,补码形式存储。 2字节,LSB低字节,MSB高字节,-55~125 1、初始化 检测存在脉冲:总线上存在DS18B20,总线会根据时序要求返回一个低电平脉冲。单片机要拉低这个引脚,持续大概 480us到960us之间 的时间即可,我们的程序中持续了 500us。然后,单片机释放总线,就是给高电平,DS18B20 等待大概 15 到 60us 后,会主动拉低这个引脚大概是 60 到 240u
[单片机]
<font color='red'>51单片机</font>——DS18B20
基于51单片机的交通灯控制系统设计
第一章 硬件设计与原理 以AT89C51单片机为核心,起着控制作用。系统包括数码管显示电路、复位电路、时钟电路、发光二级管电路和按键电路。设计思路分为六个模块:复位电路、晶振电路模块、AT89C51、数码管显示电路、发光二级管电路和按键电路这六个模块。 1.2 硬件设计分析 1.2.1 电源的设计 系统电源使用直流5伏。 由电脑USB接口提供电源。 USB是通用串行总线(Universal Serial Bus)接口的简称。它是目前使用比较广泛的电脑接口之一,主要版本有1.0、1.1和最新的2.0三种版本。根据USB总线的工业标准,它可以提供额定功率为5V/500mA的电源供USB设备使用。 1.2.2 单片机最小系统 5
[单片机]
基于<font color='red'>51单片机</font>的交通灯控制系统设计
51单片机液晶显示计时器
要想实现人机交互,显示装置是不可缺少的。前面讲到了如何利用单片机控制数码管的显示,这篇文章主要关于如何控制液晶显示,并在此基础上加上定时器的功能,把原来已用数码管显示的定时器搬到液晶屏上来。 这里用到的液晶为LCD1602,能够同时显示16x02即32个字符(16列2行)。1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号等,直接向其写入ASCII码即可显示相应字符。1602共16个 管脚,管脚功能如下: 实际应用时,所用液晶模块与单片机的连接图如下: 其中7~14管脚为IO,与单片机的P0口相接,单片机可通过向P0口发送数据被液
[单片机]
<font color='red'>51单片机</font>液晶显示计时器
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved