題目:? ? ? ??
使用單片機(jī)驅(qū)動(dòng)8個(gè)LED,2個(gè)按鍵并實(shí)現(xiàn)跑馬燈功能。
????????當(dāng)按下按鍵1時(shí),LED?從左至右依次點(diǎn)亮,全亮后再?gòu)挠抑磷笠来蜗?,全滅后再?gòu)淖笾劣乙来吸c(diǎn)亮,依次循環(huán)下去。
???????當(dāng)按下按鍵2 時(shí),LED?從右至左依次點(diǎn)亮,全亮后再?gòu)淖笾劣乙来蜗?,全滅后再?gòu)挠抑磷笠来吸c(diǎn)亮,依次循環(huán)下去。
電路部分:
利用Proteus軟件搭建的電路圖如下:
部分一:AT89C51最小系統(tǒng)電路。
AT89C51最小系統(tǒng)電路其中包括時(shí)鐘電路和復(fù)位電路。
時(shí)鐘電路:產(chǎn)生像時(shí)鐘一樣準(zhǔn)確運(yùn)動(dòng)的振蕩電路。
復(fù)位電路:按鍵按下可以使程序重新運(yùn)行。
部分二:從LED-0到LED7接入P2口的八個(gè)LED燈電路。
發(fā)光二極管:只允許電流單方向通過(guò),并發(fā)光。
上拉電阻:降低回路電流,避免元件損壞。
部分三:按鈕控制電路
按鍵按下,P3_2或P3_3口與GND相接,置 0。
按鍵未按下,P3_2或P3_3口與電阻相接,按鍵處斷開(kāi),置 1。
上拉電阻:降低電流,保護(hù)電路。
程序部分:
設(shè)計(jì)思路:
1.先利用兩個(gè)for循環(huán)和延時(shí)函數(shù)初步實(shí)現(xiàn)LED燈延時(shí)流水功能。
2.按鍵部分接入單片機(jī)的外部中斷0和外部中斷1,當(dāng)按鍵按下時(shí)利用外部中斷去打斷for循環(huán),從而實(shí)現(xiàn)流水燈方向的改變。
跑馬燈亮滅思路:
右移亮:
P2=0xFE;
for(i=0;i<7;i++)
{
DELAY;
P2<<=1;
}
左移滅:
P2=0x80;
for(i=0;i<7;i++)
{
DELAY;
P2=(P2>>1)|0x80;
}
左移亮:
P2=0x7F;
for(i=0;i<7;i++)
{
DELAY;
P2>>=1;
}
右移滅:
P2=0x01;
for(i=0;i<7;i++)
{
DELAY;
P2=(P2<<1)|0x01;
}
方法一:利用外部中斷0、外部中斷1和Delay延時(shí)函數(shù)。
具體代碼:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-470888.html
#include <REGX52.H>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
void Delay300ms();
bit key1_flag = 0;
bit key2_flag = 0;
u8 i =0;
u16 Num;
void main()
{
AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
TMOD=0x01;//設(shè)置定時(shí)器0為工作方式1
TH0=(65535-50000)/256;//50MS
TL0=(65535-50000)%256;
ET0=1;
TR0=1;
EA=1;//開(kāi)總中斷
while(1)
{
if(key1_flag)
{
P2 = 0xFE;
for(i=0;i<7;i++) //左移循環(huán)亮
{
Delay300ms();
P2 <<= 1;
}
Delay300ms();
P2 = 0x80;
for(i=0;i<7;i++)//右移循環(huán)滅
{
Delay300ms();
P2 = (P2 >> 1) | 0x80;
}
Delay300ms();
}
if(key2_flag)
{
P2=0x7F;
for(i=0;i<7;i++)//右移循環(huán)亮
{
Delay300ms();
P2>>=1;
}
Delay300ms();
P2=0x01;
for(i=0;i<7;i++)//左移循環(huán)滅
{
Delay300ms();
P2=(P2<<1)|0x01;
}
Delay300ms();
}
}
}
void exter0() interrupt 0 //外部中斷0
{
key1_flag = 1;
key2_flag = 0;
}
void exint1() interrupt 2 //外部中斷1
{
key1_flag = 0;
key2_flag = 1;
}
//時(shí)鐘頻率為12MHz的300ms的延時(shí)函數(shù)
void Delay300ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 3;
j = 72;
k = 161;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
弊端:
1.浪費(fèi)CPU資源:因?yàn)椴捎昧舜罅康腄elay()函數(shù)會(huì)導(dǎo)致單片機(jī)cpu進(jìn)行大量的空運(yùn)算。
2.延時(shí)可能不夠精準(zhǔn):通過(guò)指令周期進(jìn)行延時(shí)會(huì)產(chǎn)生誤差。
改進(jìn)的方法二:利用外部中斷0、外部中斷1和定時(shí)器0。
具體代碼:
#include <REGX52.H>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
bit key1_flag = 0;
bit key2_flag = 0;
u8 i =0;
u16 Num = 0;
sbit led = P2^0;
void main()
{
TMOD = 0x01;//設(shè)置定時(shí)器0為工作方式1
TH0 = (65535-1000)/256;//設(shè)初值1ms
TL0 = (65535-1000)%256;
ET0 = 1;//定時(shí)器0的溢出允許位
TR0 = 1;//定時(shí)器0的運(yùn)行控制位
EX0 = 1;//外部中斷0的控制位
EX1 = 1;//外部中斷1控制位
EA = 1;//開(kāi)總中斷
while(1)
{
}
}
void exter0() interrupt 0 //外部中斷0
{
key1_flag = 1;
key2_flag = 0;
i = 0;
}
void exint1() interrupt 2 //外部中斷1
{
key1_flag = 0;
key2_flag = 1;
i= 0;
}
void tm0_isr() interrupt 1 using 1 //定時(shí)器中斷0
{
TH0 = (65535-1000)/256;//設(shè)初值1ms
TL0 = (65535-1000)%256;
Num++;
if(Num>199)
{
Num = 0;
if(key1_flag)
{
switch(i++)
{
case 0:P2 = 0xFE; break;
case 1:case 2:case 3:case 4:case 5:case 6:case 7:P2 <<= 1;break;
case 8:P2 = 0x80;break;
case 9:case 10:case 11:case 12:case 13:case 14:P2 = (P2 >> 1) | 0x80;break;
case 15:P2 = (P2 >> 1) | 0x80;i=0;break;
}
}
else if(key2_flag)
{
switch(i++)
{
case 0:P2 = 0x7F; break;
case 1:case 2:case 3:case 4:case 5:case 6:case 7:P2 >>= 1;break;
case 8:P2 = 0x01; break;
case 9:case 10:case 11:case 12:case 13:case 14:P2 = (P2 << 1) | 0x01; break;
case 15:P2 = (P2 << 1) | 0x01;i=0;break;
}
}
}
}
以上就是我此次對(duì)51單片機(jī)跑馬燈部分的學(xué)習(xí),如有錯(cuò)誤或者更好的想法,歡迎大家提出。? ? ? ??文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-470888.html
到了這里,關(guān)于利用51單片機(jī)進(jìn)行LED 跑馬燈設(shè)計(jì)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!