一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

51單片機(jī)LED流水燈多種驅(qū)動(dòng)方式

華仔的編程隨筆 ? 來源:華仔stm32 ? 作者:華仔stm32 ? 2023-04-24 15:29 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

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

硬件

我以新定義TBK-RD8T3x_v1.0開發(fā)板,為實(shí)驗(yàn)條件。

image.png

板載了8個(gè)流水燈。原理圖如下:

image.png

實(shí)現(xiàn)方式之一

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

于是我寫下了第一種方法那就是直接對(duì)每一個(gè)燈進(jìn)行寫來實(shí)現(xiàn):

#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)   //延時(shí)約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號(hào)代表跑空,for語句不需要分號(hào),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);
	}
}

這樣的編程實(shí)現(xiàn)了流水燈,優(yōu)點(diǎn)是直觀,缺點(diǎn)是編寫起來麻煩,代碼比較長。經(jīng)查看map文件編譯結(jié)果為:Program Size: data=21.0 xdata=28 const=0 code=418

實(shí)現(xiàn)方式之二

用數(shù)組法來實(shí)現(xiàn),我們用數(shù)據(jù)來定義了P4,P3兩組顯示狀態(tài),共組組了9對(duì)分別表示8個(gè)燈的顯示狀態(tài):

#include "rd8.h"

//P40 P41 P42 P43 
//P31 P32 P33 P34  
//定義LED 狀態(tài)數(shù)組 

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)   //延時(shí)約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號(hào)代表跑空,for語句不需要分號(hào),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);
	}
}

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

實(shí)現(xiàn)方式之三

實(shí)現(xiàn)方式2,主要是查表的數(shù)組還是比較點(diǎn)內(nèi)存,這里優(yōu)化一下。

#include "rd8.h"

//P40 P41 P42 P43 
//P31 P32 P33 P34  
//定義LED 狀態(tài)數(shù)組 

//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,我們右移了一位,在顯示時(shí),我們需要左移一位
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)   //延時(shí)約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號(hào)代表跑空,for語句不需要分號(hào),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);
	}
}

這樣優(yōu)化后,點(diǎn)用內(nèi)存有所減少:Program Size: data=31.0 xdata=0 const=0 code=446

實(shí)現(xiàn)方式之四

在方式2、方式3,我們定義了數(shù)組,利用查表法來實(shí)現(xiàn)流水燈。這一節(jié)我用利用位移來實(shí)現(xiàn)。

#include "rd8.h"

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


void delay(uint32_t xms)   //延時(shí)約xms毫秒
{
    uint32_t  i,j;
    for(i=xms*2;i >0;i--)
    for(j=112;j >0;j--);    //分號(hào)代表跑空,for語句不需要分號(hào),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);		
		}
	}
}

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

實(shí)現(xiàn)方式之五

上面所有的流水燈是阻塞式的,我們?nèi)绻枰幚砥涞氖氯?,那就得修改為非阻塞式,這里我們?cè)黾恿?a href="http://www.www27dydycom.cn/tags/定時(shí)器/" target="_blank">定時(shí)器來實(shí)現(xiàn),代碼如下:

#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;  // 配置定時(shí)器0為 16位定時(shí)器,  TH0、TL0全用 
	TH0 =(65536-1000)/256;   //1000us定時(shí),即1毫秒溢出產(chǎn)生中斷
	TL0 =(65536-1000)%256;  //1000us定時(shí),即1毫秒溢出產(chǎn)生中斷
	ET0 = 1;									//開啟定時(shí)器0中斷
	EA = 1;										//開啟全局中斷
	TR0 = 1;									//定時(shí)器0開始計(jì)數(shù);
}

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
{
	//每次產(chǎn)生中斷后初始化定時(shí)器初值, 1ms秒產(chǎn)生1次中斷
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	//500毫秒執(zhí)行次LED1反轉(zhuǎn)
	count ++;
	if(count == 500)
	{
		sta =1;
		count = 0;
	}
	
}

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

實(shí)現(xiàn)方式之六

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

#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;  // 配置定時(shí)器0為 16位定時(shí)器,  TH0、TL0全用 
	TH0 =(65536-1000)/256;   //1000us定時(shí),即1毫秒溢出產(chǎn)生中斷
	TL0 =(65536-1000)%256;  //1000us定時(shí),即1毫秒溢出產(chǎn)生中斷
	ET0 = 1;									//開啟定時(shí)器0中斷
	EA = 1;										//開啟全局中斷
	TR0 = 1;									//定時(shí)器0開始計(jì)數(shù);
}

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
{
	//每次產(chǎn)生中斷后初始化定時(shí)器初值, 1ms秒產(chǎn)生1次中斷
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	//500毫秒執(zhí)行次LED1反轉(zhuǎn)
	count ++;
	if(count == 500)
	{
		sta =1;
		count = 0;
	}
	
}

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

總結(jié)

總結(jié)一下這幾種編程方式點(diǎn)用的空間:

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

