色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

51單片機LED流水燈多種驅動方式

華仔的編程隨筆 ? 來源:華仔stm32 ? 作者:華仔stm32 ? 2023-04-24 15:29 ? 次閱讀

前言

開發者在入門點亮第一盞燈后,再深入一點就會用到流水燈。而如何實現流水燈又有好幾種方式,我查詢了一網上大神們的作品,無非有三種方式即查詢法、位移法。這篇文章,我就如何實現流水燈開展討論。

硬件

我以新定義TBK-RD8T3x_v1.0開發板,為實驗條件。

image.png

板載了8個流水燈。原理圖如下:

image.png

實現方式之一

從原理圖上看,這8個燈不是接在1個P口上,分別接到了P3的第1-4,與P4的0-3端口之,按網上的教材位移方法都是不適用的。

于是我寫下了第一種方法那就是直接對每一個燈進行寫來實現:

#include "rd8.h"


#define ON 1
#define OFF 0

sbit LED0 = P4^0;
sbit LED1 = P4^1;
sbit LED2 = P4^2;
sbit LED3 = P4^3;
sbit LED4 = P3^1;
sbit LED5 = P3^2;
sbit LED6 = P3^3;
sbit LED7 = P3^4;

void  delay(uint32_t xms)   //延時約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號代表跑空,for語句不需要分號,112次表示一毫秒
}

void LED_Init(void)
{
	P3CON |= 0x1E; //P3 0b0001 1110 輸出
	P4CON |= 0x0F; //P4 0b0000 1111
}



void main(void)
{
	LED_Init();
	while(1)
	{
		LED0 = ON;
		delay(500);
		
		LED0 = OFF;
		LED1 = ON;
		delay(500);
		
		LED1 = OFF;
		LED2 = ON;
		delay(500);
		
		LED2 = OFF;
		LED3 = ON;
		delay(500);
		
		LED3 = OFF;
		LED4 = ON;
		delay(500);
		
		LED4 = OFF;
		LED5 = ON;
		delay(500);
		
		LED5 = OFF;
		LED6 = ON;
		delay(500);
		
		LED6 = OFF;
		LED7 = ON;
		delay(500);
		
		LED7 = OFF;
		delay(500);
	}
}

這樣的編程實現了流水燈,優點是直觀,缺點是編寫起來麻煩,代碼比較長。經查看map文件編譯結果為:Program Size: data=21.0 xdata=28 const=0 code=418

實現方式之二

用數組法來實現,我們用數據來定義了P4,P3兩組顯示狀態,共組組了9對分別表示8個燈的顯示狀態:

#include "rd8.h"

//P40 P41 P42 P43 
//P31 P32 P33 P34  
//定義LED 狀態數組 

static uint8_t LEDs[]={0x00,0x00,0x01,0x00, 0x02,0x00,0x04,0x00,0x08,0x00, 0x00,0x02, 0x00,0x04, 0x00,0x08,0x00,0x10};  


void LED_Init(void)
{
	P3CON |= 0x1E; //P3 0b0001 1110 輸出
	P4CON |= 0x0F; //P4 0b0000 1111
}


void delay(uint32_t xms)   //延時約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號代表跑空,for語句不需要分號,112次表示一毫秒
}

void LED_Flash(void)
{
	static uint8_t ledIndex = 0;
	if(ledIndex == 9)
		ledIndex = 0;
	P4 = LEDs[ledIndex*2];
	P3 = LEDs[ledIndex*2+1];
	ledIndex ++;
	
}


void main(void)
{
	LED_Init();

	while(1)
	{
		LED_Flash();
		delay(500);
	}
}

這樣用查表法整理出來的的代碼相對于第一種實現方式,代碼行有所減短,編譯后,查看.map結果為:Program Size: data=40.0 xdata=0 const=0 code=454

實現方式之三

實現方式2,主要是查表的數組還是比較點內存,這里優化一下。

#include "rd8.h"

//P40 P41 P42 P43 
//P31 P32 P33 P34  
//定義LED 狀態數組 

//static uint8_t LEDs[]={0x00,0x00,0x01,0x00, 0x02,0x00,0x04,0x00,0x08,0x00, 0x00,0x02, 0x00,0x04, 0x00,0x08,0x00,0x10};  
//                            高四位代表P4 低四位代表P3 由于P3 為1-4,我們右移了一位,在顯示時,我們需要左移一位
static uint8_t LEDs[]={0x00,// 0b 0000 00000
											 0x10,// 0b 0001 00000 
                       0x20,
                       0x40,
                       0x80,
                       0x01,//0b 0000 0001 
                       0x02, 0x04,0x08,}; 
