久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 52246|回復: 35
打印 上一主題 下一主題
收起左側

第4章 C語言基礎以及流水燈的實現

  [復制鏈接]
跳轉到指定樓層
樓主
ID:1 發表于 2013-6-6 06:42 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

C語言,沒接觸過計算機編程語言的人會把它看的很神秘,感覺非常的難,而在我看來,C語言的邏輯和運算,就是小學水平,所以大家不要怕它,我盡可能的從小學數學邏輯方式帶著大家學習C語言。

1.1 二進制、十進制和十六進制

看似很簡單的東西,但是從同學們學習視頻的情況來看,很多同學不能徹底明白。這里先簡單介紹一些注意事項,然后還是從實驗中講解會比較深刻。

1、十進制就不多說了,逢十進位,一個位有十個值:09我們的生活中到處都是它的身影。二進制就是逢二進位,它的一個位只有兩個值:01,但它卻實現計算機系統的最基本的理論基礎,計算機(包括單片機)芯片是基于成萬上億個的開關管組合而成的,他們每一個都只能有開和關兩種狀態,再難找出第三個狀態了(不要辯解半開半關這個狀態,它是不穩定態,是極力避免的),所以他們只能對應于二進制的10兩個值,而沒有234……,理解二進制對于理解計算機的本質很有幫助。書寫二進制數據時需加前綴0b,每一位的值只能是01十六進制就是把4個二進制位組合為一位來表示,于是它的每一位有0b00000b111116個值,用09再加上AF(或af)表示,那么它自然就是逢十六進位了,它本質上同二進制是一樣的,是二進制的一種縮寫形式,也是我們程序編寫中常用的形式。書寫十六進制數據時需加前綴0x下表是三種進制之間的對應關系

十進制

二進制

十六進制

0

0b0

0x00

1

0b1

0x01

2

0b10

0x02

3

0b11

0x03

4

0b100

0x04

5

0b101

0x05

6

0b110

0x06

7

0b111

0x07

8

0b1000

0x08

9

0b1001

0x09

10

0b1010

0x0A

11

0b1011

0x0B

12

0b1100

0x0C

13

0b1101

0x0D

14

0b1110

0x0E

15

0b1111

0x0F

16

0b10000

0x10

17

0b10001

0x11

18

0b10010

0x12

……

……

……

4-1 進制轉換

2、對于二進制來說,8位二進制我們稱之為一個字節,二進制的表達范圍值是從0b000000000b11111111,而我們程序中用十六進制表示的時候就是從0x000xFF,這里教大家一個二進制轉換十進制和十六進制的方法,二進制4位一組,遵循8,4,2,1的規律比如 1010,那么從最高位開始算,數字大小是8*1+4*0+2*1+1*0 = 10,那么十進制就是10,十六進制就是0xA。尤其二進制轉十六進制的時候,十六進制一位剛好是和二進制的4位相互對應的,這些大家不需要強行記憶,用幾次就熟練了。

3、對于進制來說,只是數據的表現形式,而數據的大小不會因為進制表現形式不同而不同,比如二進制的0b1十進制的1十六進制的0x01他們本質上數值大小相等的同一個數據。我們在進行C語言編程的時候,我們只寫十進制和十六進制,那么不帶0x的就是十進制,帶了0x符號的就是十六進制。

1.2 C語言變量類型和范圍

什么是變量?變量自然和常量是相對的。常量比如是123......等固定的數字,而量,和我們小學學的x是一個概念,我們可以讓1,也可以讓2,我們想讓是幾是我們程序說算的。

那么我們小學學的數學里邊,有這么幾類,正數、負數、整數和小數。在C語言里,名字和我們數學里學的不一樣外,還對數據大小進行了限制。這個地方有一點復雜的是,在C51里邊的數據范圍和其他編程環境還不完全一樣,因此我們下邊的這個圖,僅僅代表的是C51,其他編程環境可能不一樣,大家知道有這回事就可以了。C語言的關鍵字較多語法有些嚴謹我們不必死記硬背只需理解了,用的時候再打開http://www.zg4o1577.cn/mcuteach/150.html 查閱即可.

