【编程之美】常用于单片机的接口适配器模式C语言实现

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lihuidashen/p/12875018.html
微信链接:https://mp.weixin.qq.com/s/rXfKnFrBY-9OjnzCgBtQ6g
前言
通俗的讲,适配器模式是将一个类的接口转换成客户希望的另外一个接口,在我们编写程序的时候,尤其是在我们使用到单片机做项目的时候,经常会用到。

但是往往我们做项目写程序的时候,并没有想到那么多,如果在不带操作系统的情况下,想要整个框架易于移植,易于理解,那么我们真的需要好好想想这个设计模式怎么写了。
下面我根据自己的项目经验,来说说适用于单片机的接口适配器模式的实现。大佬勿扰,多多指教。
一般实现
在我们做项目的时候,一般的实现,可能我们会这样写代码
// FileName: test.c
// 来源:公众号【技术让梦想更伟大】
#include <stdio.h>
#include “ExternModule.h” int main(void)
{ /*初始化*/
vAllInit(); while(1)
{ /*项目逻辑*/
vLogicModule1(); vLogicModule2(); }
}
在其外部文件中,调用相对应的初始化函数以及逻辑函数,但是当我们项目很复杂的时候,逻辑关系也层层覆盖、交替的时候,这样的写法就有些不是很好看了。
接口适配器
首先我们还是要来定义数据结构,一般这样的项目分为这样几个步骤:
- 初始化
- 输入
- 处理
- 输出
我们把这四个步骤封装起来,再定义数据结构如下:
// FileName: test1.c
// 来源:公众号【技术让梦想更伟大】
/* 适配器类型定义 */
struct _ADAPTER
{
void (*Init )( void ); //初始化函数
void (*Input )( void ); //输入转换函数
void (*Process )( void ); //处理函数
void (*Output )( void ); //输出转换函数
};
typedef struct _ADAPTER ADAPTER ;
那么初始化函数,我们先来这样定义
// FileName: test1.c
// 来源:公众号【技术让梦想更伟大】
/* 模块初始化 */
void moduleInit( ADAPTER *module )
{
if( module->Init != NULL )
{
module->Init();
}
}
模块的逻辑运行,我们可以这样使用
// FileName: test1.c
// 来源:公众号【技术让梦想更伟大】
/* 模块逻辑运行 */
void moduleRun( ADAPTER *module )
{
// 模块输入适配接口不为空,则执行输入适配操作
if( module->Input != NULL )
{
module->Input();
} // 模块处理接口不为空,则执行处理操作 // 模块输出适配接口不为空,则执行输出适配操作
}
在定好了这些数据结构以及封装之后,我们在每个子模块中都只需要调用这个模式即可。例如有一个需求,需要点一个灯,我们建立独立文件,在文件中申明
// FileName: led.c
// 来源:公众号【技术让梦想更伟大】
/*led灯运行 */
ADAPTER LedModule = { vLedInit, NULL, vLedRunModule, NULL };
那么接下来只需要对初始化函数,逻辑运行函数进行描述就可以了。同理,我们需要一个按键的功能,在另一个独立文件申请
// FileName: key.c
// 来源:公众号【技术让梦想更伟大】
/*按键运行 */
ADAPTER KeyModule = { vKeyInit, NULL, vKeyRunModule, NULL };
这样的话就便于我们拆分需求,便于移植,同时程序也就模块化了,最后我们在main文件中做的就是调用这些函数就行。我们需要这样做。
// FileName: main.c
// 来源:公众号【技术让梦想更伟大】
/*主函数 */
void main( void )
{ moduleInit( &LedModule );
moduleInit( &keyModule ); while( 1 )
{
moduleRun( &LedModule );
moduleRun( &keyModule );
} }
最后
main函数就是这么简单了,整个架构也是很清晰,体现出编程之美
推荐阅读

