第一章(1.2—跑馬燈的實(shí)現(xiàn))

實(shí)物制作視頻教程:
http://v.youku.com/v_show/id_XMzIxNDkzNTYxMg==.html?spm=a2hzp.8244740.0.0
這次的實(shí)物電路是接著上一節(jié)的電路制作的艰毒,希望看過第一節(jié)的讀者沒有丟棄之前的電路板浮驳,若你是第一次看到本視頻,點(diǎn)此可閱讀前一節(jié)內(nèi)容选脊。

如果你的計(jì)算機(jī)無法編譯我提供的工程文件澎怒,你需要看下面的視頻教程
Keil軟件添加STC單片機(jī)并創(chuàng)建工程視頻教程

原理圖褒搔、源代碼、元件清單等資料下載 戳我下載

1.2.1 單片機(jī)準(zhǔn)雙向口的電器特性

STC15系列單片機(jī)IO口默認(rèn)工作在準(zhǔn)雙向口模式喷面,與STC89系列單片機(jī)不同星瘾,STC89系列單片機(jī)的P0端口默認(rèn)為開漏模式。STC15系列單片機(jī)準(zhǔn)雙向口模式的拉電流為150μA~150μA惧辈,灌電流為20mA琳状。
單片機(jī)I/O口作為輸出使用時(shí),可由軟件控制輸出0或1盒齿,通常稱之為邏輯“0”和邏輯“1”念逞,當(dāng)輸出邏輯“0”時(shí),可用萬用表測得單片機(jī)IO口電壓為0V边翁,當(dāng)輸出邏輯“1”時(shí)翎承,萬用表測得單片機(jī)IO口電壓為5V或3.3v(3.3v單片機(jī))。
注:實(shí)際上邏輯“0”和邏輯“1”測得電壓與本文的理論值有所誤差符匾,邏輯“0”通常測得的電壓并不是絕對0V叨咖,但通常都小于0.1V。邏輯“1”測得的電壓會(huì)隨著工作電壓不同而變化啊胶。
原理圖中D1至D8八只發(fā)光二極管的負(fù)極與單片機(jī)P0端口的P0.0至P0.7一一對應(yīng)甸各,所有發(fā)光二極管均串聯(lián)了一只100歐姆的電阻。大多數(shù)發(fā)光二極管的工作電壓在1.8 -3.2V之間焰坪。在實(shí)際制作過程中趣倾,讀者根據(jù)選用的二極管工作電壓選擇100至500歐姆的電阻。
所有LED的陽極串聯(lián)電阻后琳彩,并聯(lián)到5V電源處誊酌,利用發(fā)光二極管單向?qū)ǖ奶匦圆看眨?dāng)單片機(jī)IO口的輸出邏輯“0”時(shí),LED正負(fù)極兩端的電勢差大于導(dǎo)通電壓時(shí)碧浊,LED開始發(fā)光工作涂邀。
通過編程,依次控制P0組端口每個(gè)I/O的邏輯輸出箱锐,達(dá)到跑馬燈效果比勉。
思考:本原理圖中的LED接法稱之為“共陽極”接法,共陰極接法應(yīng)該如何設(shè)計(jì)電路驹止?

1.2.2 控制邏輯的實(shí)現(xiàn)

大到機(jī)器人浩聋,小到傳感器,都離不開單片機(jī)的I/O口操作臊恋,跑馬燈就是單片機(jī)I/O口的入門課衣洁。STC系列單片機(jī)可通過如下指令操作某一I/O口。

P00 = 0;        //P0.0端口輸出邏輯“0”
P01 = 1;        // P0.1端口輸出邏輯“1”

用同樣的方法抖仅,可操作其他組端口:

P20 = 0;        //P2.0端口輸出邏輯“0”
P31 = 1;        //P3.1端口輸出邏輯“1”
P41 = 1;        //P4.1端口輸出邏輯“1”

我們可以這樣操作I/O口坊夫,是因?yàn)閱纹瑱C(jī)的頭文件中定義好了這些內(nèi)容,在STC15F2K60S2.h頭文件中撤卢,部分定義如下:

sfr P0          =   0x80;  
sbit P00        =   P0^0;
sbit P01        =   P0^1;
sbit P02        =   P0^2;
sbit P03        =   P0^3;
sbit P04        =   P0^4;
sbit P05        =   P0^5;
sbit P06        =   P0^6;
sbit P07        =   P0^7;
sfr P1          =   0x90;   
sbit P10        =   P1^0;
sbit P11        =   P1^1;
sbit P12        =   P1^2;
sbit P13        =   P1^3;
sbit P14        =   P1^4;
sbit P15        =   P1^5;
sbit P16        =   P1^6;
sbit P17        =   P1^7;

也可以通過下面的方法實(shí)現(xiàn)I/O口的輸出控制环凿。

P0^0 = 0;
P1^1 = 1;   
P2^3 = 1;

