工厂模式是抽象出来,使得对象的方法不依赖于具体实现。按照专业术语来说有个做依赖倒置原则,即高层模块不应依赖于低层模块,二者应依赖于抽象。抽象不应依赖于细节,细节应依赖于抽象。
以最简单的LED灯为例,我们可以将IO抽象出来
.文件
c
ypedef struct DRV_GPIO_Type
{
GPIO_TypeDef *GPIOx;
uint32_t GPIO_PIN;
//操作
uint8_t action; //动作
void (*Init)(const struct DRV_GPIO_Type*);
void (*On)(struct DRV_GPIO_Type*);
void (*Off)(struct DRV_GPIO_Type*);
uint8_t (*ReadPin)(struct DRV_GPIO_Type*);
void (*Toggle)(struct DRV_GPIO_Type*);
}DRV_GPIO_T;
extern DRV_GPIO_T gtDrv_R_LED;
extern DRV_GPIO_T gtDrv_Y_LED;
void Drv_GPIO_ON(DRV_GPIO_T *pDrv);
void Drv_GPIO_OFF(DRV_GPIO_T *pDrv);
uint8_t Drv_GPIO_ReadPin(DRV_GPIO_T *pDrv);
void Drv_GPIO_Toggle(DRV_GPIO_T *pDrv);
.c文件
c
#include "drv_io.h"
/* 实例化LED灯 红灯 */
DRV_GPIO_T gtDrv_R_LED=
{
.GPIOx = LED1_GPIO_PORT,
.GPIO_PIN = LED1_GPIO_PIN,
.On = Drv_GPIO_OFF,
.Off = Drv_GPIO_ON,
.ReadPin = Drv_GPIO_ReadPin,
.Toggle = Drv_GPIO_Toggle,
};
/* 实例化 LED灯 黄灯*/
DRV_GPIO_T gtDrv_Y_LED=
{
.GPIOx = LED0_GPIO_PORT,
.GPIO_PIN = LED0_GPIO_PIN,
.action = 0,
.On = Drv_GPIO_OFF,
.Off = Drv_GPIO_ON,
.ReadPin = Drv_GPIO_ReadPin,
.Toggle = Drv_GPIO_Toggle,
};
/**
* @brief IO口输出高电平
* @param pDrv :IO口的结构体指针
*
* @retval none
*/
void Drv_GPIO_ON(DRV_GPIO_T *pDrv)
{
//GPIO_SetBits(pDrv->GPIOx, pDrv->GPIO_PIN);
HAL_GPIO_WritePin(pDrv->GPIOx, pDrv->GPIO_PIN, GPIO_PIN_SET);
pDrv->action = 1;
}
/**
* @brief IO口输出低电平
* @param pDrv :IO口的结构体指针
*
* @retval none
*/
void Drv_GPIO_OFF(DRV_GPIO_T *pDrv)
{
//GPIO_ResetBits(pDrv->GPIOx, pDrv->GPIO_PIN);
HAL_GPIO_WritePin(pDrv->GPIOx, pDrv->GPIO_PIN, GPIO_PIN_RESET);
pDrv->action = 0;
}
/**
* @brief IO口翻转
* @param pDrv :IO口的结构体指针
*
* @retval none
*/
void Drv_GPIO_Toggle(DRV_GPIO_T *pDrv)
{
HAL_GPIO_TogglePin(pDrv->GPIOx, pDrv->GPIO_PIN);
}
/**
* @brief 读取IO口的电平
* @param pDrv :IO口的结构体指针
*
* @retval lRet Bit_SET 或者 Bit_RESET
*/
uint8_t Drv_GPIO_ReadPin(DRV_GPIO_T *pDrv)
{
uint8_t lRet ;
//lRet = GPIO_ReadInputDataBit(pDrv->GPIOx, pDrv->GPIO_PIN);
lRet = HAL_GPIO_ReadPin(pDrv->GPIOx, pDrv->GPIO_PIN);
return lRet;
}
测试实现
c
**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
int16_t i = 0;
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* 配置通道 0,上行配置*/
// SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
// /* 配置通道 0,下行配置*/
// SEGGER_RTT_ConfigDownBuffer(0, "RTTDOWN", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
// SEGGER_RTT_SetTerminal(0);
led_init();
// multiTimerInstall(PlatformTicksGetFunc);
//
// multiTimerStart(&timer1, 500, LED_Task_callback, NULL);
// multiTimerStart(&timer2, 100, KeyScan_Task_callback, NULL);
// multiTimerStart(&timer3, 1000, DataProcess_Task_callback, NULL);
// multiTimerStart(&timer4, 2000, Display_Task_callback, NULL);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
gtDrv_R_LED.On(>Drv_R_LED);
gtDrv_Y_LED.On(>Drv_Y_LED);
HAL_Delay(500);
gtDrv_R_LED.Off(>Drv_R_LED);
gtDrv_Y_LED.Off(>Drv_Y_LED);
HAL_Delay(500);
}
/* USER CODE END 3 */
}
可以看到2个LED等确实亮灭了。