C語言的數據基本類型分為整型、字符型以及浮點型,如圖4-1

圖片

4-1 C語言數據類型

4-1中,三種基本類型,每個基本類型又包含了兩個類型。其中字符型和整型,除了有一定的數據大小范圍之外,只能表達整數。而unsigned型的又只能表達正數,要表達負數必須用signed型,編寫程序的時候,signed可以省略。表達小數,必須用浮點型。

比如上節課最后給的閃爍小燈的程序,我們用的是unsigned int i = 0;這個地方i的范圍就是0~65535,我們for語句的寫法,如果那個30000改成70000的話,for(i=0;i<70000;i++);大家會發現小燈會一直亮,而不是閃爍了,那理解這個問題,當然我們要來了解for語句的用法了。 

這里有一個編程宗旨,就是能用小不用大。就是說定義能用1個字題的,就不定義成int,一方面節省RAM空間可以其他變量或者中間運算過程使用,另外一方面,占空間小程序運算速度也快一些。

1.3 for循環語句

for語句是我們今后編程的一個常用的語句,這個語句必須得學會其用法,他不僅僅可以用來做延時,還可以用來做一些循環運算。for語句的一般形式如下:

        for(表達式1表達式2表達式3)

        (需要執行的語句);

其執行過程是表達式1首先執行且只執行一次然后執行表達式2,通常都是一個用于判定條件的表達式,如果表達式2條件成立,就執行(需要執行的語句);然后再執行表達式3再判斷表達式2,再執行表達式3.....一直到表達式2不成立,跳出循環往下執行。舉個例子:

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

        j++;

這里有一個符號++,這個符號表示加1的意思。假如j最開始初值是0,首先執行表達式1i=0,然后判斷i小于2這個條件成立,就執行一次j++j的值就是1了,然后經過表達式3后,i的值也變成1了,再判斷條件2,還是符合,j再加一次,j變成2了,表達式3i也變成2了,再判斷條件2,發現2<2這個條件不成立了,所以就不會再執行j++這個語句了。所以執行完畢后,j的值就是2。   

for語句除了這種標準用法,還有幾種特殊用法,我們上節課的閃爍小燈對for語句的用法for(i=0; i<30000; i++) ;我們沒有加(需要執行的語句),沒有加的話,就是什么都不操作。但是什么都不操作的話,我們這個for語句循環判斷了30000次,程序執行是會用掉時間的,所以就起到了延時的作用。比如我們把30000改成20000,會發現燈的閃爍速度加快了,因為我們延時時間短了,當然,我們該成40000后會發現,閃爍慢了。但是有一點特別注意,C語言的延時時間是不能通過程序看出來的,也不會成比例,比如假如我們這個for循環里邊的表達式2使用30000的時候延時3秒的話,那么延時40000的時候,可能不會是4秒,那如何看實際延時時間呢,一會我再教大家。

還有一種寫法for( ; ; ),這樣寫后,這個for循環就變成了死循環了,就不停的執行(需要執行的語句),和我們前邊講的while(1)的意思是一樣的。那while這個語法是如何用的呢?

1.4 while循環語句

在我們單片機C語言編程的時候,每個程序我們都會固定的加一句while(1),這條語句就可以起到死循環的作用。對于while語句來說,他的一般形式是:

     While (表達式)

     {

        循環體語句;

     } 

C語言里,通常表達式符合條件,我們叫做真,不符合條件,叫做假。比如前邊i<30000,當i等于0的時候,那這個條件成立,就是真,如果i大于30000的時候,條件不成立,叫做假。

while(表達式)這個括號里的表達式,為真的時候,就會執行循環體語句,當為假的時候,就不執行。在這里先不舉例,后邊遇到再詳細說

還有另外一種情況,就是我們C語言里邊,除了表達式外,還有常數,習慣上,我們非0的常數都認為是真,只有0認為是假,所以我們程序中加了while(1),這個數字1,可以改成2,3,4......等等都可以,都是一個死循環,不停的執行循環體的語句,但是如果把這個數字改成0,那么就不會執行循環體的語句了。

1.5 函數的簡單介紹