void LED_Init(void)
{
	P3CON |= 0x1E; //P3 0b0001 1110 輸出
	P4CON |= 0x0F; //P4 0b0000 1111
}


void delay(uint32_t xms)   //延時約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號代表跑空,for語句不需要分號,112次表示一毫秒
}

void LED_Flash(void)
{
	static uint8_t ledIndex = 0;
	if(ledIndex == 9)
		ledIndex = 0;
	P4 = (LEDs[ledIndex] & 0xF0) >>4;
	P3 = (LEDs[ledIndex] & 0x0F)< 1;
	ledIndex ++;
	
}


void main(void)
{
	LED_Init();

	while(1)
	{
		LED_Flash();
		delay(500);
	}
}

這樣優化后,點用內存有所減少:Program Size: data=31.0 xdata=0 const=0 code=446

實現方式之四

在方式2、方式3,我們定義了數組,利用查表法來實現流水燈。這一節我用利用位移來實現。

#include "rd8.h"

void LED_Init(void)
{
	P3CON |= 0x1E; //P3 0b0001 1110 輸出
	P4CON |= 0x0F; //P4 0b0000 1111
}


void delay(uint32_t xms)   //延時約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號代表跑空,for語句不需要分號,112次表示一毫秒
}

void LED_Flash(uint8_t led_data)
{
	P3 = (led_data & 0xF0) >>3;  //由于P3從1開始,所以只右移3位
	P4 = (led_data & 0x0F);
}


void main(void)
{
	uint8_t LED_DATA;
	uint8_t i;
	LED_Init();
	
	while(1)
	{
		LED_DATA = 0x00;
		LED_Flash(LED_DATA); // 這里開始是熄滅所有的燈
		delay(500);
		LED_DATA = 0x01;      //初始值
		for(i=0;i< 9;i++)
		{
			LED_Flash(LED_DATA);
			LED_DATA = LED_DATA < < 1;
			delay(500);		
		}
	}
}

這樣我也實現了流水燈,這次位移的實現,我們的代碼量變化為:Program Size: data=23.0 xdata=0 const=0 code=325

實現方式之五

上面所有的流水燈是阻塞式的,我們如果需要處理其的事任,那就得修改為非阻塞式,這里我們增加了定時器來實現,代碼如下:

#include "rd8.h"

uint8_t sta;  
uint32_t count = 0;

void LED_Init(void)
{
	P3CON |= 0x1E; //P3 0b0001 1110 輸出
	P4CON |= 0x0F; //P4 0b0000 1111
}

void Timer0Iint(void)
{
	TMOD |= 0x01;  // 配置定時器0為 16位定時器,  TH0、TL0全用 
	TH0 =(65536-1000)/256;   //1000us定時,即1毫秒溢出產生中斷
	TL0 =(65536-1000)%256;  //1000us定時,即1毫秒溢出產生中斷
	ET0 = 1;									//開啟定時器0中斷
	EA = 1;										//開啟全局中斷
	TR0 = 1;									//定時器0開始計數;
}

void LED_Flash(void)
{
	static uint8_t led_data = 0x00;

	P3 = (led_data & 0xF0) >>3;  //由于P3從1開始,所以只右移3位
	P4 = (led_data & 0x0F);
	led_data = led_data< 1;
	if (led_data == 0x00)
		led_data = led_data |= 0x01;
}


void main(void)
{
	Timer0Iint();
	LED_Init();
	
	while(1)
	{
		if(sta == 1)
		{
			sta = 0;
			LED_Flash();		
		}
	}
}

void Timer0() interrupt 1
{
	//每次產生中斷后初始化定時器初值, 1ms秒產生1次中斷
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	//500毫秒執行次LED1反轉
	count ++;
	if(count == 500)
	{
		sta =1;
		count = 0;
	}
	
}

經過修改,這一版是基于非阻塞式的實現。編譯后的.map,代碼尺寸如下:Program Size: data=15.0 xdata=0 const=0 code=364

實現方式之六

這里再增加一種位移的方面代碼如下,這種方式更加簡潔:

#include "rd8.h"
#include 
uint8_t sta;  
uint32_t count = 0;

void LED_Init(void)
{
	P3CON |= 0x1E; //P3 0b0001 1110 輸出
	P4CON |= 0x0F; //P4 0b0000 1111
}

