🔥小龍報✨ 永遠相信美好的事情即將發生
文章目錄
- 前言
- 一、應用場景
- 二、點燈原理
- 2.1LED的限流電阻計算
- 三、點亮LED
- 3.1如何用單片機點亮LED
- 3.2 通過編程控制芯片某個IO輸出高低電平
- 3.3板卡LED部分的原理圖
- 3.4點燈方法
- 方法一:操作整個寄存器
- 方法二 操作寄存器的某個位
- 四、閃爍控制
- 五、流水燈
- 六、相關擴展
- 總結與每日勵志
前言
本文討論了點亮 LED 的相關知識,包括應用場景、點燈原理、點亮方法、閃爍控制、流水燈實現以及相關擴展知識
一、應用場景
二、點燈原理
插件led燈珠長引腳為正極,短引腳為負極。
LED(發光二極管)兩端存在電壓差,有一定的電流流過時會亮起。電流可以理解為水流,電壓差可以理解為水位差,當兩個點水位高度不一樣時,水流會從高水位流向低水位。
2.1LED的限流電阻計算
注意:流過LED的電流需要在一定範圍內,否則會燒壞LED,一般小於20ma,所以我們就需要串聯電阻分壓,那串聯的電阻需要多大阻值呢?
一般插件LED電流是20ma左右,壓降:紅/黃色1.8V, 藍/白色 3V, 實際電壓要看 LED 規格書。
一般貼片LED電流是5ma左右,壓降:紅/綠/橙色1.8V,藍/白色 3V
例如:供電電壓是3.3V,黃色貼片LED
根據V = I * R ,則R= (3.3 - 1.8) /0.005 (5ma = 0.005), 所以 R = 300 歐姆.
很多時候你看到別人設計的電路中,LED串聯的電阻去到幾百歐或幾千歐都有,是設計錯了嗎?
實際上這是非常合理的, 因為大多數電路中,LED只是一個提示燈,對亮度沒有要求,反而希望把功耗降低,所以需要增大限流電阻來實現超低電流 ,像產品中的貼片LED去到0.5ma也是能看清楚燈光的。
三、點亮LED
3.1如何用單片機點亮LED
首先是接線部分,我們可以通過單片機的引腳,又叫做GPIO,這些IO都是具備輸出和輸入能力的,什麼是 GPIO 呢?GPIO 的 英文全程是 General-purpose input/output,翻譯過來就是:通用輸入輸出,也就是我們可以設置某個引腳輸出高低電平,或讀取某個引腳輸入的電平。
所以,所以我們的做法是:將LED和電阻串聯,一段接負極(接地),另一端接單片機IO口,然後 控制單片機的IO口電平 就可以決定LED是否點亮了
注意:通常我們不採用第一種情況,因為單片機IO口雖然可以達到高電壓,但是輸出電流不會大,因此單片機IO口給LED供電時可能會出現電流不足,導致LED不會全亮。
因此,我們一般選擇第二種,利用電源直接供電,電流灌入單片機IO口的方式來給LED燈供電
3.2 通過編程控制芯片某個IO輸出高低電平
操作芯片對應IO的寄存器即可,這部分我們可以在芯片手冊上看到
51單片機的每組IO口的電平狀態都被儲存在一個單獨的8位寄存器中,寄存器的位為0或1就分別對應其相應的GPIO電平為低或高。
3.3板卡LED部分的原理圖
因為擺放順序錯的原因,LED燈的順序如下哦:
3.4點燈方法
方法一:操作整個寄存器
直接在C語言代碼中用賦值法即可,例如操作P2口的P2.0 P2.1 P2.4 P2.6口輸出高電平的代碼是
P2 = 0x53;
0x53的是16進制的53,即53H,對應二進制01010011,即01010011B,
所以它對應P2.0 P2.1 P2.4 P2.6口輸出高電平
這裏的0x53是十六進制的表示方法,為什麼需要十六進制,什麼是十進制,什麼是二進制呢?
進制的作用:更好的表示數值。
(1)十進制: 十進制是人類最自然的數字系統,因為我們有十個手指,故我們使用十進制進行計數,使用 0-9 來表示數字,逢10進1。
(2)二進制: 二進制的出現是因為數字電路中,數字信號只有高/低或開/關兩種狀態,所以只需要使用兩個數字 0 和 1 來表示數字 ,優點是非常直觀,缺點是書寫起來冗長,過長的二進制容易記錄錯誤,不便閲讀和書寫。
(3)十六進制:為了可以更緊湊地表示二進制數據,就有了十六進制,使用十六個數字 0-9 和字母 A-F 來表示數字,在代碼中,使用0x前綴來表示十六進制。
方法二 操作寄存器的某個位
在C語言中,先定義你要操作的位,使用 關鍵字sbit(這是標準C語言沒有的關鍵字,是C51編譯器的拓展關鍵字,用於定義寄存器的某個位)。你就可以理解成sbit就是給寄存器的某個位起一個別名。之後用等號賦值即可更改此位的0或1
例:
sbit led1= Px^y;
(1)符號^在C51中也表示寄存器的第某位,如上方代碼,Px^y表示Px寄存器的第y位。
//定義變量led1表示P2寄存器的第7位
sbit led1= P2^7;
注意:"^"實質代表的是異或運算,可以算一下,恰好符合。
//定義變量led1表示P2寄存器的第7位
sbit led1= P2^7;
//定義變量led2表示P2寄存器的第6位
sbit led2= P2^6;
...
//將P2.7口 輸出低電平
led1= 0;
//將P2.6口 輸出高電平
led2= 1;
...
我們可以這樣來定義P2.7這個引腳的輸出低電平
#include <reg52.h>
sbit led = P2^7;
void main(void)
{
led = 0;
while(1)
{
}
}
四、閃爍控制
前面,我們通過設置某個引腳輸出低電平,點亮LED,也就是我們設置輸出高電平時,會關閉LED,那我們需要 實現LED閃爍的功能時,如何實現呢?
解決方案: 先點亮LED,延時一段時間,關閉LED,再延時一段時間,如此反覆,就可以得到一個閃爍的LED功能。
在單片機中如何實現延時功能呢?有以下幾種生成延時函數的生成方法
1、讓芯片循環執行一些無意義的代碼
我們知道,芯片執行每一句代碼都需要時間,假設執行一句代碼的時間為1ms,那我們點亮LED,然後執行500句(500ms)無意義的代碼,再關閉LED,就可以得到閃爍的效果啦。
//帶參延時函數
void delay_ms(unsigned int xms) //@12MHz
{
unsigned int i, j;
for(i=xms;i>0;i--)
{
for(j=124;j>0;j--)
{}
}
}
2、使用STC-ISP工具生成
//延時函數,延時500ms
void delay_500ms()
{
unsigned char i, j, k;
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
最終效果:
#include <reg52.h>
sbit led = P2^7;
//帶參延時函數
void delay_ms(unsigned int xms) //@12MHz
{
unsigned int i, j;
for(i=xms;i>0;i--)
{
for(j=124;j>0;j--)
{}
}
}
void main()
{
while(1)
{
led = 0;
delay_ms(500);
led = 1;
delay_ms(500);
}
}
五、流水燈
如果需要實現多個燈的顯示和熄滅呢?
其實就是流水燈的效果
#include "reg52.h"
#include "intrins.h"
sbit LED1 = P2^7;
sbit LED2 = P2^6;
sbit LED3 = P2^5;
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main(){
while(1){
LED1 = 0;
LED2 = 1;
LED3 = 1;
Delay1000ms();
LED2 = 0;
LED1 = 1;
LED3 = 1;
Delay1000ms();
LED3 = 0;
LED1 = 1;
LED2 = 1;
Delay1000ms();
}
}
代碼優化:
#include <reg52.h>
void delay_ms(unsigned int xms)
{
unsigned int i, j;
for(i=xms;i>0;i--)
{
for(j=124;j>0;j--)
{}
}
}
void main()
{
while(1)
{
P2 = 0xDF; //1101 1111
delay_ms(500);
P2 = 0xBF; //1011 1111
delay_ms(500);
P2 = 0x7F; //0111 1111
delay_ms(500);
}
}
六、相關擴展
bit、sbit、sfr的區別
首先,bit和sbit都是C51擴展的變量類型
bit是一種數據類型,ta就跟int、char、double這些數據類型一樣,只不過char=8位, bit=1位而已,這種變量只有兩種值存在0或是1,和bool類似
sbit更像是define或者typedef一樣(define和typedef也有區別,這又是另外一個坑,這裏就不説了),它是為已經分配了內存空間的變量重新取一個別名,一般用來定義特殊功能寄存器的位變量,以方便對寄存器的某位進行操作的,
例:
bit i = 0;
//意思就是在內存中劃一塊空間給i,讓他存儲0這個數據位。
sbit Flag = P0^1;//意思就是給P0^1取一個別名,它叫做Flag,
他是一個位操作變量,它代表訪問的地址是P0^1,0x80的第二位數據位。
sbit的用法有三種:
第一種方法:sbit 位變量名=地址值
第二種方法:sbit 位變量名=SFR名稱^變量位地址值
第三種方法:sbit 位變量名=SFR地址值^變量位地址值
如定義PSW中的OV可以用以下三種方法:
sbit OV=0xd2 (1)説明:0xd2是OV的位地址值
sbit OV=PSW^2 (2)説明:其中PSW必須先用sfr定義好
sbit OV=0xD0^2 (3)説明:0xD0就是PSW的地址值
因此這裏用sfr P1_0=P1^0;就是定義用符號P1_0來表示P1.0引腳,如果你願意也可以起P10一類的名字,只要下面程序中也隨之更改就行了。
sfr 不是標準C 語言的關鍵字,而是Keil 為能直接訪問80C51 中的SFR 而提供了一個新的關鍵詞,其用法是:
sfr變量名=地址值。
例:sfr P1 = 0x90;
這樣的一行即定義P1 與地址0x90 對應,P1 口的地址就是0x90.
SFR的定義在頭文件reg51.h或reg52.h中。
總結與每日勵志
✨ ***本文介紹了LED點亮的原理、方法及擴展應用。主要內容包括:LED工作原理及限流電阻計算,單片機控制LED的接線方式與編程方法(通過寄存器操作或位操作),閃爍LED的實現原理及延時函數生成技巧(循環代碼或STC-ISP工具)。文章還提供了51單片機控制LED的具體代碼示例,並簡要提及流水燈等擴展應用場景。適合嵌入式初學者快速掌握LED控制的基礎知識。***