|
|
下面的代碼用了一個(gè)二維數(shù)組來實(shí)現(xiàn)led定時(shí)間隔閃爍,復(fù)用很簡單,直接把ledstate函數(shù)放進(jìn)定時(shí)器中斷就行,可以用外部函數(shù)改變ledmode,進(jìn)而調(diào)整到不同的模式。想要修改間隔,就改數(shù)組值或者改定時(shí)器中斷的頻率,改間隔的話,可以改數(shù)組的值,也可以增加數(shù)組的行數(shù)或者列數(shù)(同時(shí)修改計(jì)數(shù)器循環(huán)值)
具體原理很簡單,就是通過ledmode和currentbit這兩個(gè)數(shù)值在二維數(shù)組中選值,然后與計(jì)數(shù)器做比較,定時(shí)器每次中斷都會(huì)對計(jì)數(shù)器+1,于是就有了時(shí)間基礎(chǔ),每個(gè)1都是定時(shí)器中斷的間隔。直到計(jì)數(shù)器的值大于從數(shù)組中讀取到的值,才會(huì)切換讀取數(shù)組的下一位。通過&運(yùn)算讓位數(shù)在0到3的范圍里循環(huán)。
根據(jù)你的定時(shí)器中斷間隔與與想要實(shí)現(xiàn)的閃爍,調(diào)整數(shù)組數(shù)值就行。
const unsigned char ledform[][4] = {//二維數(shù)組
//每次125ms定時(shí)器1中斷l(xiāng)edcounter++,將ledcounter與數(shù)組做比較
{0,0,0,0}, //mode0,常亮(vcc>4200mv),數(shù)組中的0表示立即切換到下一位
{16,4,16,4}, //mode1,2000ms亮,500ms滅 (3800<vcc<=4000)
{8,4,8,4}, //mode2,1000ms亮,500ms滅 (3400<vcc<=3800)
{4,4,4,4}, //mode3,500ms亮,500ms滅 (2750=<vcc<=3400)
{1,1,1,1}, //mode4,125ms亮,125ms滅(vcc<2750)
{12,1,1,1}, //mode5,1500ms亮,125ms滅亮滅,charging
};
void LED_STATE(void){
static unsigned char ledcounter = 0;//局部變量聲明
//用于從ledform中選值,比如ledmode=1,currentbit=2,segtimes=4
static unsigned char currentbit = 0;//當(dāng)前位
unsigned char bitvalue = ledform[ledmode][currentbit];//讀取當(dāng)前位值
if(ledmode == 0){//對常亮的特殊情況單獨(dú)設(shè)置
P30 = 0;
ledcounter = 0;
return;//不繼續(xù)執(zhí)行下面的語句
}
//狀態(tài)切換判斷
if(ledcounter >= bitvalue){
currentbit = (currentbit + 1) & 0X03;//0~3循環(huán),改了列數(shù)修改這里,可以改成%N,N就是數(shù)組列數(shù)
ledcounter = 0;
}
//如果位值為0,位數(shù)+1,并退出函數(shù),實(shí)現(xiàn)常亮,與下面的狀態(tài)切換判斷不能調(diào)換先后位置
//定義位數(shù)對應(yīng)LED亮滅
if (currentbit == 0 || currentbit == 2) {
P30 = 0; // 亮
} else {
P30 = 1; // 滅
}
ledcounter++;//led計(jì)數(shù)器加1
}
|
|