函數定義的一般形式如下:

    函數值類型  函數名 (形式參數列表)

    {

        函數體

    }

1、函數值類型,就是函數返回值的類型。在我們后邊程序使用中,會有很多函數中有return x這個東西,這個返回值也就是函數本身的類型。還有一種情況,就是這個函數只執行操作,不需要返回任何值,那么這個時候的類型就是空類型void,這個void按道理來說是可以省略的,但是一旦省略,Keil軟件會報一個警告,所以我們通常也不省。

2、函數名。可以是任何合法的標示符,但是不能與其他函數或者變量重名,也不能是關鍵字。什么是關鍵字,后邊我們慢慢接觸,比如char這類,都是關鍵字,是我們程序中具備特殊功能的標志符,這種東西不可以命名函數。

3、形式參數列表,我們也叫做形參,這個是函數調用的時候,相互傳遞數據用的。有的函數,我們不需要傳遞參數,那么可以用void來替代,void同樣可以省略,但是那個括號是不能省略的。

4、函數體。函數體包含了聲明語句部分和執行語句部分。聲明語句部分主要用于聲明函數內部所使用的變量,執行語句部分主要是一些函數需要執行的語句。特別注意,所有的聲明語句部分必須放在執行語句之前,否則編譯的時候會報錯。

5、一個工程文件必須有且僅能有一個main函數,程序執行的時候,都是從main函數開始的。

6、關于形參和實參的概念,我們后邊再總結,如果遇到程序里有,大家再跟著抄一段時間。先用,后講解,這樣更有利于理解。

我們再來回顧一下我們上節課閃爍LED程序部分

void  main()               //void即函數類型          

{

    unsigned int i = 0;   //定義一個無符號整數i,變量范圍是0~65535

                            //并且賦一個初值0

    ENLED = 0;             //先定義變量i,后寫執行部分

    ADDR0 = 0;

    ADDR1 = 1;

    ADDR2 = 1;

    ADDR3 = 1;             //74HC138開啟三極管   

 

    while(1)               //程序死循環  

    {

           LED = 0;                //點亮小燈

           for(i=0;i<30000;i++);  //for延時操作

           LED = 1;                //熄滅小燈

           for(i=0;i<30000;i++);  //for延時操作

    }

}

1.6 Keil軟件延時

    C語言常用的延時辦法,有以下4

 

圖片

 

 

4-2 C語言延時

4-2是我們編程語言常用的4種延時方法,其中兩種非精確延時,兩種精確一些的延時。for語句和while語句都可以通過改變i的范圍值來改變延時時間,但是C語言的時間都是不能通過程序看出來的。

精確延時有兩個方法,一個方法是用定時器來延時,這個方法我們后邊課程要詳細介紹,定時器是單片機的一個重點。另外一個就是用庫函數_nop_();,一個NOP的時間是一個機器周期的時間,這個后邊也要介紹。

非精確延時,只是在我們做一些簡單的比如小燈閃爍,流水燈等簡單實驗中使用,而實際做實際開發程序中其實這種非精確延時用的極少,這里我們只是做演示功能使用。

好了,介紹完了,我們就要實戰了。上節課的LED小燈閃爍的程序,我們用的延時方式是for(i=0;i<30000;i++);大家如果把這里的i改成100,下載進入單片機,會發現小燈一直亮,而不是閃爍狀態,現在大家都把這個程序改一下,都改成100,然后下載觀察一下現象再繼續。

觀察完了,毫無疑問,實際現象和我提到的理論是相符合的,這是為什么呢?這里介紹一個常識。我們人的肉眼對閃爍的光線有一個最低分辨能力,通常情況下當閃爍的頻率高于50Hz時,我們看到的信號就是常亮的。延時的時間低于20ms的時候,我們的肉眼是分辨不出來小燈在閃爍的,可能最多看到的是小燈亮暗稍微變化了一下。要想清楚的看到小燈閃爍,延時的值必須大一點,大到什么程度呢,不同的亮度的燈不完全一樣,大家可以自己做實驗。

那么如何觀察延時有多長時間呢?大家鼠標點KeilProject-->Options for Target Target1,或點Target1右側圖標圖片,進入設置選項,如圖4-3所示

