参考
【编程之美】常用于单片机的接口适配器模式C语言实现.pdf
- 基于以上内容稍作修改
- 结合RT-Thread操作系统
- 设计了面向对象的LED驱动接口
- 可移植性大大提高,移植文件时无任何全局变量
- 将对象的要素作为指针传递,无需考虑参数过大导致出入栈耗时问题
- 函数作为方法封装
源文件
/* * Copyright (c) 2020 - ~, HIT_HERO Team * * LED MODULE SOUCE FILE * Used in RT-Thread Operate System * * Change Logs: * Date Author Notes QQ * 2020-06-02 WangXi first version 1098547591 */#include "Module_LED.h"/* User Code Begin*/void LEDTest(int argc,char **argv){ rt_err_t res = RT_EOK; MODULE_LED dev_led_1 = {GET_PIN(C, 3),MODULE_LED_ON}; res = Module_Led_Config(&dev_led_1); if(res != RT_EOK){ rt_kprintf("Error: Some wrong happened while led config\n"); return; } if (argc < 2){ rt_kprintf("Error: Command missing arguments\n"); return; } if(!rt_strcmp(argv[1], "-on")){ dev_led_1.Enable(&dev_led_1); } else if(!rt_strcmp(argv[1], "-off")){ dev_led_1.Disable(&dev_led_1); } else{ rt_kprintf("Error: Command not found\n"); }}MSH_CMD_EXPORT(LEDTest , LEDTest(PC3) <-on|-off>);/* User Code End *//* Static Method */static void Module_LedInit(MODULE_LED *module);static void Module_LedToggle(MODULE_LED *module);static void Module_LedEnable(MODULE_LED *module);static void Module_LedDisable(MODULE_LED *module);/* Global Method */rt_err_t Module_Led_Config(MODULE_LED *Dev_LED){ if(Dev_LED->Init==NULL && Dev_LED->Toggle==NULL && Dev_LED->Enable==NULL && Dev_LED->Disable == NULL ){ /* Link the Method */ Dev_LED->Init = Module_LedInit; Dev_LED->Toggle = Module_LedToggle; Dev_LED->Enable = Module_LedEnable; Dev_LED->Disable = Module_LedDisable; } else{ rt_kprintf("Warning: Module Led is Configed twice\n"); return RT_ERROR; } /* Device Init */ Dev_LED->Init(Dev_LED); return RT_EOK;}/* Static Method */static void Module_LedInit(MODULE_LED *module){ rt_pin_mode(module->pin, PIN_MODE_OUTPUT); rt_pin_write(module->pin, module->status);}static void Module_LedToggle(MODULE_LED *module){ rt_pin_write(module->pin, !rt_pin_read(module->pin)); module->status = rt_pin_read(module->pin);}static void Module_LedEnable(MODULE_LED *module){ rt_pin_write(module->pin, MODULE_LED_ON); module->status = rt_pin_read(module->pin);}static void Module_LedDisable(MODULE_LED *module){ rt_pin_write(module->pin, MODULE_LED_OFF); module->status = rt_pin_read(module->pin);}/************************ (C) COPYRIGHT 2020 WANGXI **************END OF FILE****/
头文件
/* * Copyright (c) 2020 - ~, HIT_HERO Team * * LED MODULE HEAD FILE * Used in RT-Thread Operate System * * Change Logs: * Date Author Notes QQ * 2020-06-02 WangXi first version 1098547591 */#ifndef _MODULE_LED_H_#define _MODULE_LED_H_#define _LED_POSITIVE_POLE //RESET Enable LED//#define _LED_NEGETIVE_POLE //SET Enable LED#include <rtthread.h>#include <rtdevice.h>#include <board.h>enum LED_STATION{#ifdef _LED_POSITIVE_POLE MODULE_LED_ON = 0, MODULE_LED_OFF#endif#ifdef _LED_NEGETIVE_POLE MODULE_LED_OFF = 0, MODULE_LED_ON#endif };struct _MODULE_LED{ /* Property */ rt_base_t pin; /*!< Specifies the LED module pins to be configured. This parameter is defined by function @ref GET_PIN(GPIOPORT, GPIO_PIN_NUM) */ rt_bool_t status; /*!< Specifies the LED init status. This parameter is defined by @ref LED_STATION */ /* Method */ void (*Init)(struct _MODULE_LED *module); void (*Toggle)(struct _MODULE_LED *module); void (*Enable)(struct _MODULE_LED *module); void (*Disable)(struct _MODULE_LED *module);};typedef struct _MODULE_LED MODULE_LED;/* Glodal Method */rt_err_t Module_Led_Config(MODULE_LED *Dev_LED);#endif /************************ (C) COPYRIGHT 2020 WANGXI **************END OF FILE****/
使用
MODULE_LED dev_SystemLed = {GET_PIN(C, 2),MODULE_LED_ON}; Module_Led_Config(&dev_SystemLed); while (1){ rt_thread_mdelay(500); dev_SystemLed.Toggle(&dev_SystemLed); }