参考
【编程之美】常用于单片机的接口适配器模式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);
}