圖片

4-3 Options for Target

首先我們打開Target這個選項卡,找到里邊的Xtal(MHz)這個位置,這是填寫我們進行模擬時間的晶振選項,從我們原理圖以及板子上都可以看到,我們單片機所配的晶振是11.0592MHz,所以這個地方我們要填上11.0592。然后找到Debug這個選項,選擇左側的Use Simulator,然后點擊最下邊的OK就可以了,如圖4-4所示。

圖片

4-4 Debug配置信息

點擊Debug菜單里的Start/Stop Debug Session,或者鼠標點做左側的這個Debug圖標圖片,會進入一個新的頁面,如圖4-5所示。

圖片

4-5 Debug窗口顯示

最左側那一欄是單片機的一些寄存器和系統信息,最上邊那一欄是KeilC語言轉換成匯編的代碼,下邊就是我們C語言的程序,還有各種窗口都可以打開,在view菜單可以打開或者關閉我們的各種窗口。這節課我們只關心我們需要的窗口,其他窗口用到再說。那么有時候我們覺得這種分布不是特別的好,所以我們想改變一下窗口分布怎么辦呢?比如Disassembly(匯編)窗口,我們先用鼠標拖動它,然后中間會出現一個方向符號,再用鼠標點那個方向符號,他就給我們分布了,如圖4-6所示。

圖片

4-6 Keil窗口移動()

我們點擊最右邊的那個箭頭,然后窗口變化成如4-7圖所示。或者我們如果用不到匯編的程序,也可以直接關掉。

圖片

4-7所示 Keil窗口移動()

細心的同學會看到在C語言的程序里有個黃色的箭頭,這個箭頭代表的就是這個程序當前運行的位置,在這個Debug里邊,我們可以看到我們的程序運行的過程。在左上角有這三個圖標圖片,第一個是復位,點擊一下之后,程序就會跑到最開始的位置運行,第二個圖標是全速運行圖標,點擊一下程序就會全速運行跑起來,第三個圖標是停止圖標,當程序全速運行跑起來后,我們可以通過點擊第三個圖標來讓程序停止,觀察程序運行到哪里了。點擊一下復位后,我們會發現C語言程序左側有的灰色或者綠色,有的地方還是保持原來的白色,我們可以在我們灰色的位置雙擊鼠標設置斷點,就是比如程序一共20行,在第十行設置斷點后,點全速運行,程序就會運行到第十行停止,方便我們觀察運行到這個地方的情況。

同學們會發現,有的位置可以設置斷點,有的地方不可以設置斷點,這是為什么呢?Keil軟件本身具備優化我們程序的功能,如果大家想在所有的位置設置斷點,可以把優化選項設置到0位置,就是程序不進行優化。如圖4-8所示。


 
圖片
 

4-8 優化選項設置

這節課我們重點是看看C語言代碼的運行時間,在最左側的register那個框內,有一個sec選項,這個選項就是單片機運行時間的統計選項,大家點一下復位按鈕,會發現這個sec變成了0,然后我們在LED = 0; 這一句加一個斷點,在LED = 1;這個位置加一個斷點,我們點擊全速運行按鈕,會直接停留在LED = 0;我們會看到我們的時間變化成0.000197秒,如圖4-9所示。

圖片

4-9 斷點設置

    我們再點一下全速運行,會發現sec變成了0.07530650秒,那么這樣一個for循環的時間大概有75ms左右,我們也可以通過改變30000這個數字來改變這個間隔時間。當然了,大家要注意i的變量范圍,你如果寫成了大于65535的值以后,程序就會一直運行不下去了,因為i無論如何變化,都不會大于這個值,如果要大于這個值正常運行,必須改變i定義的類型了。后邊如果我們要求看一段程序運行多長時間,都可以通過這種方式來看。

1.7 流水燈程序

我們前邊學了點亮LED小燈,然后又學了LED小燈閃爍,下邊我們要進一步了解一下如何讓8個小燈依次一個一個點亮,流動起來。

圖片

4-10 LED小燈電路圖

