高效使用单片机放弃程序中延时函数

最新更新时间:2014-01-16来源: 电源网关键字:单片机  延时函数 手机看文章 扫描二维码
随时随地手机看文章

第一次看到教程里Delay()函数的代码时我吓了一跳,竟然让单片机空转以实现和外界同步,这怎么可能?

试想,如果PC机CPU空转一秒,那么音乐会断一秒、画面会停顿一秒、下载文件会断一秒,这怎么可行?

我看到很多单片机程序,它们的单片机99.9%的工作时间都在打空转,99.9%大家可能感到有些危言耸听,那就让我们算一算:

已内部8M频的AVR单片机来说,单指令周期仅为1/8 = 0.125us,那一毫秒可以执行多少个单周期指令? 1%0.125*1000 = 8000

而我看到论坛里下到的绝大多数程序,两个延时函数之间代码的执行时间要远远小于8000个指令周期。

说实话,很多16K以上的程序,把所有延时函数去掉,总体能执行几毫秒就不错了。

换句话说,我说单片机的利用率小于0.01%还是口下留情了。

要说怎么解决问题,就要先找到问题,我问问大家,程序中,我们为什么延时?

原因很多,可能是外设速度太慢,也可能是为了躲过人眼视觉停留时间,等等。

总之就是与外界不同步,而我们想要同步。

所以说这些延时应该是很有道理的,我不否定这一点,但问题的关键这些延时空转,我们为什么不能把这些时间回收起来做一些别的事呢?

试想,如果把这99.9%的时间回收,那可以一笔相当巨大的资源。

有很多人有些特殊方法回收过这些空转时间,比如说在延时函数中做点事。

但这些往往都不通用,下面我说一些我的两种方法:

1、前后台模式下延时时间回收的方法:

前后台模式就是大家最常用的主程序大循环 + 中断的模式。

首先解决外设太慢问题,像串口、键盘、LCD、SD卡等IO,这些收发可以建立外部缓冲区。比如串口收发在中断中完成保存到缓冲区,而主程序操作缓冲区而不直接操纵串口,这已经看到很多人这样用了。但像矩阵键盘的缓冲区,我很少看到有人这么用,在中断中接收按键信息保存到缓冲区。

还有像LCD,我们一个个往显存中写数据是很浪费的,也应该建立缓冲,统一处理。

建立缓冲区这类方式中间有一些技术难点,比如像串口接收,无法判断对发是否全部发完,怎么办?可以设立定时,如果一个字节接收之后1ms之内没收到下一个,则认为接收完毕。这只是一个思想,具体应用大家掌握。

可能有人会说,除了外设太慢,还有像视觉停留的问题怎么解决,总不能让流水灯快到人眼都看不清吧。

这就我下面要说的问题,这些延时的时间怎么回收?就是全部放到定时中断中!

可能又有些人会说,书里、教程都说了,中断处理东西的时间要尽量短,你这样整个中断有太多判断、很长,时间很长,这不行。

这是一种教条的思想,把书读死了。可以在中断中这样处理,比如:

void (*Task)(void);

ISR

{

(*Task)(void);

}

中断里用的内容通过函数指针来调用,这样可以在主程序根据需要时任意改变要执行的任务,还可以改任务的周期。所用的判断都是在主程序需中执行,然后改变指针的指向,来确定中断中下一步的任务。

这样,在前后台系统中主程序将任务分配完,还有很多余力处理很多事。

比如有很多个键盘、LED点阵、数码管等,它们都需要实时响应,很容造成编程困难、响应迟钝,其实只要把延时的时间回收,处理这些就非常从容了。

可能还有人会说,有些项目用不了这么苛刻的时间,你回收的时间用不了,要那么多干嘛?

其实这时,你就可以用死循环扫描事件,可以实时响应。你的系统跟原来空循环延时比,实时性要高了不知多少倍。2、变异的协作式内核

先说说嵌入式操作系统的内核,简单的说,它就是个任务调度器,让多个任务在同一个CPU上同时执行,所谓同时也是相对的,无非就第一个任务执行几毫秒、第二个任务在执行几毫秒。。。外表看起来就是同时执行。

至于可剥夺式内核和协作式内核的区别,大家可以百度一下。

说道能在单片机上用的嵌入式操作系统,大家会说出一些如uCosII、FreeOS等操作系统。

还有很多人对这些操作系统十分抗拒、十分反对,他们的理由是什么?

1、这些操作系统占用大量RAM、ROM

2、这些实时操作系统所谓的实时是相对非实时操作系统的,跟裸机比实际上是慢了

这些理由不是没道理,因为这些商用操作系统都是可剥夺式内核,它们的原则是保证最高优先级任务在可确定的时间内响应。

它们的有优点是任务切换时间是确定的,不会随任务的多少而改变。