void Timer0Iint(void)
{
	TMOD |= 0x01;  // 配置定時器0為 16位定時器,  TH0、TL0全用 
	TH0 =(65536-1000)/256;   //1000us定時,即1毫秒溢出產生中斷
	TL0 =(65536-1000)%256;  //1000us定時,即1毫秒溢出產生中斷
	ET0 = 1;									//開啟定時器0中斷
	EA = 1;										//開啟全局中斷
	TR0 = 1;									//定時器0開始計數;
}

void LED_Flash(void)
{
	static uint8_t led_data = 0x01;
	led_data = _crol_(led_data,1);
	P3 = (led_data & 0xF0) >>3;  //由于P3從1開始,所以只右移3位
	P4 = (led_data & 0x0F);
//	led_data = led_data< 
//	if (led_data == 0x00)
//		led_data = led_data |= 0x01;
}


void main(void)
{
	Timer0Iint();
	LED_Init();
	
	while(1)
	{
		if(sta == 1)
		{
			sta = 0;
			LED_Flash();		
		}
	}
}

void Timer0() interrupt 1
{
	//每次產生中斷后初始化定時器初值, 1ms秒產生1次中斷
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	//500毫秒執行次LED1反轉
	count ++;
	if(count == 500)
	{
		sta =1;
		count = 0;
	}
	
}

此次修改后的.map文件顯示為:Program Size: data=15.0 xdata=0 const=0 code=359

總結

總結一下這幾種編程方式點用的空間:

序號dataxdataconstcode優點缺點
定義端口法21.0280418代碼可讀性高,直觀代碼行數多,如何需要修改比較麻煩
數組查表法40.000454代碼較第一種整潔,容易修改占用內存大
查表法優化31.000446相比上一種減少了內存的占用占用內存大
位移法之一23.000325相比上面的數組查詢占用內存小實現代碼復雜
非阻塞式位移15.000364相比上面的,實現非阻塞式位移代碼理解需要一定基礎
非阻塞進式位移二15.000359代碼更整法,占用空間小,后期實現功能簡單方便閱讀理解代碼,需要位移的基礎知識

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6050

    文章

    44687

    瀏覽量

    641171
  • 編程
    +關注

    關注

    88

    文章

    3649

    瀏覽量

    94344
  • 定時器
    +關注

    關注

    23

    文章

    3259

    瀏覽量

    115884
  • 流水燈
    +關注

    關注

    21

    文章

    433

    瀏覽量

    59957