通過前面的課程,我們可以了解到控制引腳P0.0通過了74HC245控制DB0P0.1控制DB1......P0.7控制DB7。我們還學到一個字節是8位,我們如果寫一個P0,就代表了P0.0P0.7的共8位。比如我們寫P0 = 0xFE;轉換成二進制就是0b11111110,所以點亮LED小燈的程序,實際上我們可以改成另外一種寫法,如下所示。

#include <reg52.h>

sbit  ADDR0 = P1^0;

sbit  ADDR1 = P1^1;

sbit  ADDR2 = P1^2;

sbit  ADDR3 = P1^3;

sbit  ENLED = P1^4;

 

void  main()                

{

    ENLED = 0;

    ADDR0 = 0;

    ADDR1 = 1;

    ADDR2 = 1;

    ADDR3 = 1;            //74HC138開啟三極管    

 

    P0 = 0xFE;

    while(1);             //程序停止在這里 

}

通過上邊這個程序我們可以看出來,可以通過P0來控制所有的8LED小燈的亮和滅。我們下邊要進行依次亮和滅,怎么辦呢?從這里就可以得到方法了,如果想讓單片機流水燈流動起來,依次要實現的結果是:0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F

在我們的C語言當中,有一個移位操作,其中<<代表的是左移,>>代表的是右移。比如a = 0x01 << 1就是的結果等于0x01左移一位。大家注意,移位都是指二進制移位,那么移位完了,本來在第0位的1移動到了第一位上,移動完了低位是補0的。所以a的值最終是等于0x02

還要學習另外一個運算符~,這個符號是按位取反的意思,同樣,按位取反也是針對二進制而言。比如a = ~(0x01)0x01的二進制是0b00000001,按位取反是0b11111110,那么a的值就是0xFE了。

學會了這兩個符號后,那么我們就可以把流水燈的程序寫出來,先把程序貼上。

#include <reg52.h>

sbit  ADDR0 = P1^0;

sbit  ADDR1 = P1^1;

sbit  ADDR2 = P1^2;

sbit  ADDR3 = P1^3;

sbit  ENLED = P1^4;

 

void  main()

{

    unsigned char j = 0;

    unsigned int  i = 0;

 

    ENLED = 0;

    ADDR0 = 0;

    ADDR1 = 1;

    ADDR2 = 1;

    ADDR3 = 1;              //74HC138開啟三極管Q16           

    while(1)                //程序死循環  

    {

        P0 = ~(0x01 << j++);     //P0等于1左移j位,并且j++

        for(i=0; i<20000; i++);  //延時

        if(j == 8)                //如果j等于8,重新給j賦值0

        {

            j = 0;

        }

     }

}

這里我只講兩種情況,當j等于0的時候,1左移0位還是1,那么寫成二進制后就是0b00000001,對這個數字按位取反就是0b11111110,亮的是最右邊的小燈。當j等于7的時候,1左移7位就是0b10000000,按位取反0b01111111,亮的是最左邊的小燈。中間過程大家自己分析一下。

流水燈結束后,關于小燈的講解,我們暫時告一段落,后邊還有小燈的高級用法,我們到時候再詳細講解

1.8 作業

1、熟練掌握二進制、十進制和十六進制的轉換方法。

2、掌握C語言變量類型和范圍,forwhile等基本語句的用法。

3、了解函數的基本結構,能夠獨立進入程序Debug,多多動手操作,熟練Keil軟件環境的一些基本操作。

4、將流水燈左移理解透徹后,獨立完成流水燈右移操作以及流水燈先左移后右移等簡單的花樣操作。

 

 

 


上一課:第三章 硬件基礎知識學習
下一課:第五章 定時器和數碼管

評分

參與人數 2黑幣 +13 收起 理由
莫子棟 + 8 很給力!
禹1850 + 5 很給力!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏13 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:60906 發表于 2014-4-20 17:29 | 只看該作者
繼續學習!!!
回復

使用道具 舉報

板凳
ID:61750 發表于 2014-5-13 00:06 | 只看該作者
不知道這輩子能不能到樓主這水平,繼續學習
回復

使用道具 舉報