有了这些确定性,让它们在商用产品大放光彩。因为其时间稳定性。

但它们的缺点也很明显,中断级节拍浪费很多时间。任务间同时调用时引发同步问题而引入许多如信号量、邮箱等机制浪费大量RAM、ROM。

综上,可剥夺式内核稳定可定量,在越高级的单片机上越有优势,在8位机上可用,但需要大量裁剪,并不一定合适。

而协作式内核的核心思想是什么?它不像剥夺式内核保证最高级任务速度最快,而是保证所有任务的平均速度最快!

正如我前面的说法,我连续两个延时函数之间的代码很难超过1ms,甚至很难超过100us,我们可以将其忽略。这样10个任务,第一个执行完主动放弃单片机控制权,交给第二个任务,第二个任务执行完主动放弃控制权,交给第三个任务。10个任务之间无间隙,每一个任务需要延时时,就主动放弃控制权。

基于这种思想,我们的就达到了回收空转延时的目的,而且应为每个任务是执行完后主动放弃,所以不存在剥夺式内核的同步问题,基本不需要邮箱、信号量等机制,对RAM、ROM的要求就非常低了。

这样来看,协作式内核非常适合8位机。但可能有太多嵌入式系统的书中对剥夺式内核不分场合的认可,造成很多人误解。而且uCos等系统的权威,也让很多RTOS作者争相效仿,没用对8位机的场合做合理分析。

商用系统中没有协作式内核,而民用的,还少有优秀的协作式内核,都是基于传统节拍。

传统协作式内核需要定时中断为时钟基准,也会间歇性打断任务,造成不必要的损失,这并不是我们想要的。

我们其实可以仅仅是让定时器以大分频系数开着, 而不给其产生中断的机会。当任务将要放弃使用权时,读取定时器,作为时钟基准,然后清零。

做法一句两句说不清,而效果是什么?可以做到任务是以不受干扰,与裸机相同的工作状态,这是传统协作式内核做不到的,而仅当它需要延时了,才放弃使用权,将延时的时间给其它任务。这正符合我全文的目的 -- 回收空转延时时间,这样的内核体积会非常小,运行方式与裸机无异,仅仅是把空转延时时间干些其它事。对使用者还没什么要求,不想以往系统那么复杂。

可惜市面上并没有基于这种方式的内核,我已经写了一个,非常精简,运行稳定。但作为一个想应用实际的内核,还需要检验。

关键字:单片机  延时函数 编辑:探路者 引用地址:高效使用单片机放弃程序中延时函数

上一篇:精心总结单片机、PSOC、FPGA三者的主要区别
下一篇:单片机晶振不起振故障原因及排除方法介绍

推荐阅读最新更新时间:2023-10-12 22:34

STM32系列MCU开发环境的搭建
导读: 选择某款MCU的学习一般从其开发环境的搭建开始,即安装支持该处理器的编译、调试软件。其中最为关键的就是编译器的选择与安装,编译器的具体工作原理和作用可以参见本公众号“嵌入式ARM篇”合集文章《01_编译过程简介及为什么需要交叉编译器》。支持STM32系列MCU的编译软件有很多种,开发编译环境也各不相同,其中Keil uVision5(以下简称Keil5)编译软件以其简单易用的特点,应用最为广泛。 为了便于MCU的快速推广,开发商积极推出了各自的底层应用函数库,便于工程师的快速开发与应用。STM32系列MCU目前主要有两种函数库,一种是标准库,一种是HAL库(以下简称硬件库)。在使用标准库开发不同系列的MCU时,其中的功
[单片机]
STM32系列<font color='red'>MCU</font>开发环境的搭建
stm32F4系列MCU,窗口看门狗 WWDG中的bug
stm32F4系列MCU,窗口看门狗 WWDG中的bug。 1. 如果使能预喂狗中断,那么必须满足如下两点 (1)在开启wwdg中断之前,需要先将 SR 寄存器中的EWI标志位清零,否则会看门狗会不断复位 (2)在wwdg_irq里加上一小段延时,否则看门狗会不断复位 2. 如果系统里还有其他中断,比如按键,在按键中断中设置一个变量,这个变量在wwdg_isr中读取,来决定是否停止喂狗 这样按下按键以后,系统直接就飞了。 这里给出一个测试代码。 如下所示。 / * @file USART/USART_Printf/main.c * @author MCD Appl
[单片机]
智能点阵电子显示屏控制系统设计
  1 引 言    LED电子 显示屏是一种显示文字、图像等视频信号的理想的公众信息显示媒体,在提高政府行政部门、企事业单位服务公众的形象和服务档次方面起到了良好的作用。本文设计的LED 电子显示屏除具备电子屏的常规功能外,还进行了设计,通过Internet对电子显示屏进行远程智能控制。   2 硬件电路设计   硬件设计以控制器AT89S52 为控制核心,基于RTX51实时多任务操作系统,结合时钟设计以及所需设计的外围电路,完成 LED驱动 、控制以及显示。整个硬件设计框图如图1所示。        图1 点阵电子屏设计硬件原理框图   2. 1 单片机系统设计   单片机选用ATMEL公司生产
