51單片機(jī) LED點(diǎn)陣的呼吸燈效果
STC 89C52RC
#include
typedefunsignedcharuchar;
typedefunsignedintuint;
typedefunsignedlongulong;
sbitADDR0=P1^0;
sbitADDR1=P1^1;
sbitADDR2=P1^2;
sbitADDR3=P1^3;
sbitENLED=P1^4;
ulongperiodCnt=0;//PWM周期計(jì)數(shù)值
ucharhighRH=0;//高電平重載值的高字節(jié)
ucharhighRL=0;//高電平重載值的低字節(jié)
ucharlowRH=0;//低電平重載值的高字節(jié)
ucharlowRL=0;//低電平重載值的低字節(jié)
ucharT1RH=0;//T1重載值的高字節(jié)
ucharT1RL=0;//T1重載值的低字節(jié)
ucharcodedutyCycle[13]={//占空比調(diào)整表
5,18,30,41,51,60,68,75,81,86,90,93,95
};
ucharcodeimage[8]={
0x81,0x81,0xE7,0xC3,0xC3,0xE7,0x81,0x81
};
ucharhRHi[13],hRLi[13],lRHi[13],lRLi[13];
voidconfigTmr1(uintms);
voidconfigPWM(uintfr,uchardc);
voidcalcRldVal(ucharidx);
voidmain(){
uchari;
EA=1;//開(kāi)總中斷
ADDR3=0;//選中LED點(diǎn)陣
configPWM(1000,dutyCycle[0]);//配置并啟動(dòng)PWM
for(i=0;i<13;i++)
calcRldVal(i);
configTmr1(50);//用T1定時(shí)調(diào)整占空比
while(1);
}
/*配置并啟動(dòng)T1,ms-定時(shí)時(shí)間*/
voidconfigTmr1(uintms){
ulongtmp;//臨時(shí)變量
tmp=11059200/12;//定時(shí)器計(jì)數(shù)頻率
tmp=(tmp*ms)/1000;//計(jì)算所需的計(jì)數(shù)值
tmp=65536-tmp;//計(jì)算定時(shí)器重載值
tmp=tmp+12;//補(bǔ)償中斷響應(yīng)延時(shí)造成的誤差
T1RH=tmp>>8;//定時(shí)器重載值拆分為高低字節(jié)
T1RL=tmp;
TMOD&=0x0F;//清零T1的控制位
TMOD|=0x10;//配置T1為模式1
TH1=T1RH;//加載T1重載值
TL1=T1RL;
ET1=1;//使能T1中斷
TR1=1;//啟動(dòng)T1
}
/*配置并啟動(dòng)PWM,fr-頻率,dc-占空比*/
voidconfigPWM(uintfr,uchardc){
uinthigh,low;
periodCnt=11059200/12/fr;//計(jì)算一個(gè)周期所需的計(jì)數(shù)值
high=periodCnt*dc/100;//計(jì)算高電平所需的計(jì)數(shù)值
low=periodCnt-high;//計(jì)算低電平所需的計(jì)數(shù)值
high=65536-high+12;//計(jì)算高電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
low=65536-low+12;//計(jì)算低電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
highRH=high>>8;//高電平重載值拆分為高低字節(jié)
highRL=high;
lowRH=low>>8;//低電平重載值拆分為高低字節(jié)
lowRL=low;
TMOD&=0xF0;//清零T0的控制位
TMOD|=0x01;//配置T0為模式1
TH0=highRH;//加載T0重載值
TL0=highRL;
ET0=1;//使能T0中斷
TR0=1;//啟動(dòng)T0
}
/*占空比調(diào)整函數(shù),頻率不變只調(diào)整占空比*/
voidcalcRldVal(ucharidx){
uinthigh,low;
high=periodCnt*dutyCycle[idx]/100;//計(jì)算高電平所需的計(jì)數(shù)值
low=periodCnt-high;//計(jì)算低電平所需的計(jì)數(shù)值
high=65536-high+12;//計(jì)算高電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
low=65536-low+12;//計(jì)算低電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
hRHi[idx]=high>>8;//高電平重載值拆分為高低字節(jié)
hRLi[idx]=high;
lRHi[idx]=low>>8;//低電平重載值拆分為高低字節(jié)
lRLi[idx]=low;
}
voidLED1_Scan(){
staticuchari=0;
P0=0xFF;
P1=(P1&0xF8)|i;
P0=image[i];
i=++i&0x07;
}
/*T0中斷服務(wù)函數(shù),產(chǎn)生PWM輸出*/
voidinterruptTimer0()interrupt1{
if(ENLED==1){
TH0=lowRH;
TL0=lowRL;
ENLED=0;
LED1_Scan();
}
else{
TH0=highRH;
TL0=highRL;
ENLED=1;
}
}
/*T1中斷服務(wù)函數(shù),定時(shí)動(dòng)態(tài)調(diào)整占空比*/
voidinterruptTimer1()interrupt3{
staticbitdir=0;
staticucharindex=0;
TH1=T1RH;//重新加載T1重載值
TL1=T1RL;
highRH=hRHi[index];
highRL=hRLi[index];
lowRH=lRHi[index];
lowRL=lRLi[index];
if(dir==0){
index++;
if(index==12)
dir=1;
}
else {