地板
ID:61153 發表于 2014-8-20 21:48 | 只看該作者
老大,我正在學習這個單 片機C語言,我也沒有基礎,好像有點難哦,你有沒有C語言方面比較好 的視頻資料呀?
回復

使用道具 舉報

5#
ID:66128 發表于 2014-9-13 15:21 來自手機 | 只看該作者
又學到了一秒方法
回復

使用道具 舉報

6#
ID:67954 發表于 2014-12-12 20:38 | 只看該作者
學習中,贊幾個先
回復

使用道具 舉報

7#
ID:73030 發表于 2015-1-30 23:55 | 只看該作者
受益匪淺,感謝樓主。
回復

使用道具 舉報

8#
ID:80108 發表于 2015-5-16 15:37 | 只看該作者
每一個章節都要認真學習!
回復

使用道具 舉報

9#
ID:88566 發表于 2015-8-20 11:14 | 只看該作者
又學完一課,慢慢,謝謝
回復

使用道具 舉報

10#
ID:89012 發表于 2015-8-28 17:29 | 只看該作者
1.7節流水燈程序,實現燈依次亮、滅的程序(第二部分程序)中為什么j要定義為無符號字符型,不是應該為無符號整型嗎?請前輩指教,謝謝!
回復

使用道具 舉報

11#
ID:93531 發表于 2015-11-7 09:46 | 只看該作者
怎么都覺得C比匯編簡單多了...
回復

使用道具 舉報

12#
ID:114291 發表于 2016-4-24 21:58 | 只看該作者
我要繼續學習
回復

使用道具 舉報

13#
ID:120460 發表于 2016-5-21 12:12 | 只看該作者
想通過語音控制這流水燈,要怎么控制他跳出這死循環,或者進入這死循環?
回復

使用道具 舉報

14#
ID:151661 發表于 2016-12-26 15:03 來自手機 | 只看該作者
好好學習,天天向上。
回復

使用道具 舉報

15#
ID:162190 發表于 2017-2-16 17:00 | 只看該作者
好好學習,天天向上
回復

使用道具 舉報

16#
ID:164574 發表于 2017-3-22 16:02 | 只看該作者
講德挺詳細的
回復

使用道具 舉報

17#
ID:193946 發表于 2017-4-26 19:08 | 只看該作者
樓主  P0&nbsp;=&nbsp;~(0x01&nbsp;<<&nbsp;j++);&nbsp;這句是不是應該把P0改成P1....
回復

使用道具 舉報

18#
ID:211251 發表于 2017-6-15 21:45 | 只看該作者
挺好的,受教了
回復

使用道具 舉報

19#
ID:155764 發表于 2017-10-22 15:10 | 只看該作者
贊一個!
回復

使用道具 舉報

20#
ID:155764 發表于 2017-10-25 20:50 | 只看該作者
絕世好貼!
回復

使用道具 舉報

21#
ID:243040 發表于 2017-10-26 10:34 | 只看該作者
講的很詳細謝謝
回復

使用道具 舉報

22#
ID:260785 發表于 2017-12-20 16:40 | 只看該作者
絕世好貼!講的很詳細謝謝!辛苦了!!!!
回復

使用道具 舉報

23#
ID:269163 發表于 2017-12-30 13:02 | 只看該作者
帖子牛B啊。最通俗易懂的教程
回復

使用道具 舉報

24#
ID:314995 發表于 2018-4-24 00:08 | 只看該作者
在哪里能看到呀
回復

使用道具 舉報

25#
ID:315638 發表于 2018-4-24 21:03 | 只看該作者
很厲害,今日打卡!!
回復

使用道具 舉報

26#
ID:316044 發表于 2018-4-25 11:05 | 只看該作者
學習學習長知識
回復

使用道具 舉報

27#
ID:314979 發表于 2018-5-1 21:45 | 只看該作者
學習長的知識快
回復

使用道具 舉報

28#
ID:93625 發表于 2018-6-27 13:59 | 只看該作者
學習,感謝樓主
回復

使用道具 舉報

29#
ID:229981 發表于 2018-8-13 11:41 | 只看該作者
curry 發表于 2015-8-28 17:29
**** 作者被禁止或刪除 內容自動屏蔽 ****