在實(shí)際的項(xiàng)目開發(fā)中,為了提高代碼的閱讀性及可維護(hù)性放吩,經(jīng)常需要使用“sbit”位定義從新定義IO口智听,如下面的代碼所示。

#include"STC15F2K60S2.h"
sbit led0 = P0^0;
void main()
{
    led0 = 1; 
    led0 = 0;  
}

led0 = 1;等價(jià)于P0^0 = 0;P00 = 0;這樣設(shè)計(jì)程序的好處是渡紫,一旦硬件需要做出修改到推,只需要在程序開頭修改led0所對應(yīng)的IO口即可。
跑馬燈實(shí)際上就是控制8個(gè)IO口的邏輯輸出惕澎,在控制邏輯上可理解為:

流程圖

根據(jù)上面的流程圖环肘,可設(shè)計(jì)較為簡單的程序:

程序C1-2-1

#include"STC15F2K60S2.h"
#include"intrins.h"

sbit led1 = P0^0; 
sbit led2 = P0^1;   
sbit led3 = P0^2;   
sbit led4 = P0^3;   
sbit led5 = P0^4;   
sbit led6 = P0^5;   
sbit led7 = P0^6;   
sbit led8 = P0^7; 
        
void Delay300ms()       //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 13;
    j = 156;
    k = 83;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}


void main(void)
{
    
    while(1)
    {
        led1 = 0;
        Delay300ms();
        led1 = 1;

        led2 = 0;
        Delay300ms();
        led2 = 1;

        led3 = 0;
        Delay300ms();   
        led3 = 1;

        led4 = 0;
        Delay300ms();
        led4 = 1;

        led5 = 0;
        Delay300ms();
        led5 = 1;

        led6 = 0;
        Delay300ms();
        led6 = 1;

        led7 = 0;
        Delay300ms();
        led7 = 1;

        led8 = 0;
        Delay300ms();
        led8 = 1;
    }
}

除了前文中操作I/O口的方法,還可以直接操作一組I/O口集灌,示例代碼:

P0 = 0x01;  //P0^0輸出1,P0^1至P0^7輸出0
P0 = 0xFF;  //P0^0至P0^7全部輸出1

這種寫法的優(yōu)點(diǎn)在于一次性可操作一組端口的8個(gè)I/O复哆,1字節(jié)十六進(jìn)制長度是8位欣喧,與P0口的8個(gè)I/O口相對應(yīng),對應(yīng)關(guān)系如表1-2-1所示梯找。


表1-2-1

由表1-2-1可知唆阿,只需要改變P0端口的賦值,即可實(shí)現(xiàn)跑馬燈效果锈锤,完整代碼如下驯鳖。

程序代碼C1-2-2

#include"STC15F2K60S2.h"
#include"intrins.h"
        
void Delay300ms()       //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 13;
    j = 156;
    k = 83;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void main(void)
{
    while(1)
    {           
        P0 = 0xFE;  
        Delay300ms();
        P0 = 0xFD;  
        Delay300ms();   
        P0 = 0xFB;  
        Delay300ms();
        P0 = 0xF7;  
        Delay300ms();   
        P0 = 0xEF;  
        Delay300ms();
        P0 = 0xDF;  
        Delay300ms();   
        P0 = 0xBF;  
        Delay300ms();
        P0 = 0x7F;  
        Delay300ms();       
    }
}

1.2.3代碼優(yōu)化

代碼C1-2-1與代碼C1-2-2可以很直觀的讓程序閱讀者讀懂代碼含義闲询,但這兩種寫法都顯得過于臃腫。下面介紹2種方式優(yōu)化上述代碼浅辙。

通過觀察程序C1-2-2扭弧,可發(fā)現(xiàn)P0端口每次賦值是有規(guī)律的,對于才接觸單片機(jī)的讀者记舆,可能難以發(fā)現(xiàn)十六進(jìn)制數(shù)的規(guī)律鸽捻,轉(zhuǎn)換為二進(jìn)制后,能較為容易的發(fā)現(xiàn)賦值規(guī)律泽腮,如表1-2-2所示御蒲。


表1-2-2

每次賦值都是前一次的數(shù)值左移一次,根據(jù)此規(guī)律诊赊,可以設(shè)計(jì)如下代碼:

程序C1-2-3

#include"STC15F2K60S2.h"
#include"intrins.h"
        
void Delay300ms()       //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 13;
    j = 156;
    k = 83;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void main(void)
{   
    unsigned char i,m;  

    while(1)
    {
        for(i=0,m=0xFE;i<8;i++)
        {           
            P0 = m; 
            m = m<<1;
            Delay300ms();       
        }

    }
}

主函數(shù)還可以這樣設(shè)計(jì)

void main(void)
{   
    unsigned char i;    

    while(1)
    {
        for(i=0;i<8;i++)
        {           
            P0 = 0xFE<<i;   
            Delay300ms();       
        }
    }
}

思考:兩種主函數(shù)對比厚满,能發(fā)現(xiàn)什么不同嗎?

將C-1-2-3.hex文件燒錄到單片機(jī)后碧磅,會(huì)發(fā)現(xiàn)顯示效果與視頻中的顯示效果二相同碘箍,并不是預(yù)期的顯示效果一。這是因?yàn)樾拢看螆?zhí)行左移指令后敲街,會(huì)自動(dòng)將數(shù)據(jù)最低位補(bǔ)“0”,如圖1-2-2所示严望。


圖1-2-2

由此可見多艇,直接使用左移指令,并不難達(dá)到預(yù)期效果像吻,當(dāng)然這種現(xiàn)實(shí)方式也值得學(xué)習(xí)峻黍。若想實(shí)現(xiàn)演示視頻中的第一種顯示效果,可以使用“循環(huán)移位”拨匆,如圖1-2-3所示姆涩。


圖1-2-3

使用循環(huán)移位后,最高位多出的“1”不會(huì)被丟掉惭每,而是“移動(dòng)”到數(shù)據(jù)的最低位骨饿。若使用51匯編,可使用循環(huán)移位指令(RL 循環(huán)左移)實(shí)現(xiàn)台腥,雖然Keil Cx51編譯器完整的實(shí)現(xiàn)了ANSI C標(biāo)準(zhǔn)宏赘,但ANSI C并不支持類似匯編中循環(huán)移位指令、布爾跳轉(zhuǎn)指令(JBC)黎侈、空操作等指令察署。為了讓用戶在使用C語言編程時(shí)可以使用一些匯編語言的操作,Cx51編譯器提供了INTRINS.H庫峻汉,添加INTRINS.H庫后贴汪,可以像匯編那樣通過循環(huán)移位指令設(shè)計(jì)跑馬燈程序脐往,代碼如下。

程序C1-2-4

#include"STC15F2K60S2.h"
#include"intrins.h"
        
void Delay300ms()       //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 13;
    j = 156;
    k = 83;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void main(void)
{   
    unsigned char i,m=0xFE; 

    while(1)
    {
        for(i=0;i<8;i++)
        {           
            P0 = m;
            m = _crol_(m,1); //循環(huán)左移一次
            Delay300ms();       
        }
    }
}

本程序中使用的_crol_用于無符號字符型(unsigned char)扳埂,INTRINS.H還包含支持其他類型數(shù)據(jù)類型的循環(huán)移位操作业簿,如表1-2-3所示。

表1-2-3

網(wǎng)絡(luò)學(xué)習(xí)以下詞條聂喇,將有助于理解本節(jié)內(nèi)容辖源。

邏輯電平、拉電流希太、灌電流克饶、發(fā)光二極管特性

下節(jié)預(yù)告:延時(shí)函數(shù)、系統(tǒng)時(shí)鐘

作者水平有限誊辉,編寫過程中難免出現(xiàn)不當(dāng)之處矾湃,還望讀者諸君不吝賜教,或許您有好的建議堕澄,歡迎與我聯(lián)系QQ:136678431邀跃,作者將報(bào)以實(shí)質(zhì)性獎(jiǎng)勵(lì)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛙紫,一起剝皮案震驚了整個(gè)濱河市拍屑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坑傅,老刑警劉巖僵驰,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唁毒,居然都是意外死亡蒜茴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門浆西,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粉私,“玉大人,你說我怎么就攤上這事近零∨岛耍” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵久信,是天一觀的道長猪瞬。 經(jīng)常有香客問我,道長入篮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任幌甘,我火速辦了婚禮潮售,結(jié)果婚禮上痊项,老公的妹妹穿的比我還像新娘。我一直安慰自己酥诽,他們只是感情好鞍泉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肮帐,像睡著了一般咖驮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上训枢,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天托修,我揣著相機(jī)與錄音,去河邊找鬼恒界。 笑死睦刃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的十酣。 我是一名探鬼主播涩拙,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼耸采!你這毒婦竟也來了兴泥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤虾宇,失蹤者是張志新(化名)和其女友劉穎搓彻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體文留,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡好唯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了燥翅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骑篙。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖森书,靈堂內(nèi)的尸體忽然破棺而出靶端,到底是詐尸還是另有隱情,我是刑警寧澤凛膏,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布杨名,位于F島的核電站,受9級特大地震影響猖毫,放射性物質(zhì)發(fā)生泄漏台谍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一吁断、第九天 我趴在偏房一處隱蔽的房頂上張望趁蕊。 院中可真熱鬧坞生,春花似錦、人聲如沸掷伙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽任柜。三九已至卒废,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宙地,已是汗流浹背摔认。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绸栅,地道東北人级野。 一個(gè)月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像粹胯,于是被迫代替她去往敵國和親蓖柔。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容