一、单片机延时分类
1、软件延时:在程序中使用循环等语句来消耗一定的时间,从而实现延时,这种方式简单易用,但会占用CPU资源,影响程序的响应性能。
2、硬件延时:通过外部电路或者定时器等硬件模块来实现延时,这种方式可以不占用CPU资源,但需要占用额外的硬件资源,增加系统成本和复杂度。
3、系统延时:一些单片机芯片提供了硬件延时和软件延时的组合方式,例如使用定时器和中断相结合的方式来实现精确的延时,这种方式既能够满足延时的精度要求,又能够减少CPU的占用率,提高系统的响应性能。
4、外部时钟:通过外部时钟来实现精确的延时,这种方式需要使用外部时钟电路,并配置好单片机的时钟源,可以实现高精度的延时,但同时也增加了系统的复杂度和成本。

二、软件延时举例
下面是一个简单的单片机软件延时的演示代码,以STM32为例,使用SysTick中断来实现延时:
#include "stm32f10x.h"void SysTick_Handler(void){static uint32_t ticks = 0;ticks++;    // 计数器加1}void delay_ms(uint32_t ms){uint32_t ticks = 0;ticks = ms * SystemCoreClock / 1000;    // 计算延时的时钟周期数SysTick->CTRL = 0;    // 关闭SysTick定时器SysTick->LOAD = ticks - 1;    // 设置定时器的重装载值SysTick->VAL = 0;    // 清空定时器的计数器SysTick->CTRL = 0x00000005;    // 开启SysTick定时器,使用CPU时钟源while(!(SysTick->CTRL & 0x00010000));    // 等待延时结束}int main(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    // 使能GPIOC时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);    // 初始化PC13引脚为推挽输出模式while(1){GPIO_SetBits(GPIOC, GPIO_Pin_13);    // PC13输出高电平delay_ms(1000);    // 延时1秒GPIO_ResetBits(GPIOC, GPIO_Pin_13);    // PC13输出低电平delay_ms(1000);    // 延时1秒}}
上述代码中,delay_ms()函数使用SysTick定时器实现了精确的延时,可以实现LED灯的闪烁效果。具体来说,delay_ms()函数首先计算出延时的时钟周期数,然后关闭SysTick定时器,设置定时器的重装载值,清空计数器,最后开启定时器,等待延时结束。使用SysTick定时器可以实现精确的延时,同时不会占用CPU的资源。
三、硬件延时的举例
下面是一个单片机系统硬件延时的举例,以STM32为例,使用定时器来实现延时:
#include "stm32f10x.h"void delay_us(uint32_t us){TIM_Cmd(TIM3, DISABLE);    // 关闭TIM3定时器TIM_SetCounter(TIM3, 0);    // 清空计数器TIM_SetAutoreload(TIM3, us - 1);    // 设置重装载值TIM_Cmd(TIM3, ENABLE);    // 开启TIM3定时器while(TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) == RESET);    // 等待计数器溢出TIM_ClearFlag(TIM3, TIM_FLAG_Update);    // 清除计数器溢出标志}int main(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    // 使能TIM3时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_TimeBaseStructure.TIM_Period = 65535;    // 设置定时器周期为65535TIM_TimeBaseStructure.TIM_Prescaler = 71;    // 设置预分频系数为72-1TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;    // 设置时钟分割为1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    // 设置计数器为向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);    // 初始化TIM3定时器GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    // 使能GPIOC时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);    // 初始化PC13引脚为推挽输出模式while(1){GPIO_SetBits(GPIOC, GPIO_Pin_13);    // PC13输出高电平delay_us(1000000);    // 延时1秒GPIO_ResetBits(GPIOC, GPIO_Pin_13);    // PC13输出低电平delay_us(1000000);    // 延时1秒}}
上述代码中,delay_us()函数使用TIM3定时器实现了硬件延时,可以实现LED灯的闪烁效果。具体来说,delay_us()函数首先关闭TIM3定时器,然后清空计数器,设置重装载值,开启定时器,等待计数器溢出,最后清除计数器溢出标志。使用定时器可以实现高精度的延时,同时不会占用CPU的资源。
四、阻塞式延时和非阻塞式延时的区别
阻塞式延时和非阻塞式延时是两种不同的延时方式,主要区别在于是否会阻塞程序的执行。
阻塞式延时是指程序在执行延时函数时会一直等待,直到延时结束后才会继续执行下一条指令。在延时期间,程序无法执行其他任务。例如,以下代码是一个阻塞式延时的例子:
void delay_ms(uint32_t ms){uint32_t i, j;for(i = 0; i < ms; i++){for(j = 0; j < 7200; j++);    // 延时1毫秒}}
在上述代码中,程序在执行延时函数时会一直等待,直到延时结束后才会继续执行下一条指令。如果需要延时1秒,程序会占用1秒的时间,无法执行其他任务。
非阻塞式延时是指程序在执行延时函数时可以继续执行其他任务,不会一直等待。在延时期间,程序可以执行其他任务。例如,以下代码是一个非阻塞式延时的例子:
void delay_ms(uint32_t ms){uint32_t ticks = ms * SystemCoreClock / 1000;uint32_t start = SysTick->VAL;while((SysTick->VAL - start) < ticks);}
在上述代码中,程序在执行延时函数时可以继续执行其他任务,不会一直等待。如果需要延时1秒,程序可以在延时期间执行其他任务,只有在延时结束后才会继续执行延时函数中的下一条指令。
总的来说,阻塞式延时会占用CPU的资源,无法执行其他任务,而非阻塞式延时可以让程序在执行延时函数时继续执行其他任务,提高了程序的效率。但是非阻塞式延时需要使用定时器或者其他硬件资源来实现,实现起来相对复杂一些。
---------------------
作者:王小琪
链接:https://bbs.21ic.com/icview-3293776-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

[技术讨论]关于单片机延时的实现讨论相关推荐

  1. 新书上市|当我们讨论“量子计算”时我们在讨论什么?

    请收好,这是一份<量子计算公开课>阅读指南. 量子力学是对概率法则的精彩推广:基于2-范数而不是1-范数,基于复数而不是非负实数.它可以完全独立于物理学应用而被研究(并且事实上,这样做会为 ...

  2. c语言程序 5ms 延时,计算机单片机延时方法电脑c语言.docx

    计算机单片机延时方法电脑C 语言 您需要登录后才可以回帖登录| 注册发布 单片机是一种集成电路芯片,是采用超大规模集成电路技术把 具有数据处理能力的中央处理器CPU.随机存储器RAM.只读存储器 RO ...

  3. 利用单片机延时播放孤勇者

    利用单片机延时播放孤勇者 采用的单片机为aducm4050 adi_gpio_Toggle(Port0,Pin8);函数即切换电平状态 void play_NOTE(uint32_t freq_t,f ...

  4. 谈谈51单片机延时子程序

    延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器 周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念.机器周期和指 令周期的区 ...

  5. 【四足机器人】SOLO技术详解--(4)问题讨论【翻译】

    Ⅳ. 问题讨论 1) 设计选择: 设计一个低重量的四足机器人,同时保持有效的阻抗和力控制能力需要我们将这些功能相互协调地设计.我们设计一个新型足式机器人,使用无刷直流电机进行驱动,因为它们是一种高性能 ...

  6. 《结合DDD讲清楚编写技术方案的七大维度》再讨论

    欢迎大家关注公众号「JAVA前线」查看更多精彩分享文章,主要包括源码分析.实际应用.架构思维.职场分享.产品思考等等,同时欢迎大家加我个人微信「java_front」一起交流学习 1 前文回顾 我在之 ...

  7. 【代码收藏夹 · C51】51单片机延时函数

    代码 11.0592MHz晶振 // 延时10*n微秒 void delay_10us(unsigned int n) {unsigned char i;i = 2*n;while (--i); }/ ...

  8. 计算机网络讨论4,计算机网络的创新研究讨论原稿(资料4)

    <计算机网络的创新研究讨论(原稿).doc>由会员分享,可免费在线阅读全文,更多与<计算机网络的创新研究讨论(原稿)>相关文档资源请在帮帮文库(www.woc88.com)数亿 ...

  9. 【技术分享】单片机模拟NS手柄 半自动完成太鼓达人曲目

    一.前言 1.1 项目由来 前些天,在b站上看到有人分享单片机模拟NS手柄,在<精灵宝可梦>.<异度之刃>等游戏中实现自动操作的视频.我是个有着多年"鼓龄" ...

最新文章

  1. 某高校教授要求:博士生发表论文,必须把他列为第一作者
  2. 2018阿里云云数据库RDS核心能力演进
  3. 农行计算机安全制度,制度体系之农行 数据中心计算机安全检查实施细则.doc
  4. ACM-ICPC 2018 焦作赛区网络预赛
  5. Hive _函数(系统内置函数、自定义函数、自定义UDF函数)
  6. 如何访问 SAP Screen Personas 培训系统以及完成一个最简单的例子
  7. 学习数字电路必须知道的几种编码
  8. Struts2 POI 导入导出Excel数据
  9. python调用imblearn中SMOTE踩坑
  10. DateFormat PHP Class (php 处理日期)
  11. Autodesk 3DSMax 2018 安装注册说明
  12. 时间序列预测的机器学习方法
  13. 2016年北京邮电大学计算机考研机试试题及答案
  14. 测试网速_使用Speedtest CLI测试你的网速
  15. input中加入图标实现搜索框
  16. Android Studio 按钮样式实现
  17. 网页与服务器时间不一致,js解决客户端与服务器时间不一致的问题
  18. 《无声告白》这不是我想要的生活
  19. WhatsApp群控的好处,为什么使用SendWS拓客系统实现WhatsApp耐用账号的群控管理?
  20. React-Redux 学习,转载

热门文章

  1. 数字图像处理 拉普拉斯(Laplace)变换 边缘检测算子(二阶导 sobel)变换 锐化(反锐化模板锐化) 算法实现及效果
  2. PyTorch:DistributedDataParallel(DDP)学习
  3. UTC时间与Beijing时间转换工具
  4. button控件具体用法(CommandName, CommandArgument)
  5. 几种隐藏批处理运行窗口的方法
  6. 医学图像质量评价方法SSIM
  7. 【server2019】refs数据恢复/打捞
  8. 猫狗大战——基于TensorFlow的猫狗识别(2)
  9. 游戏服务器主程白皮书-概述
  10. android SENSOR_ACCELEROMETER 三轴加速度传感器