收藏 人收藏

    評論

    相關推薦

    如何去點亮基于51單片機LED流水燈

    如何讓8個小燈依次一個接一個的點亮?怎樣去編寫基于51單片機LED流水燈的程序?如何去點亮基于51單片
    發表于 08-11 08:49

    基于51單片機的心形流水燈原理圖

    51單片機控制的心形流水燈原理圖,通心形流水燈的制作熟悉單片機的接口
    發表于 11-23 11:03 ?72次下載

    51單片機流水燈程序

    51單片機流水燈程序 51單片機流水燈程序
    發表于 12-21 15:52 ?170次下載

    基于單片機流水燈介紹_51單片機流水燈的五種實現方法

    本文為大家帶來五種51單片機流水燈的實現方法。
    發表于 01-06 10:23 ?5.2w次閱讀
    基于<b class='flag-5'>單片機</b>的<b class='flag-5'>流水燈</b>介紹_<b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>流水燈</b>的五種實現方法

    使用51單片機控制的LED流水燈C語言程序免費下載

    本文檔的主要內容詳細介紹的是使用51單片機控制的LED流水燈C語言程序免費下載。
    發表于 03-25 18:19 ?17次下載
    使用<b class='flag-5'>51</b><b class='flag-5'>單片機</b>控制的<b class='flag-5'>LED</b>的<b class='flag-5'>流水燈</b>C語言程序免費下載

    使用51單片機實現LED流水燈的程序和仿真資料免費下載

    本文檔的主要內容詳細介紹的是使用51單片機實現LED流水燈的程序和仿真資料免費下載。
    發表于 12-07 08:00 ?38次下載
    使用<b class='flag-5'>51</b><b class='flag-5'>單片機</b>實現<b class='flag-5'>LED</b><b class='flag-5'>流水燈</b>的程序和仿真資料免費下載

    基于51單片機流水燈參考案例下載

    基于51單片機流水燈參考案例下載
    發表于 09-05 17:02 ?43次下載

    基于AT89C51單片機簡易流水燈設計(C語言)

    ,區別于匯編語言。在進行單片機學習時,流水燈是基礎的練習,了解單片機程序編程的基本語句。本文章的流水燈僅僅實現簡單的單個LED依次亮滅。在后
    發表于 11-05 11:06 ?19次下載
    基于AT89C<b class='flag-5'>51</b>的<b class='flag-5'>單片機</b>簡易<b class='flag-5'>流水燈</b>設計(C語言)

    51單片機實現流水燈

    文章目錄51單片機實現流水燈一、點亮第一個LED燈二、流水燈1.總線型控制2.延時函數3._ crol _函數使用4. 實現
    發表于 11-05 13:36 ?24次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b>實現<b class='flag-5'>流水燈</b>

    C51單片機流水燈C代碼

    C51單片機流水燈C代碼
    發表于 11-05 15:20 ?34次下載
    C<b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>流水燈</b>C代碼

    51單片機流水燈教程。

    51單片機流水燈教程。
    發表于 11-11 20:21 ?22次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>流水燈</b>教程。

    51單片機流水燈實驗

    基于51單片機流水燈實驗 我們知道通過編寫程序對51單片機進行控制,完成流水燈實驗的
    發表于 11-20 17:51 ?66次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>流水燈</b>實驗

    單片機led燈閃爍實驗總結_51單片機實現LED流水燈

    流水燈51單片機實現點亮1個2個3個……8個流水燈。我們選擇P1口作為控制端口,輸出0時LED燈點亮。
    發表于 11-23 16:19 ?26次下載
    <b class='flag-5'>單片機</b><b class='flag-5'>led</b>燈閃爍實驗總結_<b class='flag-5'>51</b><b class='flag-5'>單片機</b>實現<b class='flag-5'>LED</b><b class='flag-5'>流水燈</b>

    單片機51流水燈

    實驗一 單片機流水燈【實驗目的】1、熟練掌握AT89C51開發板的使用方法和注意事項。2、了解簡單單片機應用系統的設計方法。3、掌握應用KEIL軟件編輯、編譯源程序的操作方法。4、掌握
    發表于 11-23 16:20 ?24次下載
    <b class='flag-5'>單片機</b><b class='flag-5'>51</b>的<b class='flag-5'>流水燈</b>

    51單片機流水燈制作

    ?流水燈是學習51單片機的一個基本項目,是我們對單片機IO口輸出認識的基本項目。當然學會了花樣流水燈也很好玩。 下面就分享一種
    的頭像 發表于 02-26 10:06 ?1788次閱讀
    <b class='flag-5'>51</b><b class='flag-5'>單片機</b><b class='flag-5'>流水燈</b>制作
    主站蜘蛛池模板: 伊人影院综合 | 国产免费内射又粗又爽密桃视频 | 国产亚洲精品欧洲在线视频 | 少妇人妻偷人精品视蜜桃 | 伊人精品视频直播 | 免费夜色污私人影院网站 | 久青草国产97香蕉在线视频 | 久久精品综合网中文字幕 | 国产一级特黄aa毛片 | 偷窥 亚洲 色 国产 日韩 | 99久久伊人一区二区yy5o99 | 自拍 偷拍 亚洲 经典 | 一级大乳奶 | yellow日本动漫观看免费 | 色噜噜狠狠色综合中文字幕 | 久见久热 这里只有精品 | 9277在线观看免费高清完整版 | 国产精品久久久久久久久无码 | 亚洲一二三产品区别在哪里 | 色婷婷我要去我去也 | 国产亚洲精品久久无亚洲 | 成在线人免费视频 | 91国偷自产一区二区三区 | 69xx欧美 | 久久婷五月综合色啪网 | 我半夜摸妺妺的奶C了她 | a三级黄色片 | 成人免费看片45分钟 | 亚洲国产成人精品青青草原100 | 99热这里只有精品88 | 总裁呻吟双腿大开男男H | 亚洲AV人无码综合在线观看蜜桃 | 小SAO货边洗澡边CAO你动漫 | 日本老妇一级特黄aa大片 | 国产精品自在在线午夜蜜芽tv在线 | 国产免费人成在线视频有码 | 狠狠狠的在啪线香蕉 | 欧美z000z猪| 亚洲精品123区 | 亚洲AV无码久久流水呻蜜桃久色 | 亚洲 无码 制服 日韩 |