點(diǎn)擊上方藍(lán)色“混說(shuō)Linux”,選擇“設(shè)為星標(biāo)”

為了能夠使得產(chǎn)品得到更好的開(kāi)發(fā)速度與以后更好的迭代和移植,框架分層是很有必要的。但如對(duì)于中小型項(xiàng)目嚴(yán)格遵循這些原則,勢(shì)必會(huì)消耗過(guò)多精力去思考怎么設(shè)計(jì)系統(tǒng),這是一個(gè)抉擇的過(guò)程。?
?
在嵌入式架構(gòu)中:一般分為硬件架構(gòu)與軟件架構(gòu)。這里是嵌入式軟件設(shè)計(jì),也是大多數(shù)人接觸的設(shè)計(jì)。
一般可以分為:硬件驅(qū)動(dòng)層–>功能模塊層–>應(yīng)用接口層–>業(yè)務(wù)邏輯層–>應(yīng)用層

?
如果想要更好地利用這些優(yōu)勢(shì),那得嚴(yán)格遵循設(shè)計(jì)的原則。
開(kāi)發(fā)成本高:因?yàn)槎鄬臃謩e承擔(dān)各自的職責(zé),增加功能需要在多個(gè)層增加代碼,這樣難免會(huì)增加開(kāi)發(fā)成本。但是合理的抽象,根據(jù)自己的項(xiàng)目設(shè)置合理的層級(jí)是能降低開(kāi)發(fā)成本的。
性能略低:業(yè)務(wù)流需要經(jīng)過(guò)多層代碼的處理,性能會(huì)有所消耗。
可擴(kuò)展性低:因?yàn)樯舷聦又g存在耦合度,有些功能變化可能涉及到多層的修改。
?
由于主要討論的是軟件框架的分層設(shè)計(jì),這里使用STM32cubemx來(lái)進(jìn)行硬件的初始化,盡可能少考慮到硬件驅(qū)動(dòng)的部分。
按鍵控制小燈的亮度,等級(jí)為:0,1,2,3
串口可以觀察當(dāng)前小燈亮度等級(jí)
OLED也可以觀察當(dāng)前小燈亮度等級(jí)
這和例子比較簡(jiǎn)單,業(yè)務(wù)邏輯層完全可以去除,直接從應(yīng)用層調(diào)用功能模塊層,加快開(kāi)發(fā)進(jìn)度。

最后附上一點(diǎn)點(diǎn)代碼,就是關(guān)于LED如何進(jìn)行在不同層進(jìn)行封裝