【编程之美】常用于单片机的接口适配器模式C语言实现的更多相关文章
- 【Android 应用开发】Android 网络编程 API笔记 - java.net 包相关 接口 api
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
- Android 网络编程 API笔记 - java.net 包相关 接口 api
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
- java并发编程之美-阅读记录1
1.1什么是线程? 在理解线程之前先要明白什么是进程,因为线程是进程中的一个实体.(线程是不会独立存在的) 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程中的 ...
- 【编程之美】2.5 寻找最大的k个数
有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2 ...
- 【编程之美】CPU
今天开始看编程之美 .第一个问题是CPU的使用率控制,微软的问题果然高大上,我一看就傻了,啥也不知道.没追求直接看答案试了一下.发现自己电脑太好了,4核8线程,程序乱飘.加了一个进程绑定,可以控制一个 ...
- 编程之美_1.1 让CPU占用率曲线听你指挥
听到有人说让要写一个程序,让用户来决定Windows任务管理器的CPU占用率. 觉得很好奇.但第一个想法就是写个死循环.哈哈.不知道具体的占用率是多少,但至少能保证在程序运行时,CPU的占用率终会稳定 ...
- 编程之美的2.17,数组循环移位 & 字符串逆转(反转) Hello world Welcome => Welcome world Hello
代码如下:(类似于编程之美的2.17,数组循环移位) static void Main(string[] args) { string input = "Hello World Welcom ...
- [质疑]编程之美求N!的二进制最低位1的位置的问题
引子:编程之美给出了求N!的二进制最低位1的位置的二种思路,但是呢?但是呢?不信你仔细听我道来. 1.编程之美一书给出的解决思路 问题的目标是N!的二进制表示中最低位1的位置.给定一个整数N,求N!二 ...
- 编程之美 两个叶子的节点之间 最大距离 变种 leecode
提交地址: https://oj.leetcode.com/problems/binary-tree-maximum-path-sum/ 说一下思路http://www.cnblogs.com/mil ...
随机推荐
- util.Date与sql.Date的异同以及相互转换
Java中有两个Date类 一个是java.util.Date通常情况下用它获取当前时间或构造时间 另一个是java.sql.Date是针对SQL语句使用的,它只包含日期而没有时间部分 两个类型的时间 ...
- stand up meeting 1/12/2016
part 组员 工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 UI测试和调整:页面跳转调整 3 查漏补缺,扫除UI b ...
- A 蚂蚁觅食
A. 蚂蚁觅食(一) 单点时限: 1.0 sec 内存限制: 512 MB 一只饥饿的小蚂蚁外出觅食,幸运的小蚂蚁发现了好多食物,但是它只有一次搬食物的机会.可因为力气太小了,它不能搬走重量超过自己体 ...
- python selenium模块 xpath定位
''' 附w3xpath语法地址 https://www.w3school.com.cn/xpath/xpath_syntax.asp 总结: 返回匹配到所有符合条件的第一个节点,对象是 <cl ...
- [YII2] 文件上传类
//测试文件上传类 public function actionCreate() { $model = new Lvyou(); $upload_model = new \app\models\Upl ...
- python第三方库安装与卸载
一.检查python环境是否正常 python安装完毕并设置环境变量后,可在cmd中运行python查看,显示版本等信息 二.查看已经安装的第三方库 通过pip list可查看已安装的库,以及对应的 ...
- 从零开始学习docker之docker的安装
一.Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程 ...
- tensorflow1.0 构建神经网络做图片分类
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnist = input_dat ...
- Docker 中如何安装配置 Nginx
拉取 nginx 最新版镜像,然后简单启动一个 nginx 容器: docker pull nginx:latest docker run --name nginx01 -d -p 80:80 ngi ...
- 005.Ansible de palybook简单使用
一 Ansible Playbook简介 ansbile-playbook是一系列ansible命令的集合,利用yaml 语言编写.playbook命令根据自上而下的顺序依次执行.同时,playboo ...