日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

51單片機入門教程(2)——實現(xiàn)流水燈

 幽州淺水 2021-03-18

一、搭建流水燈電路

在Proteus中搭建流水燈電路如圖
在這里插入圖片描述

二、流水燈程序

我們可以把流水燈看作依次點亮若干個燈。
程序如下:

#include <reg52.h> 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); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

編譯并下載程序到仿真中,觀察現(xiàn)象發(fā)現(xiàn)只有第二個燈是亮的???
什么鬼???

2.1 延時程序

單片機的執(zhí)行指令速度非???,一個晶振是12MHz的單片機執(zhí)行一條指令的速度是微秒級的,所以點亮第一個燈的時間太短了,以至于我們根本沒有察覺。
因此我們需要一個延時的語句。
實現(xiàn)延時的方法就是循環(huán)執(zhí)行很多次空指令。程序如下:

//延時一秒的程序
int i,j;
for(i = 0;i < 110; ++i)
{
  for(j = 0; j < 1000; ++j)
  {
    ;//什么也不做
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后我們就可以把流水燈的程序改成這樣的:

#include <reg52.h> 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); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

編譯并下載程序到仿真中,觀察現(xiàn)象發(fā)現(xiàn)首先第一個燈亮,過了一會兒第二個燈亮。

2.2 延時函數(shù)

我們剩下的任務(wù)就是依次點亮每個燈,但是每次點亮一個燈就需要寫一段延時程序,很麻煩!
為了程序的可讀性(toulan),可以把延時程序?qū)懗梢粋€子函數(shù),隨時供我們使用。
C語言中子函數(shù)的定義方式如下

返回值類型 函數(shù)名 (參數(shù)1,參數(shù)2,……)
{
  函數(shù)體;
}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

這樣我們就可以把延時函數(shù)寫成這樣:

void delay1s() { int i,j; for(i = 0; i<110;++i) { for(j = 0; j<1000;++j) { //什么也不做 } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

幾點說明:

  • void:因為該延時函數(shù)不需要返回值,所以寫為void
  • delay1s:該函數(shù)的函數(shù)名,命名需要符合C語言的標識符命名規(guī)則。
  • (): 不需要傳入?yún)?shù),所以括號中為空
    至此我們可以把流水燈程序?qū)憺橐韵滦问剑?/li>
#include <reg52.h>

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

2.3 按字節(jié)尋址

我們可以看到,上面的代碼十分冗長,每次點亮一個燈需要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;
  • 1
  • 2
  • 1
  • 2

至此,我們可以把流水的代碼優(yōu)化為如下形式:

#include <reg52.h>

//延時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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

2.4 邏輯移位

依次點亮8個燈,每點亮一個燈都需要一句賦值語句還是很麻煩 。
所以可以使用邏輯移位語句,每次賦值后,將數(shù)值左移一位。
C語言邏輯左移代碼如下:

unsigned char a = 0x01; //a = 0000 0001 unsigned char b = a<<1; // b = 0000 0010 usingned char c = a<<3; //c = 0000 1000
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

至此,我們可以把流水燈的代碼優(yōu)化如下:

#include <reg52.h>
//延時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)
{
  //循環(huán)點亮流水燈
  P2 = a;   
  a = a<<1;
  delay1s();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

編譯并下載程序到仿真中,觀察現(xiàn)象發(fā)現(xiàn)8個燈依次亮過之后不再亮了。

2.5 條件判斷

因為在移位操作中,當變量a的值為1000 0000時,再次執(zhí)行左移操作,a 中的1就溢出了,因此a的值變?yōu)?code>0000 0000,此時我們需要加一個判斷,使a再次恢復為0000 0001
C語言中,if條件判斷使用方式如下

if(判斷條件) { //語句 }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

當判斷條件為真時,執(zhí)行{ }中的語句。
至此,流水燈代碼可改成如下形式:

#include <reg52.h>

//延時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;      //則恢復
  }
  //循環(huán)點亮led燈
  P2 = a;
  a = a<<1;
  delay1s();
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多