IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机工程经验 - 分层思想 -> 正文阅读

[嵌入式]单片机工程经验 - 分层思想

单片机工程经验 - 分层思想

单片机工程经验是本人对单片机编程从业以来的一点经验总结,希望能为大家的职业生涯提高一点点效率,不要陷入整日重复造轮子的境地。人生不只有工作,还有生活。

分层思想

分层思想其实一点都不神秘,它就是简单的把一个项目分成多个层级,仅可上层调用下层接口,且不能跨层级调用。这里我简单的把单片机程序分为3层。

应用层
驱动层
硬件层

矩阵键盘为例子

这里我们以矩阵键盘为例子。
矩阵键盘

  1. 将ROW1 ~ ROW4设置为输出模式、将COL1 ~ COL4设置为输入。
  2. 将ROW1输出低电平,ROW2、ROW3、ROW4输出高电平。
  3. 读取COL1 ~ COL4电平,如果有一列电平为低,则相应的按键按下,比如K2按下时COL2就会收到低电平,而此时K5~K16无论是否按下,对这个电平都没有影响,因为即使按下,也只是增加一个3.3V的上拉。
  4. 将不同的ROW输出低电平,其他输出高重复读取COL上的电平。这样每次哪一行上的ROW置低就能读取到这一ROW上4个按键的状态。

分层

硬件层

ROW1 ~ ROW4,COL1 ~ COL4需要连接到单片机的8个普通IO口上,而不同单片机的IO口操作寄存器或者库函数都不同,如果这里不做分层,那么换一个单片机就得重写矩阵键盘的驱动,这显然是我们不想要的。

首先我们对IO口操作进行抽象化处理,我们发现IO口操作无非就是设置IO输入输出模式,输出高低电平,检测输入电平的高低。
然后我们就可以抽象出这么三个函数

drv_pin_mode(int id,int mode);
drv_pin_write(int id,int level);
drv_pin_read(int id);

因为不同的IO口都可以单独配置,所以我们要将IO传入函数,这里不同的id就能代表不同的IO口。
不同单片机这三个函数的实现都不同,但这没有关系,只要我们把这三个函数的实现单独写成一个源文件,那么换单片机是不是只要换这个源文件就可以了?这样我就实现了硬件层的分层。

驱动层

驱动层就需要考虑我们需要为上层应用层提供什么东西,比如矩阵键盘需要提供哪个按键被按下、led需要提供亮灯灭灯闪烁、温度传感器需要提供温度值。而对上层应用来说,我不需要知道你是怎么实现的,驱动只要提供应用层想要的东西就行了。
对于矩阵键盘来说,应用层只需要一个函数

char get_key_date();

应用层实时调用这个函数就可以知道哪个按键被按下了。
或者我们可以使用回调函数的方式。

void set_key_callback(void (*key_date)(char key));

上层应用先写好函数,这个函数可以处理不同的键值按下,然后调用上方函数设置好回调,当矩阵键盘驱动检测到按键被按下时就可以自动调用这个回调函数。

采用这两种方法就可以实现矩阵键盘驱动写好后,下次需要使用可以直接将驱动复制而无需更改任何代码。

矩阵键盘驱动实现

首先我们思考矩阵键盘和硬件有哪些关联。

  1. ROW和COL的数量是不确定的
  2. 每个ROW和COL对应的IO口是不确定的。

因为这两个不确定,所以我们需要把这两个不确定的条件传入驱动

void set_key_row_col(int *rowMap,int rowNum,int *colMap,int colNum);

这里rowMap是ROW列的引脚id数组,rowNum是数组长度,col也同理。
比如row的id是1357,col的id是2468,那么可以这样调用

int row[] = {1,3,5,7};
int col[] = {2,4,6,8};
set_key_row_col(row,4,col,4);

在驱动层,我们就可以将这几个参数保存下来,以便后续使用。

接着我们要思考矩阵键盘的具体实现了,我们知道一开始需要将row设置成输出,col设置成输入,所以可以定义一个初始化函数

void keyi_init()
{
	int i = 0;
	for(i = 0; i < rowNum;i++)
	{
		drv_pin_mode(rowMap[i],PIN_MODE_OUT);
		drv_pin_write(rowMap[i],1);
	}
	for(i = 0; i < colNum;i++)
	{
		drv_pin_mode(colMap[i],PIN_MODE_IN);
	}
}

然后我们就要考虑轮流去读取col的值。

void key_thread()
{
	static int rowIndex = 0;
	int i = 0;
	drv_pin_write(rowMap[rowIndex],0);// 将某一row输出低电平
	for(i = 0; i < colNum;i++)
	{
		if(drv_pin_read(colMap[i]) == 0)// 如果读取到低电平
		{
			if(key_date)// 如果用户设置了回调函数
			{
				key_date(i*rowNum + rowIndex);// 执行回调函数并输入键值
			}
		}
	}
	drv_pin_write(rowMap[rowIndex],1);// 将这一row输出高电平
	rowIndex++;// 换到下一轮输出低电平
	if(rowIndex >= rowNum)// 如果全部row都检查过了就回到第 0 row开始检查
	{
		rowIndex = 0;
	}
}

只要应用层不断的去调用key_thread()函数,那么就可以十分简单的获取到键值。当然这个驱动没有考虑按键消抖,辨别长按双击等,这里只介绍思想,不作深入研究,你可以根据这些思想去思考怎么完善这个程序。

应用层

经过上述介绍,应用层需要完成的事情非常简单

  1. 定义好row和col的id,然后调用set_key_row_col函数
  2. 编写好回调函数然后调用set_key_callback告知驱动
  3. 调用keyi_init函数对驱动进行初始化
  4. 不断调用key_thread函数完成驱动的操作

至此,我们就可以发现,无论是什么单片机,无论几个口的矩阵键盘,只要将硬件层和驱动层复制到项目中,都只需要上述4部即可完成对矩阵键盘的使用。

总结

分层思想的好处是,硬件层和驱动层都只需要编写一次,极大的减少工作量,工程师可以专心思考应用层的实现。而由于这两层完全不涉及逻辑,可以轻松编写单元测试代码,只要一次测试通过,以后这两层代码将安心使用而不用担心bug的出现,减少测试压力。
当然分层思想也不是没有缺点,首先就是资源占用的增加,分层势必增加许多冗余代码,而且每一层都有自己的资源分配,尽管不同层级的资源代表的东西是相同的,但是为了减少耦合不得不另外分配资源,同时部分编译器可能对调用堆栈有限制,分层的实现会加重函数调用的深度。而且部分的代码可能不支持,比如51单片机对于函数指针的使用可能会出现问题。
总结下就是,对于资源丰富的现代单片机建议使用分层思想来构筑程序,这样的程序不仅写的快而且质量高。如果单片机是落后的八九十年代的产品,那还是不要用了。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-02-14 21:20:17  更:2022-02-14 21:21:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:45:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码