读一本书一哥谈谈对时间触发的一些理解

9f748cd9575386f3c12762e0286fe76d.png

\\\插播一条:

自己在今年整理一套单片机单片机相关论文800余篇

论文制作思维导图

原理图+源代码+开题报告+正文+外文资料

想要的同学私信找我。

58efbd3fff14cdec4845f464628e97cf.png

读《时间触发嵌入式系统设计模式》一书谈谈个人对嵌入式编程的一些理解

入门阶段

这个阶段,我们最常用的程序构造根本都是这种while大循环构造,达到的功能主要以单任务为主,由于我们大局部时长都是在进修单片机自身的资源怎么样运用(I/O, I2C, SPI, 串口),嵌入式开发工具、环境搭建(Keil软件,ISP下载软件),C语言根底以及单片机怎么样配合外部设备(按键,数码管、LED灯、1602,12864显示器,时钟芯片,光电传感器、电机驱动模块)来达到我们一些想要的功能,我们的程序也相对来说比较简略。

7263e6f452e6fb47f576266e82c19ac7.png

 典型的点亮一颗LED灯程序构造

书中前面1~8章主要是介绍这些软件的一些根本的概念和根底的硬件知识

进阶阶段

203f059dfbfcaf85bf4c4928b9b8bee1.png

来自百度图片

有了入门阶段的知识积攒,我们对单片机有了一个全新的认识,迫不及待的想通过单片机达到一些更复杂、更炫酷的功能;在这个过程中我们慢慢的发现,原有的程序构造很难满足我们的程序开发需求,可能用按键控制LED灯亮灭问题不是太大,我们想想办法根本都能达到相应功能。

b2907f56a009072e2e6a0c086acdfffd.png

 按键控制LED灯程序构造

但是像下面的一个典型的电子钟:要达到按键的输写,又要控制数码管的以一定的频次(>50Hz)刷新,同时还要以一定的周期与时钟芯片通信以及控制蜂鸣器声音,用原有的大循环也是能达到,但是我们须要耗费大量的精力在各模块之间怎么样配合,带来的程序可移植性也很差。

119468f5fd9718fd6ec464471acee984.png

 一个典型的电子钟程序构造

书中还特意举了洗衣机的例子,这是一个有多个输写,同时有多个输出控制的程序,很多输写输出都是随机的,但是你又不能错过,不然整个洗衣机的体验会很差,当然作者也给出了攻克思维

1337bcdeb9faff58bbc87eb5214b1194.png

 书中提到的洗衣机控制框图

37db03d404998d6cea24f7200786bdad.png

下图是贯通全书核心思想的程序构造

 贯通全书的程序构造

运用这种方式来设计程序,也对我们自身的知识储备提了一些要求,要掌握模块化式的文件怎么样编写,这种模块化的思想不关是在程序设计中应用非常广泛,在各行各业中应用同样广泛,我个人觉得其核心思想就是,所有东西都是由零部件组成,这些零部件是能够"规范化"的,了解这种思想对我们从事嵌入式行业的人员来说是非常重要的,一方面会为你节省大量时长,另一方面你所储备的"规范模块"在不断的累加,你会有更多的时长去考虑更高层次的东西,久而久之就成为这个行业的专家,没论你是从事技术岗位还是以后想走向管理岗位都是非常有用的。

93162eb8497cd03c8a33771581c2ca99.png

 汽车底盘构造(摘自搜狐)

9c17f1208d157ba3b286dde163fb3bb8.png

 汽车剖视图(摘自搜狐)

第9章主要就是介绍这种模块化方面的软件体系构造方面的内容,就算不了解时长触发式系统设计模式里面的调度器设计思维,在原来大循环程序的根底上也是能够使用这种模块化的程序设计思维,假如:将LED灯亮灭程序拆解成LED显示模块和主函数模块。

8902731be61c69824297385abf2f0729.png

 main.c文件

beb6b7d7265958d9c824a09c1ed6ec25.png

模块.h文件

d1ef085a6815e89dbe05da9d5744e5cb.png

 模块.c文件

对于多任务,我们可能会想到运用定时器的溢出中断来攻克这方面的问题,作者也尝试着使用这种方式来攻克,假如说我们51单片机有三个定时器,我们能够通过配置每个定时器的中断周期来达到不同周期任务的执行。

4292604a84d9286c4da3b1bcbc7d9e14.png

 运用多个定时器中断达到多任务

b94d3833c530cb4c88d4a5817601bb78.png

书中提到的多个定时器执行多任务方式

显然对于复杂的系统,我们不止这么几个任务,并且我们的单片机定时器资源都是有限的,那么对于复杂的多任务处理显然是不适宜的,这个时候,书中初始给出调度器的方案来攻克这方面的问题。

a091983694743afa7418220e881bf49e.png

 一个根本的调度器原型