我也覺得應該是unsigned int j = 0;
回復

使用道具 舉報

30#
ID:229981 發表于 2018-8-13 12:46 | 只看該作者
/***直接從keil里復制過來的漢字全是亂碼,估計從這里復制回去也是***/
/**剛寫了一個流水,延時時間大概在1秒多一點,可以通過修改DELAY()括號里的值來改變延時時間**/
/***依次點亮一顆燈的流水燈----Heron***/
#include <reg52.h>
sbit  ADDR0 = P1^0;
sbit  ADDR1 = P1^1;
sbit  ADDR2 = P1^2;
sbit  ADDR3 = P1^3;
sbit  ENLED = P1^4;

void DELAY(unsigned int k)        //循環次數 = k * 10000
{
        unsigned int a, b;
       
        for(a = 0; a < k; a++)
        {
                for(b = 0; b < 10000; b++);   //括號后邊直接分號就是自循環
        }
}

void  main()
{
   unsigned int i, j;
   i = j = 0;

   ENLED = 0;
   ADDR0 = 0;
   ADDR1 = 1;
   ADDR2 = 1;
   ADDR3 = 1;
       
        while(1)
        {
                for(i = 0; i < 8; i++)
                {
                        P0 = 0xFE<<i;         //0xFE = B11111110 ,每次點亮一顆燈
                        DELAY(20);            //調用延時函數,且k = 20
                }
        }
}
回復

使用道具 舉報

31#
ID:357877 發表于 2018-9-7 21:44 | 只看該作者
heron 發表于 2018-8-13 12:46
/***直接從keil里復制過來的漢字全是亂碼,估計從這里復制回去也是***/
/**剛寫了一個流水,延時時間大概在 ...

這個就是LED燈依次往左點亮嗎  能告訴我為什么樓主要用~按位取反嗎
回復

使用道具 舉報

32#
ID:288930 發表于 2019-1-29 10:26 | 只看該作者
謝謝分享!
回復

使用道具 舉報

33#
ID:615425 發表于 2019-9-25 21:00 來自手機 | 只看該作者
謝謝,學習中
回復

使用道具 舉報

34#
ID:815563 發表于 2020-10-28 16:20 | 只看該作者
要認真學習才能對得起師傅的教導與分享。
回復

使用道具 舉報

35#
ID:956549 發表于 2021-8-25 18:28 | 只看該作者
heron 發表于 2018-8-13 12:46
/***直接從keil里復制過來的漢字全是亂碼,估計從這里復制回去也是***/
/**剛寫了一個流水,延時時間大概在 ...

這應該不是每次點亮一個led吧
回復

使用道具 舉報

36#
ID:966468 發表于 2022-6-23 09:25 | 只看該作者
用心施教,要認真學習,好教程。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩欧美在线视频播放 | www.久| 粉嫩一区二区三区四区公司1 | 久久国产精99精产国高潮 | 亚洲综合网站 | 四虎影视1304t| 日韩av在线一区二区 | 先锋资源站 | 一级毛片视频在线 | 美女爽到呻吟久久久久 | 91久久北条麻妃一区二区三区 | gav成人免费播放视频 | 欧美日韩不卡合集视频 | 日本福利一区 | 欧美成人精品一区二区三区 | 国产精品国产精品国产专区不蜜 | 欧美日韩免费 | a级黄色毛片免费播放视频 国产精品视频在线观看 | 欧美网站一区二区 | 欧美大片黄| 国产欧美精品一区二区色综合朱莉 | zzzwww在线看片免费 | 国产成人久久 | 99久久久久久99国产精品免 | 午夜视频在线观看视频 | av性色全交蜜桃成熟时 | 久久久免费少妇高潮毛片 | 国产激情| 亚洲欧美一区二区三区在线 | 日韩精品免费看 | 色婷婷国产精品综合在线观看 | 91精品一区二区三区久久久久 | av一区二区三区四区 | 亚洲一级av毛片 | 免费的色网站 | 国产精品视频久久久 | 国产99久久精品一区二区永久免费 | 91视频免费 | 2019天天操| 九九九久久国产免费 | 天天天天操 |