|
我在上一篇帖子簡(jiǎn)單展示了如何使用狀態(tài)機(jī)來替代阻塞延時(shí),這一篇我將向大家展示如何使用結(jié)構(gòu)體和函數(shù)指針來構(gòu)建對(duì)象。假設(shè)有個(gè)需求是需要三個(gè)LED分別按照5HZ、1HZ和0.5HZ的頻率來閃爍,我們應(yīng)該怎么實(shí)現(xiàn)它呢?如果按照上篇的解決方案需要三個(gè)LED_Twinkle函數(shù),只是函數(shù)內(nèi)部關(guān)于開關(guān)LED的部分不一樣。這樣存在一個(gè)問題,假如LED_Twinkle是一個(gè)非常復(fù)雜函數(shù),那么寫三遍非常費(fèi)時(shí)費(fèi)力容易出bug并且編譯出的可執(zhí)行文件體積還大。于是乎面向?qū)ο蠛痛a分層呼之欲出,廢話不多說先上代碼。
這段代碼涉及到結(jié)構(gòu)體和函數(shù)指針的語(yǔ)法知識(shí),關(guān)于語(yǔ)法這里不再贅述,我來介紹一下這段代碼是如何面向?qū)ο蠛头謱拥摹?br />
結(jié)構(gòu)體:
struct LED_Obj
{
uint8_t Status;
uint16_t DelayTime_LED;
void (*LED_OnOff)(uint8_t Com);
};
該結(jié)構(gòu)體成員包括運(yùn)行狀態(tài)變量(Status)、LED開關(guān)延時(shí)變量(DelayTime_LED)以及作為上下層接口用來控制LED開關(guān)的函數(shù)指針(*LED_OnOff)(uint8_t Com)
硬件層部分:
void LED1_OnOff(uint8_t Com);
void LED2_OnOff(uint8_t Com);
void LED3_OnOff(uint8_t Com);
這三個(gè)函數(shù)就是控制IO來實(shí)現(xiàn)LED開關(guān)
結(jié)構(gòu)體實(shí)例化(對(duì)象):
struct LED_Obj LED1 =
{
.LED_OnOff = LED1_OnOff
};
struct LED_Obj LED2 =
{
.LED_OnOff = LED2_OnOff
};
struct LED_Obj LED3 =
{
.LED_OnOff = LED3_OnOff
};
因?yàn)槲覀冇?個(gè)LED需要控制,所以需要?jiǎng)?chuàng)建3個(gè)LED_Obj對(duì)象并實(shí)現(xiàn)硬件層和應(yīng)用層的連接(函數(shù)指針初始化,指向一個(gè)函數(shù))
應(yīng)用層:
void LED_Twinkle(struct LED_Obj *LED,uint16_t HarfPeriod)
{
switch(LED->Status)
{
case 0:
{
LED->LED_OnOff(ON);
Set_Delay_Time(HarfPeriod,&LED->DelayTime_LED);
LED->Status++;
}break;
case 1:
{
if(CheckDelay(&LED->DelayTime_LED) == 0)
{
LED->Status++;
}
}break;
case 2:
{
LED->LED_OnOff(OFF);
Set_Delay_Time(HarfPeriod,&LED->DelayTime_LED);
LED->Status++;
}break;
case 3:
{
if(CheckDelay(&LED->DelayTime_LED) == 0)
{
LED->Status = 0;
}
}break;
}
}
void LED_Run(void)
{
LED_Twinkle(&LED1,100);
LED_Twinkle(&LED2,500);
LED_Twinkle(&LED3,1000);
}
void Task_1mS(void)
{
DelayTimeCount_ms(&LED1.DelayTime_LED);
DelayTimeCount_ms(&LED2.DelayTime_LED);
DelayTimeCount_ms(&LED3.DelayTime_LED);
}
至此,我們就實(shí)現(xiàn)了三個(gè)LED的分別控制。
|
|