也就是下面的這兩個(gè)函數(shù)
void?MX_TIM1_Init(void);
void?HAL_TIM_MspPostInit(TIM_HandleTypeDef*?timHandle);/*?TIM1?init?function?*/
void?MX_TIM1_Init(void)
{
??/*?USER?CODE?BEGIN?TIM1_Init?0?*/
??/*?USER?CODE?END?TIM1_Init?0?*/
??TIM_ClockConfigTypeDef?sClockSourceConfig?=?{0};
??TIM_MasterConfigTypeDef?sMasterConfig?=?{0};
??TIM_OC_InitTypeDef?sConfigOC?=?{0};
??TIM_BreakDeadTimeConfigTypeDef?sBreakDeadTimeConfig?=?{0};
??/*?USER?CODE?BEGIN?TIM1_Init?1?*/
??/*?USER?CODE?END?TIM1_Init?1?*/
??htim1.Instance?=?TIM1;
??htim1.Init.Prescaler?=?168-1;
??htim1.Init.CounterMode?=?TIM_COUNTERMODE_UP;
??htim1.Init.Period?=?10000;
??htim1.Init.ClockDivision?=?TIM_CLOCKDIVISION_DIV1;
??htim1.Init.RepetitionCounter?=?0;
??htim1.Init.AutoReloadPreload?=?TIM_AUTORELOAD_PRELOAD_ENABLE;
??if?(HAL_TIM_Base_Init(&htim1)?!=?HAL_OK)
??{
????Error_Handler();
??}
??sClockSourceConfig.ClockSource?=?TIM_CLOCKSOURCE_INTERNAL;
??if?(HAL_TIM_ConfigClockSource(&htim1,?&sClockSourceConfig)?!=?HAL_OK)
??{
????Error_Handler();
??}
??if?(HAL_TIM_PWM_Init(&htim1)?!=?HAL_OK)
??{
????Error_Handler();
??}
??sMasterConfig.MasterOutputTrigger?=?TIM_TRGO_RESET;
??sMasterConfig.MasterSlaveMode?=?TIM_MASTERSLAVEMODE_DISABLE;
??if?(HAL_TIMEx_MasterConfigSynchronization(&htim1,?&sMasterConfig)?!=?HAL_OK)
??{
????Error_Handler();
??}
??sConfigOC.OCMode?=?TIM_OCMODE_PWM1;
??sConfigOC.Pulse?=?0;
??sConfigOC.OCPolarity?=?TIM_OCPOLARITY_HIGH;
??sConfigOC.OCNPolarity?=?TIM_OCNPOLARITY_HIGH;
??sConfigOC.OCFastMode?=?TIM_OCFAST_DISABLE;
??sConfigOC.OCIdleState?=?TIM_OCIDLESTATE_RESET;
??sConfigOC.OCNIdleState?=?TIM_OCNIDLESTATE_RESET;
??if?(HAL_TIM_PWM_ConfigChannel(&htim1,?&sConfigOC,?TIM_CHANNEL_2)?!=?HAL_OK)
??{
????Error_Handler();
??}
??sBreakDeadTimeConfig.OffStateRunMode?=?TIM_OSSR_DISABLE;
??sBreakDeadTimeConfig.OffStateIDLEMode?=?TIM_OSSI_DISABLE;
??sBreakDeadTimeConfig.LockLevel?=?TIM_LOCKLEVEL_OFF;
??sBreakDeadTimeConfig.DeadTime?=?0;
??sBreakDeadTimeConfig.BreakState?=?TIM_BREAK_DISABLE;
??sBreakDeadTimeConfig.BreakPolarity?=?TIM_BREAKPOLARITY_HIGH;
??sBreakDeadTimeConfig.AutomaticOutput?=?TIM_AUTOMATICOUTPUT_DISABLE;
??if?(HAL_TIMEx_ConfigBreakDeadTime(&htim1,?&sBreakDeadTimeConfig)?!=?HAL_OK)
??{
????Error_Handler();
??}
??/*?USER?CODE?BEGIN?TIM1_Init?2?*/
??/*?USER?CODE?END?TIM1_Init?2?*/
??HAL_TIM_MspPostInit(&htim1);
}
void?HAL_TIM_MspPostInit(TIM_HandleTypeDef*?timHandle)
{
??GPIO_InitTypeDef?GPIO_InitStruct?=?{0};
??if(timHandle->Instance==TIM1)
??{
??/*?USER?CODE?BEGIN?TIM1_MspPostInit?0?*/
??/*?USER?CODE?END?TIM1_MspPostInit?0?*/
????__HAL_RCC_GPIOE_CLK_ENABLE();
????/**TIM1?GPIO?Configuration
????PE11?????------>?TIM1_CH2
????*/
????GPIO_InitStruct.Pin?=?GPIO_PIN_11;
????GPIO_InitStruct.Mode?=?GPIO_MODE_AF_PP;
????GPIO_InitStruct.Pull?=?GPIO_NOPULL;
????GPIO_InitStruct.Speed?=?GPIO_SPEED_FREQ_LOW;
????GPIO_InitStruct.Alternate?=?GPIO_AF1_TIM1;
????HAL_GPIO_Init(GPIOE,?&GPIO_InitStruct);
??/*?USER?CODE?BEGIN?TIM1_MspPostInit?1?*/
??/*?USER?CODE?END?TIM1_MspPostInit?1?*/
??}
}對(duì)其進(jìn)行封裝,就是我們想要的Led小燈的驅(qū)動(dòng)了,到時(shí)候如果需要,改驅(qū)動(dòng)直接改底層就行了。
void?Led_init()
{
????MX_TIM1_Init();
????HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);//啟動(dòng)PWM
}根據(jù)上面的需求要求劃分為四個(gè)不同等級(jí),同時(shí)也需要對(duì)LED驅(qū)動(dòng)進(jìn)行進(jìn)一步封裝,以便滿足層與層之間不能跨級(jí)調(diào)用的原則(到這里是不是發(fā)現(xiàn)很麻煩!小項(xiàng)目就不要用啦!)
//ARR計(jì)數(shù)器設(shè)置值為0~10000
#define?LED_GRADE_0??0
#define?LED_GRADE_1??3000
#define?LED_GRADE_2??6000
#define?LED_GRADE_3??10000
//設(shè)置LED亮度功能
void?Led_Set_brightness(int?Grade)
{
????if(Grade==LED_GRADE_0)
????{
????????__HAL_TIM_SET_COMPARE(&htim1,?TIM_CHANNEL_2,?Grade);
????????HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_2);//關(guān)閉PWM輸出
????}
????else
????{
????????HAL_TIM_PWM_Start(&htim1,?TIM_CHANNEL_2,?Grade);
????????__HAL_TIM_SET_COMPARE(&htim1,?TIM_CHANNEL_2,?Grade);
????}
}
//啟動(dòng)LED功能
void?Led_Start()
{
????Led_init();
}這里僅僅以啟動(dòng)層為例:
void?Start_app()
{
????Led_Start();
}?
到這里,一個(gè)簡(jiǎn)單的例子也解釋完畢了,通過(guò)LED這個(gè)簡(jiǎn)單的例子,已經(jīng)大概了解到這個(gè)設(shè)計(jì)的復(fù)雜了,如果是大型項(xiàng)目,運(yùn)用起來(lái)會(huì)很爽,小型的話完全沒(méi)必要這樣分層,太麻煩了,嚴(yán)重減慢開(kāi)發(fā)效率,時(shí)間都用在思考如何進(jìn)行分層才能符合框架分層的原則。
原文:http://t.csdn.cn/OWG8f
版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系刪除。

往期推薦