[电源管理]
智能点阵电子显示屏控制系统设计
ARM7单片机(学习ing)—(四)、定时器—01
大晚上的~~ 直接把文件给整理一下~~ 然后剩下的历程明天再说吧~~ 四、定时器 四—(01)、定时器相关应用和寄存器的介绍~~ 定时器0和定时器1出了外设基地址以外,其它都相同~~ 2、应用以及相关的描述: 3、管脚描述 4、寄存器描述: a、中断寄存器 b、定时器控制寄存器 c、定时器计数器 d、预分频寄存器 e、预分频计数器寄存器 f、匹配寄存器 g、匹配控制寄存器 h、捕获寄存器 i、捕获控制寄存器 j、外部匹配寄存器
[单片机]
ARM7<font color='red'>单片机</font>(学习ing)—(四)、定时器—01
51单片机实现菜单问题
这个思路应该是没问题的,但是需要设置的状态量啥的有点多,还有一些菜单项的id值啥的都不能冲突,还有那个按键扫描填充状态值函数,理论上是具有可实现性的,估计也得动会脑筋或者还会有各种bug。这个菜单系统对于具有深层次菜单项时候优势才明显,其实一般做的菜单,就用那个已经成熟且我多次用的结构体方式实现的就足够了,而且很容易实现。我现在就不需要花大量精力去思考这个如何完善和实现性了(而且emwein那些gui早就考虑过这些问题了),还是需要思考更重要,更有价值有意义的问题,操作系统内核的实现 关于12864屏幕上绘制菜单图标,圆形,矩形啥的,没必要深入去研究,只要会画一个具有代表性的矩形即可,实际上这些直接用取模的方式更加直接明了,
[单片机]
51<font color='red'>单片机</font>实现菜单问题
51 单片机汇编语言--矩阵键盘的驱动
用这个矩阵键盘做单片机输入,插 P1 口的 P1.0~P1.6。 想问的是,当: 按下 1 键 P0 口的 P0.0 输出高电平; 按下 2 键 P0.1 输出高电平; …… 一直到 8 键就可以了。 还有一个要求,当按下一个键时延时5秒并锁住其它按键,5秒之后回到起点。用汇编语言 ;===================================================== ;如下即可: ORG 0000H START: MOV P0, #255 MOV P1, #255 CLR P1.0 NOP JNB P1.4, K1 JNB P1.5
[单片机]
51 <font color='red'>单片机</font>汇编语言--矩阵键盘的驱动
STC单片机的下载接口
这几天在弄一个STC下载接口,本来想着电路比较简单,个人感觉比较容易做就可以做出来了。谁知画那个PCB图都花了九牛二虎之力,还要某人帮忙(哈哈不点名,人家很低调的)。终于画好,拿去物电做板。谁知天公不作美啊,物电的那台打印机居然打了几张纸就不工作啦。好在,我打了一张出来,那个封装基本符合,有几个要改一下,还有线太小了,我把它加大到0.6MM,打出来感觉好看了很多,后来弄那个打印机,居然不见了最后那张。后来那个打印机就是不工作,没办法,只能打道回府。第二天再杀过去,一开始打印机好好的,后来打印机又不行了。后来发现纸要很好才行的。后来在物电的人指导下,顺着步骤一下步步往下做。 首先看封装对不对,封装没问题,然后打在油纸上。
[单片机]
STC<font color='red'>单片机</font>的下载接口
TI新推29款Stellaris MCU,价格下降13%
  2009 年 10 月 22 日,北京讯——日前,德州仪器 (TI) 宣布推出价格更低的、基于 Stellaris ARM Cortex-M3 的全新微处理器产品,扩展了旗下微处理器 (MCU) 阵营。29 款全新 Stellaris MCU 包括针对运动控制应用、智能模拟功能以及扩展的高级连接选项等的独特IP,还可提供更大范围的存储器引脚兼容以及最新紧凑型封装,可显著节省空间与成本。   由于 Stellaris MCU 卓越的集成度已融入 TI 的规模效应之中,由此带来的高效率可使整个 Stellaris 系列的价格平均下降 13%。TI 综合StellarisWare软件可为每款器件提供支持,从而可加速能源、安全以
[单片机]
TI新推29款Stellaris <font color='red'>MCU</font>,价格下降13%
小广播
最新电源管理文章
换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved