0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

聊聊流水燈的寫(xiě)法

單片機(jī)技術(shù)宅 ? 來(lái)源:?jiǎn)纹瑱C(jī)技術(shù)宅 ? 作者:?jiǎn)纹瑱C(jī)技術(shù)宅 ? 2021-03-02 15:52 ? 次閱讀

流水燈,學(xué)單片機(jī)時(shí),編程第一課的內(nèi)容,多少小伙伴的單片機(jī)之路都是從流水燈開(kāi)始的。那有沒(méi)有想過(guò),我們能用幾種方式來(lái)寫(xiě)流水燈,各有什么優(yōu)缺點(diǎn)呢?今天小代就來(lái)聊聊流水燈的寫(xiě)法。

硬件介紹:小代采用自己畫(huà)的STC15開(kāi)發(fā)板,8位LED接P0口,陽(yáng)極驅(qū)動(dòng),共陰連接方式,就這么多。

(實(shí)際測(cè)試時(shí)用的數(shù)碼管模擬,昨天剛接了線(xiàn),懶得再次重新接線(xiàn),直接用數(shù)碼管來(lái)代替LED,原理都一樣,能驗(yàn)證就好)

1.初學(xué)者入門(mén)法

直接上代碼看后再說(shuō)

#include"STC15.h"#defineu8unsignedchar#defineu16unsignedintvoid delay_ms(u16x);//ms延時(shí)函數(shù)void main(){u8led=0x01;u8i=0;P0M1=0x00;//STC15單片機(jī)把IO設(shè)為推挽輸出P0M0=0xff;P2M1=0x00;P2M0=0xff;P2=0xff;//數(shù)碼管位選驅(qū)動(dòng),硬件介紹上已經(jīng)說(shuō)明原因while(1){//①初學(xué)者常見(jiàn)delay延時(shí)方式流水燈led=0x01;for(i=0;i<8;i++){????????????P0=led;????????????delay_ms(1000);????????????led=led<<1;????????}?????}??????//while(1)?結(jié)束}//main結(jié)束 //************************************//功能:ms延時(shí)函數(shù)?//參數(shù):x--延時(shí)的時(shí)間長(zhǎng)短,x=1000約為1s 24M晶振//作者:小代//微信關(guān)注:?jiǎn)纹瑱C(jī)技術(shù)宅//************************************void delay_ms(u16?x){????u16?i,j,k;????for(k=0;k

一看代碼37行,太多了,仔細(xì)一看,注釋和空行占據(jù)了一大半,這樣一想就開(kāi)心多了。這個(gè)代碼沒(méi)有更多需要解釋的,采用最常見(jiàn)的,初學(xué)者最喜歡的方式,delay延時(shí)方式實(shí)現(xiàn),下面聊優(yōu)缺點(diǎn)。

優(yōu)點(diǎn):簡(jiǎn)單粗暴好理解,能看懂文字(字母)的都知道

缺點(diǎn):代碼執(zhí)行效率太低,太低,太低

程序流程圖如下圖所示,CPU更多的時(shí)間是花在“等待1s”上,效率太低,單純的這樣演示流水燈,那這個(gè)程序沒(méi)有任何問(wèn)題,當(dāng)在這個(gè)程序中再加入其它的程序,必然會(huì)出問(wèn)題,第一流水燈會(huì)被執(zhí)行慢了,第二,新加入的功能反應(yīng)會(huì)很慢,特別是一些實(shí)時(shí)性有要求的代碼。加到這里就會(huì)有問(wèn)題了。為了解決這些問(wèn)題,我們引出了第二種方式的流水燈。

2.記錄主程序執(zhí)行次數(shù)方式

還是先上代碼再聊

#include "STC15.h"

#define u8 unsigned char

#define u16 unsigned int

//************************************

//功能:主函數(shù)入口 main

//參數(shù):無(wú)

//作者:小代

//微信關(guān)注:?jiǎn)纹瑱C(jī)技術(shù)宅

//************************************

voidmain(){

u8 led=0x01;

u16main_cnt=0;

P0M1=0x00; //STC15單片機(jī)把IO設(shè)為推挽輸出

P0M0=0xff;

P2M1=0x00;

P2M0=0xff;

P2=0xff; //數(shù)碼管位選驅(qū)動(dòng),硬件介紹上已經(jīng)說(shuō)明原因

while(1){

//②主程序循環(huán)次數(shù)實(shí)現(xiàn)延時(shí)方式流水燈

main_cnt++; //主程序每運(yùn)行一次,main_cnt將會(huì)被加1

//通過(guò)if語(yǔ)句實(shí)現(xiàn)內(nèi)部代碼塊的運(yùn)行速率降低

//只有主程序循環(huán)60000此后,if語(yǔ)句內(nèi)的代碼塊才被執(zhí)行一次

//如若需要更低的執(zhí)行速率,可以采用兩層變量嵌套計(jì)數(shù)

P0=led;

if(main_cnt>60000){

main_cnt=0; //次數(shù)記錄清零,為下一次記錄準(zhǔn)備

if(led==0x80){

led=0x01;

}

else{

led=led<<1;

}

}

} //while(1) 結(jié)束

}

//main結(jié)束

還是40+行代碼,還是注釋+空行占據(jù)了一半左右。以上代碼最大的特點(diǎn)就是沒(méi)有之前執(zhí)行效率很低的delay函數(shù),也算是升級(jí)了吧。沒(méi)了delay延時(shí),那如何實(shí)現(xiàn)等待的呢?小代慢慢聊。

在while(1)循環(huán)里的第21行,只要主程序每運(yùn)行一次,21行就會(huì)對(duì)變量main_cnt加1,這個(gè)變量定義為16位無(wú)符號(hào)類(lèi)型,最大可以到65535,在此,小代記錄60000此后就去點(diǎn)亮下一個(gè)流水燈的LED,顯示效果比方法1的略快,以上注釋也說(shuō)了,如果單一變量記錄次數(shù)沒(méi)法滿(mǎn)足需要的等待時(shí)間,可以采用兩個(gè)變量嵌套記錄的方式。

通過(guò)這種方式點(diǎn)亮LED燈,真正的點(diǎn)燈程序段只有在主程序運(yùn)行60000后才會(huì)被運(yùn)行到一次。仔細(xì)看主程序里面,其實(shí)就只有一條語(yǔ)句,那就是對(duì)main_cnt做加1處理,完了每次都去判斷一下main_cnt有沒(méi)有到60000了,到了后才去處理LED點(diǎn)燈。下面聊聊優(yōu)缺點(diǎn)。

優(yōu)點(diǎn):程序簡(jiǎn)單,效率高

缺點(diǎn):點(diǎn)燈的速度會(huì)隨著主程序內(nèi)循環(huán)語(yǔ)句的增多而降低。

也就是說(shuō)如果主程序里增加了其他的運(yùn)行語(yǔ)句,那這里控制點(diǎn)燈的記錄次數(shù)值就不再是60000,需要減小,或者說(shuō)60000得到的效果就會(huì)讓流水燈變慢。程序流程圖如下圖

到這里,程序執(zhí)行效率問(wèn)題我們已經(jīng)解決了,在這程序基礎(chǔ)上加入其它代碼后,各個(gè)功能還是能運(yùn)行起來(lái),但是還是有問(wèn)題,流水燈的速度會(huì)改變,為解決這個(gè)問(wèn)題,小代引出了第三種方法。

3.定時(shí)器實(shí)現(xiàn)

說(shuō)到定時(shí)器,首先還得知道中斷的原理,但是,中斷和定時(shí)器,學(xué)單片機(jī)連這兩個(gè)知識(shí)點(diǎn)都沒(méi)學(xué)會(huì),那怎好意思說(shuō)你學(xué)過(guò)單片機(jī)。也就是說(shuō)中斷和定時(shí)器就像單片機(jī)驅(qū)動(dòng)IO口一樣的普通,一樣的簡(jiǎn)單,不要想的多復(fù)雜。還是先上代碼再聊。

#include "STC15.h"

#define u8 unsigned char

#define u16 unsigned int

voiddelay_ms(u16 x); //ms延時(shí)函數(shù)

voidTimer0Init(void); //2毫秒@24.000MHz

u16 timer0_cnt=0;

bit timer0_1s_flag=0;

//************************************

//功能:主函數(shù)入口 main

//參數(shù):無(wú)

//作者:小代

//微信關(guān)注:?jiǎn)纹瑱C(jī)技術(shù)宅

//************************************

voidmain(){

u8 led=0x01;

u16main_cnt=0;

P0M1=0x00; //STC15單片機(jī)把IO設(shè)為推挽輸出

P0M0=0xff;

P2M1=0x00;

P2M0=0xff;

P2=0xff; //數(shù)碼管位選驅(qū)動(dòng)

Timer0Init(); //定時(shí)器初始化

while(1){

//③通過(guò)定時(shí)器中斷控制流水燈效果

//主程序里只做LED的驅(qū)動(dòng)

//如果任務(wù)少,判斷標(biāo)志位置位都可以放到定時(shí)器中斷里

//這里統(tǒng)一放到了主循環(huán)里

P0=led;

if(timer0_1s_flag==1){

timer0_1s_flag=0; //清除標(biāo)志位

if(led==0x80){ //是否移動(dòng)了8次

led=0x01;

}

else{

led=led<<1;

}

}

}//while(1) 結(jié)束

}

//main結(jié)束

//************************************

//功能:定時(shí)器初始化函數(shù)

//參數(shù):無(wú)

//作者:小代

//微信關(guān)注:?jiǎn)纹瑱C(jī)技術(shù)宅

//************************************

voidTimer0Init(void) //2毫秒@24.000MHz

{

AUXR|=0x80; //定時(shí)器時(shí)鐘1T模式

TMOD&=0xF0; //設(shè)置定時(shí)器模式

TL0=0x80; //設(shè)置定時(shí)初值

TH0=0x44; //設(shè)置定時(shí)初值

TF0=0; //清除TF0標(biāo)志

TR0=1; //定時(shí)器0開(kāi)始計(jì)時(shí)

ET0=1; //開(kāi)中斷

EA=1;

}

//************************************

//功能:Timer0中斷函數(shù) 2ms中斷一次

//參數(shù):無(wú)

//作者:小代

//微信關(guān)注:?jiǎn)纹瑱C(jī)技術(shù)宅

//************************************

voidtimer0_int (void) interrupt 1 {

TF0=0;

timer0_cnt++;

if(timer0_cnt==500){

timer0_1s_flag=1;

timer0_cnt=0;

}

}

看到這,一看代碼量暴增,一下子就是原來(lái)的兩倍,其實(shí)更多的也還是注釋?zhuān)a量是有所增加,因?yàn)橛玫搅硕〞r(shí)器和中斷,需要對(duì)定時(shí)器進(jìn)行初始化,完了還需要一個(gè)中斷函數(shù)。在這個(gè)程序,定時(shí)T0每2ms中斷一次,進(jìn)入中斷后,中斷處理函數(shù)直接對(duì)timer0_cnt變量加1記錄,當(dāng)記錄500次后,說(shuō)明1s時(shí)間到,此時(shí)置位1s時(shí)間標(biāo)志位timer0_1s_flag=1。在主程序,只做點(diǎn)燈和判斷1s時(shí)間到來(lái)沒(méi)有,當(dāng)1s時(shí)間到來(lái)后,主程序就去處理LED的移位操作。

優(yōu)點(diǎn):效率極高,實(shí)時(shí)性好,時(shí)間穩(wěn)定

缺點(diǎn):非要說(shuō),那就是用到了定時(shí)器和中斷,初學(xué)者會(huì)覺(jué)得難

通過(guò)這種方式實(shí)現(xiàn)流水燈,還可以在主程序中加入其它的代碼,并不會(huì)影響到流水燈的運(yùn)行。其實(shí)這只是一個(gè)最簡(jiǎn)單的模型,在復(fù)雜項(xiàng)目中同樣可以用這模型,比如,1s點(diǎn)亮一個(gè)LED燈,1ms刷新一次數(shù)碼管,10ms讀取一次按鍵,500ms讀取一次ADC的值等等。這樣很多的功能都可以采用這樣的模型來(lái)實(shí)現(xiàn),并且各個(gè)功能之間是互不干擾的。

到此,今天的內(nèi)容聊完了,其實(shí)第三種方式就是“狀態(tài)機(jī)”或者“分時(shí)處理”等等一些比較高級(jí)的名稱(chēng)就是這么一回事。下次再聽(tīng)到這些高大上的名稱(chēng)時(shí),一定要知道,這并不是什么高深的東西。更重要的是在以后的復(fù)雜項(xiàng)目中要會(huì)用這樣的方式去處理各個(gè)功能之間的切換。

責(zé)任編輯:lq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6037

    文章

    44558

    瀏覽量

    635406
  • 流水燈
    +關(guān)注

    關(guān)注

    21

    文章

    433

    瀏覽量

    59718
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4788

    瀏覽量

    68625

原文標(biāo)題:你有幾種方法寫(xiě)流水燈

文章出處:【微信號(hào):chuxue_MCU,微信公眾號(hào):?jiǎn)纹瑱C(jī)技術(shù)宅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    低成本單片機(jī)方案——觸摸流水燈開(kāi)關(guān)控制

    方案觸摸流水燈控制方案Thedevelopmentofascheme隨著物聯(lián)網(wǎng)技術(shù)的不斷發(fā)展和智能家居的普及,觸摸流水燈控制方案作為一種新型的智能照明控制方式,逐漸成為市場(chǎng)的新寵。PART.1方案
    的頭像 發(fā)表于 12-26 16:37 ?100次閱讀
    低成本單片機(jī)方案——觸摸<b class='flag-5'>流水燈</b>開(kāi)關(guān)控制

    【RA-Eco-RA4E2-64PIN-V1.0開(kāi)發(fā)板試用】MDK+點(diǎn)燈+流水燈

    ” 文件,在 hal_entry 函數(shù)里面編寫(xiě)我們的代碼。 直接運(yùn)行,燈會(huì)常亮 流水燈實(shí)驗(yàn),延遲200ms
    發(fā)表于 12-15 15:59

    聊聊std::move函數(shù)和std::forward函數(shù)

    今天我們聊聊Modern cpp的兩個(gè)非常重要的概念移動(dòng)語(yǔ)義和轉(zhuǎn)發(fā)引用。
    的頭像 發(fā)表于 11-05 16:58 ?289次閱讀

    基于51單片機(jī)的跑馬燈/流水燈系統(tǒng)

    具體實(shí)現(xiàn)功能(1)9種LED流水燈模式通過(guò)按鍵進(jìn)行切換,數(shù)碼管顯示流水燈模式。(2)通過(guò)加減按鍵可以切換每種LED流水燈的速度。仿真演示視頻:設(shè)計(jì)介紹51單片機(jī)簡(jiǎn)介51單片是一種低功耗、高性能
    的頭像 發(fā)表于 10-22 14:12 ?234次閱讀
    基于51單片機(jī)的跑馬燈/<b class='flag-5'>流水燈</b>系統(tǒng)

    FPGA 實(shí)驗(yàn)一:流水燈模塊

    實(shí)驗(yàn)一:流水燈模塊 對(duì)于發(fā)展商而言,動(dòng)土儀式無(wú)疑是最重要的任務(wù)。為此,流水燈實(shí)驗(yàn)作為低級(jí)建模II的動(dòng)土儀式再適合不過(guò)了。廢話(huà)少說(shuō),我們還是開(kāi)始實(shí)驗(yàn)吧。 圖1.1 實(shí)驗(yàn)一建模圖。 如圖1.1 所示
    發(fā)表于 06-10 09:38

    單片機(jī)POV LED流水燈制作

    電子發(fā)燒友網(wǎng)站提供《單片機(jī)POV LED流水燈制作.docx》資料免費(fèi)下載
    發(fā)表于 05-28 14:34 ?3次下載

    請(qǐng)問(wèn)handle的寫(xiě)法

    遇到一行代碼 YDLidar *laser = lidarCreate(); //Create a handle to this Lidar. 請(qǐng)問(wèn)這行代碼是什么意思,句柄的寫(xiě)法怎么是這樣的呀
    發(fā)表于 05-18 10:42

    在官方庫(kù)中發(fā)現(xiàn)GPIOx-&gt;ODR這種寫(xiě)法,是什么意思,怎么中間會(huì)有-&gt;?

    本人新手,剛接觸st的芯片 在官方庫(kù)中發(fā)現(xiàn)GPIOx->ODR這種寫(xiě)法,不知道這是什么意思,怎么中間會(huì)有->? 請(qǐng)論壇上高手予以幫忙解答
    發(fā)表于 05-10 06:48

    【紫光同創(chuàng)盤(pán)古PGX-Nano教程】——(盤(pán)古PGX-Nano開(kāi)發(fā)板/PG2L50H_MBG324第三章)鍵控流水燈實(shí)驗(yàn)例程

    燈、按鍵、撥碼開(kāi)關(guān)等。 二:實(shí)驗(yàn)?zāi)康?由PB0(即開(kāi)發(fā)板S0位置)按鍵輸入,切換LED0~LED7的輸出效果。 三:實(shí)驗(yàn)原理 實(shí)現(xiàn)框架如下: (1)頂層實(shí)現(xiàn)按鍵切換LED的流水燈狀態(tài)
    發(fā)表于 04-29 16:06

    【紫光同創(chuàng)盤(pán)古PGX-MINI-4K教程】——(盤(pán)古PGX-MINI-4K開(kāi)發(fā)板/PGC4KD-6ILPG144第二章)LED 流水燈實(shí)驗(yàn)例程

    載 jtag 調(diào)試接口, 預(yù)留兩組 20PIN 擴(kuò)展 IO、數(shù)碼管、按鍵、led 燈等硬件資源,為用戶(hù)提供基本的 開(kāi)發(fā)環(huán)境。 二:實(shí)驗(yàn)?zāi)康恼莆?b class='flag-5'>流水燈原理并實(shí)現(xiàn)流水燈 三:實(shí)驗(yàn)要求流水燈:8 個(gè)
    發(fā)表于 03-26 16:24

    【紫光同創(chuàng)盤(pán)古PGX-Lite 7K教程】——(盤(pán)古PGX-Lite 7K開(kāi)發(fā)板/PGC7KD-6IMBG256第二章)?LED 流水燈實(shí)驗(yàn)例程

    流水燈原理并實(shí)現(xiàn)流水燈 三:實(shí)驗(yàn)要求流水燈:8 個(gè) LED 以 0.5s 間隔接替閃爍 四:實(shí)驗(yàn)原理相比上一個(gè) LED 閃爍的實(shí)現(xiàn),只需要改變 LED 的狀態(tài)。將 8 個(gè) LED 燈流水
    發(fā)表于 03-20 15:07

    51單片機(jī)流水燈制作

    ?流水燈是學(xué)習(xí)51單片機(jī)的一個(gè)基本項(xiàng)目,是我們對(duì)單片機(jī)IO口輸出認(rèn)識(shí)的基本項(xiàng)目。當(dāng)然學(xué)會(huì)了花樣流水燈也很好玩。 下面就分享一種51單片機(jī)流水燈制作的方法。 一、流水燈原理圖 二、相關(guān)知
    的頭像 發(fā)表于 02-26 10:06 ?1632次閱讀
    51單片機(jī)<b class='flag-5'>流水燈</b>制作

    SPICONTROLE 4個(gè)HC595移位寄存器設(shè)置流水燈時(shí),在SPIIINTIGRATIONED化了的時(shí)候,控制的HC595 LED跳了起來(lái)如何解決?

    采用 SPICONTROLE 4個(gè)HC595移位寄存器,在設(shè)置流水燈的時(shí)候了,SPICONTROLLES正常,但是在SPIIINTIGRATIONED化了的時(shí)候,控制的HC595的LED跳了起來(lái)。請(qǐng)問(wèn)該如何解決。例子比如:初始化時(shí)裝的時(shí)候全部,但是還有幾個(gè)燈一直是亮的。
    發(fā)表于 01-29 08:06

    聊聊AMBA協(xié)議的evolution過(guò)程

    作為一名新時(shí)代的ICer,一定必定肯定聽(tīng)說(shuō)過(guò)AMBA協(xié)議,但是卻少有人知道AMBA協(xié)議的evolution過(guò)程,本文將大致聊聊Evolution of the ARM AMBA Specifications!
    的頭像 發(fā)表于 01-19 09:50 ?1222次閱讀
    <b class='flag-5'>聊聊</b>AMBA協(xié)議的evolution過(guò)程

    【紫光同創(chuàng)國(guó)產(chǎn)FPGA教程】——(PGL22G第二章)鍵控流水燈實(shí)驗(yàn)例程

    ~ USER_LED8 的輸出效果。 三:實(shí)驗(yàn)原理 實(shí)現(xiàn)框架如下: (1)頂層實(shí)現(xiàn)按鍵切換 LED 的流水燈狀態(tài); (2)需要設(shè)計(jì)一個(gè)輸入控制模塊及一個(gè)輸出控制模塊; 這個(gè)實(shí)驗(yàn)帶大家將多個(gè)模塊整合
    發(fā)表于 01-05 11:22