像我在平时写嵌入式程序的过程中,一般运用的是时长片轮询方式,前几天在抖音上看到有一个哥们也是用的这种方式设计程序,我在深圳工作那会儿,公司里也有人用这种方式书写程序,至于该书中提到的调度器(合作式,抢占式),大家能够先自行去了解下,后期我会专门来分析这些优秀的调度器

8ea132fcd0d0f77f40b9ef8455a574d1.png

 时长片轮询方式程序构造

这种方式的核心思想就是用一个定时器来产生基准的时长,依据详细的任务来定,我一般运用1ms周期产生定时中断,其次给每个任务定义一个任务延时变量,初始化后在定时器中不断的做减法运算,当减到0时,变更相应的任务状态标志,任务执行过程中又重新对任务状态标志和任务延时变量进行初始化,其他任务也是同样的操作;这个定时器就如同我们公司领导一样,不断的以一定的周期给我们指派任务,其次让我们去执行。

20ff1c8ffb825f2f580f1d0e8e5f4b81.png

 图片来源于百度

写在最后

顺便给大家提供几本优秀的嵌入式书籍,大家能够参照下

b75a2dde952b31119efafeb867da4890.png

《时长触发式嵌入式系统设计模式》一书作者也提到,全书讲的是一种设计模式,这种设计模式不局限于详细单片机(51,STM32,PIC包含arduino都能够用),整个软件行业的开展我个人觉的其实都是在不断的减轻设计者、开发工程师的工作量,把那些反复须要做的工作都交给软件工具或者说优秀的软件框架来做,从汇编语言到C语言在到后面的C++语言,python语言,软件自身的易用性在不断的得到改善,随着科学技术的进步以及越来越多的厂商打造的生态以及众多的优秀嵌入软件设计思维的提出,以后的嵌入式软件开发方式跟此时的windows程序和android程序开发根本没什么差别,更有甚直接采用拖框图的方式开发(matlab基于模型的开发方式)。

fa23f0f3c9db390ebbf2fe7216acf307.png

这里也有官网提供的一本书,能够在官网下载浏览

模块化式软件设计思维能够参照这本书《嵌入式系统构件》,作者是jean j.labrosse,uCOS的创作者,国内很多嵌入式实时系统的开发者都是启蒙于这位大佬,这本里面讲的是模块化式的设计思维,主要是为uCOSII提供的配套,但是能够移植到非uCOS系统的嵌入式工程中,里面提供了很多有效且已经项目验证的模块化文件,假如说输写输出模块,多功能按键,数码管驱动,串口通信等,这些模块的设计思维对我们现实中项目开发非常有用,希望对大家有借鉴作用。

c0afa45cd1424d44883a80de24bb0db1.png

29a008774f94f110ddbde701206fa143.png3d634c08dc07eaeb2cca8afd11df6e72.png6fd52c6203d6c4eda27e876c98f8beab.png

【文章福利】:小编整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!~点击绿色通讯软件搜索airuimcu加入。

想要学习单片机的朋友 ,做毕业设计的同学,关注我们,口令一哥,与导师一起学习成长,共同进步,还有更多资料领取。

说了这么多,大家记得留意下方评论第一条(或者私信我)有干货~

-END-

*本文系网络转载,版权归原作者所有,如有侵权请联系删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
您是在问如何在Verilog中实现在一段时间内随机触发的功能吗? 在Verilog中,您可以使用`$random`系统函数来生成随机数。结合使用`$time`系统函数可以获取当前的模拟时间。您可以通过比较模拟时间与预设的时间范围来触发某个事件。 以下是一个示例代码片段,展示了如何在一段时间内随机触发一个事件: ```verilog module RandomTrigger ( input wire clk, output reg trigger ); reg [31:0] start_time; reg [31:0] current_time; reg [31:0] duration; // 触发时间范围 initial begin start_time = $time; // 记录开始时间 duration = 100; // 设置触发时间范围为100个时间单位 end always @(posedge clk) begin current_time = $time; // 获取当前时间 if (current_time - start_time >= duration) begin if ($random % 2 == 0) begin // 当前时间超过触发时间范围,并且随机数为偶数时触发 trigger <= 1'b1; end else begin trigger <= 1'b0; end end else begin trigger <= 1'b0; end end endmodule ``` 以上代码中,使用了一个时钟信号`clk`作为模拟时间的驱动,`trigger`是一个输出信号,用于表示是否触发事件。在`initial`块中,我们记录了开始时间和设置触发时间范围。在`always @(posedge clk)`块中,通过比较当前时间与开始时间以及触发时间范围,来决定是否触发事件。同时,使用`$random`函数来生成随机数,并通过判断随机数的奇偶性来触发事件。 请注意,以上代码仅为示例,实际应用中可能需要根据具体需求进行修改。同时,Verilog中的随机数生成函数`$random`并不是真正的随机数生成器,它生成的数值是伪随机的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片机一哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值