審核編輯 黃宇

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

    關(guān)注

    6067

    文章

    44960

    瀏覽量

    648772
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3686

    瀏覽量

    95030
  • 定時(shí)器
    +關(guān)注

    關(guān)注

    23

    文章

    3297

    瀏覽量

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

    關(guān)注

    21

    文章

    433

    瀏覽量

    60401
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何去點(diǎn)亮基于51單片機(jī)LED流水燈

    如何讓8個(gè)小燈依次一個(gè)接一個(gè)的點(diǎn)亮?怎樣去編寫基于51單片機(jī)LED流水燈的程序?如何去點(diǎn)亮基于51單片
    發(fā)表于 08-11 08:49

    基于51單片機(jī)的心形流水燈原理圖

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

    51單片機(jī)流水燈程序

    51單片機(jī)流水燈程序 51單片機(jī)流水燈程序
    發(fā)表于 12-21 15:52 ?174次下載

    基于單片機(jī)流水燈介紹_51單片機(jī)流水燈的五種實(shí)現(xiàn)方法

    本文為大家?guī)砦宸N51單片機(jī)流水燈的實(shí)現(xiàn)方法。
    發(fā)表于 01-06 10:23 ?5.2w次閱讀
    基于<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>流水燈</b>介紹_<b class='flag-5'>51</b><b class='flag-5'>單片機(jī)</b><b class='flag-5'>流水燈</b>的五種實(shí)現(xiàn)方法

    使用51單片機(jī)控制的LED流水燈C語言程序免費(fèi)下載

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

    使用51單片機(jī)實(shí)現(xiàn)LED流水燈的程序和仿真資料免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用51單片機(jī)實(shí)現(xiàn)LED流水燈的程序和仿真資料免費(fèi)下載。
    發(fā)表于 12-07 08:00 ?39次下載
    使用<b class='flag-5'>51</b><b class='flag-5'>單片機(jī)</b>實(shí)現(xiàn)<b class='flag-5'>LED</b><b class='flag-5'>流水燈</b>的程序和仿真資料免費(fèi)下載

    基于51單片機(jī)流水燈參考案例下載

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

    基于AT89C51單片機(jī)簡易流水燈設(shè)計(jì)(C語言)

    ,區(qū)別于匯編語言。在進(jìn)行單片機(jī)學(xué)習(xí)時(shí),流水燈是基礎(chǔ)的練習(xí),了解單片機(jī)程序編程的基本語句。本文章的流水燈僅僅實(shí)現(xiàn)簡單的單個(gè)LED依次亮滅。在后
    發(fā)表于 11-05 11:06 ?19次下載
    基于AT89C<b class='flag-5'>51</b>的<b class='flag-5'>單片機(jī)</b>簡易<b class='flag-5'>流水燈</b>設(shè)計(jì)(C語言)

    51單片機(jī)實(shí)現(xiàn)流水燈

    文章目錄51單片機(jī)實(shí)現(xiàn)流水燈一、點(diǎn)亮第一個(gè)LED燈二、流水燈1.總線型控制2.延時(shí)函數(shù)3._ crol _函數(shù)使用4. 實(shí)現(xiàn)
    發(fā)表于 11-05 13:36 ?24次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機(jī)</b>實(shí)現(xiàn)<b class='flag-5'>流水燈</b>

    C51單片機(jī)流水燈C代碼

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

    51單片機(jī)流水燈教程。

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

    51單片機(jī)流水燈實(shí)驗(yàn)

    基于51單片機(jī)流水燈實(shí)驗(yàn) 我們知道通過編寫程序?qū)?b class='flag-5'>51單片機(jī)進(jìn)行控制,完成流水燈實(shí)驗(yàn)的
    發(fā)表于 11-20 17:51 ?66次下載
    <b class='flag-5'>51</b><b class='flag-5'>單片機(jī)</b><b class='flag-5'>流水燈</b>實(shí)驗(yàn)

    單片機(jī)led燈閃爍實(shí)驗(yàn)總結(jié)_51單片機(jī)實(shí)現(xiàn)LED流水燈

    流水燈51單片機(jī)實(shí)現(xiàn)點(diǎn)亮1個(gè)2個(gè)3個(gè)……8個(gè)流水燈。我們選擇P1口作為控制端口,輸出0時(shí)LED燈點(diǎn)亮。
    發(fā)表于 11-23 16:19 ?26次下載
    <b class='flag-5'>單片機(jī)</b><b class='flag-5'>led</b>燈閃爍實(shí)驗(yàn)總結(jié)_<b class='flag-5'>51</b><b class='flag-5'>單片機(jī)</b>實(shí)現(xiàn)<b class='flag-5'>LED</b><b class='flag-5'>流水燈</b>

    單片機(jī)51流水燈

    實(shí)驗(yàn)一 單片機(jī)流水燈【實(shí)驗(yàn)?zāi)康摹?、熟練掌握AT89C51開發(fā)板的使用方法和注意事項(xiàng)。2、了解簡單單片機(jī)應(yīng)用系統(tǒng)的設(shè)計(jì)方法。3、掌握應(yīng)用KEIL軟件編輯、編譯源程序的操作方法。4、掌握
    發(fā)表于 11-23 16:20 ?24次下載
    <b class='flag-5'>單片機(jī)</b><b class='flag-5'>51</b>的<b class='flag-5'>流水燈</b>

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

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