ms和us级延时函数的实现
ms和us级延时函数的实现
2020 Sept. 8th
用sysTick实现延时
寄存器说明参考火哥(膜拜)的这篇博客:第18章 SysTick—系统定时器
- 用中断输出:
//调用core_cmX.h 里的这个函数,来配置SysTick外设
SysTick_Config(72000);#if 0 //下面是 SysTick_Config 函数的定义
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /*入口参数检测*/SysTick->LOAD = ticks - 1; //把输入的参数写到LOAD寄存器里去NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /*中断优先级配置*/SysTick->VAL = 0; //计数值归零SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | /*设置时钟源*/SysTick_CTRL_TICKINT_Msk | /*使能中断标志位*/SysTick_CTRL_ENABLE_Msk; /*使能计数器*/ return (0);
}
#endif //SysTick_Config函数的定义//这个函数达到的效果是 每1s 输出 f(CLKSOURCE)/ticks 个中断,
//即每隔 ticks/f(CLKSOURCE) s 输出一个中断。
//eg: 当 f(CLKSOURCE)=72MHz 时 (即 f(AHB)=72MHz 为时钟源时),
// 写入 ticks=72000 ,则每 1ms 输出一个中断
//ms级和us级只是ticks的写入值不同
- 不用中断输出:
//us延时
void delay_us(uint32_t i)
{SysTick->LOAD= 9*i ; //设置重装数值, 72MHz时SysTick->CTRL|=0x01; //使能,减到零时无动作,采用外部时钟源,SysTick->VAL=0x00; //清零计数器/* 注:AHB总线的时钟对F103的板子一般是72MHz嘛,然后当SysTick->CTRL的CLKSOURCE位置零时,SysTick用的时钟源时AHB时钟的8分频,这就是上面的 9*i 的原因 */uint32_t temp;do{temp=SysTick->CTRL; //读取当前状态}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达SysTick->CTRL=0x00; //关闭计数器SysTick->VAL=0x00; //清空计数器值
}//ms延时
void delay_ms(uint32_t i)
{ SysTick->LOAD= i* 9000 ; //设置重装数值, 72MHz时SysTick->CTRL|=0x01 ; //使能时钟时钟信号SysTick->VAL =0x00; //清空计数器/*注:SysTick->LOAD只有24个bit位可用,故毫秒级延时一次最多延时 0xffffff/dec9000 =1864 ms想要更长时间的延时的话,可以套娃循环延时(但有一定的累计误差存在)或者,换用TIM外设实现更长时间的精确延时*/uint32_t temp; do{temp=SysTick->CTRL; //读取当前状态}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL=0x00; //关闭计数器SysTick->VAL =0X00; //清空计数器
}
用通用定时器TIM实现延时(高级定时器、基本定时器同理)
- 中断输出:
//用于延时的TIM外设配置
//需要配置的内容有 时基 和 中断void delayTimer_Config_TIM(void)
{/*时基配置*/TIM_TimeBaseInitTypeDef timTimeBase; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);// 开启定时器时钟,即内部时钟CK_INT=72MtimTimeBase.TIM_Period=TIM_Period; // 自动重装载寄存器的值,累计 TIM_Period+1 个周期后产生一个更新或者中断timTimeBase.TIM_Prescaler= GENERAL_TIM_Prescaler; // 时钟预分频数timTimeBase.TIM_ClockDivision=TIM_CKD_DIV1; // 时钟分频因子 ,没用到不用管timTimeBase.TIM_CounterMode=TIM_CounterMode_Up; // 计数器计数模式,设置为向上计数TIM_TimeBaseInit(TIM3, &timTimeBase); // 初始化定时器/*中断配置*/NVIC_InitTypeDef initNVIC; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置中断组为0 initNVIC.NVIC_IRQChannel = GENERAL_TIM_IRQ ; // 设置中断源initNVIC.NVIC_IRQChannelPreemptionPriority = 0; // 设置主优先级为 0initNVIC.NVIC_IRQChannelSubPriority = 3; // 设置抢占优先级为3initNVIC.NVIC_IRQChannelCmd = ENABLE; //NVIC使能NVIC_Init(&initNVIC);TIM_ClearFlag(GENERAL_TIM, TIM_FLAG_Update); // 清除计数器更新中断标志位TIM_ITConfig(GENERAL_TIM,TIM_IT_Update,ENABLE); // 开启计数器中断TIM_Cmd(GENERAL_TIM, ENABLE); // 使能TIM
}
- 不用中断输出:
//用于延时的TIM外设配置
//需要配置的内容有 时基
void delayTimer_Config_TIM(void)
{TIM_TimeBaseInitTypeDef timTimeBase;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//外设使能TIM_InternalClockConfig(TIM3); //使用内部时钟源(即APB1的36MHz x2 =72MHz)TIM_TimeBaseStructInit(&timTimeBase);timTimeBase.TIM_ClockDivision = TIM_CKD_DIV1; //不分割timTimeBase.TIM_CounterMode = TIM_CounterMode_Down; //向下计数timTimeBase.TIM_Period = 72; //周期数timTimeBase.TIM_Prescaler = 1-1; //预分频数TIM_TimeBaseInit(TIM3, &timTimeBase);TIM_ClearFlag(TIM3,TIM_FLAG_Update); //清空中断标志位
}/*** 函 数 名 : delay_us* 函数功能 : 延时函数,延时us(精准延时)* 输 入 : 微秒数* 输 出 : 无*/
void delay_us(uint16_t us_cnt)
{TIM_Cmd(TIM3,ENABLE); //开启TIM3while(us_cnt--){while(TIM_GetFlagStatus(TIM3,TIM_FLAG_Update)!=SET) ; //等待TIM_ClearFlag(TIM3,TIM_FLAG_Update); //清空更新中断标志位 }TIM_Cmd(TIM3,DISABLE); //关闭TIM3
}/*** 函 数 名 : delay_ms* 函数功能 : 延时函数,延时ms* 输 入 : 毫秒数* 输 出 : 无*/
void delay_ms(uint16_t ms_cnt)
{while(ms_cnt--)delay_us(1000); //套娃2333
}
ms和us级延时函数的实现相关推荐
- HAL库-us级延时函数实现
已有的HAL_Delay() __weak void HAL_Delay(__IO uint32_t Delay) {uint32_t tickstart = 0U;tickstart = HAL_G ...
- stm32实现毫秒ms微秒us级延时
stm32实现毫秒ms微秒us级延时 上一篇文章简单捋了一下32时钟初始化的过程,对systick嘀嗒定时器有了一定的了解吧 实现方法有很多种,推荐一个博客:https://blog.csdn.net ...
- 20140627-STM8L101F3P6关于毫秒级延时函数不同写法的波形
总结一下STM8L101F3P6工作在16MHz下,利用死循环.中断等不同写法的微秒级延时函数精度的情况. 一.死循环空指令的写法,延时函数程序如下: /*********************** ...
- 20140627-STM8L101F3P6关于微秒级延时函数不同写法的波形
总结一下STM8L101F3P6工作在16MHz下,利用死循环.中断等不同写法的微秒级延时函数精度的情况. 一.死循环空指令的写法,延时函数程序如下: /*********************** ...
- 嵌入式开发(7)系统定时器(SysTick)之延时函数运用
目录 一.系统定时器 1. 简介 2.工作原理 3.频率的概念 二.库函数SysTick定时器操作 系统定时器配置 三.寄存器SysTick定时器操作 1.系统定时器的用途 2.寄存器 3.官方示例 ...
- 51c语言延时作用,51单片机C语言延时函数怎么定义和使用
描述 51单片机C语言延时函数怎么定义 C语言定义延时函数主要通过无意义指令的执行来达到延时的目的.C程序中可使用不同类型的变量来进行延时设计.经实验测试,使用unsigned char类型具有比un ...
- stm32延时us寄存器_STM32延时函数的四种方法
关注.星标公众号,不错过精彩内容 单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms().本文基于STM32F207介绍4种不同方式实现的延时函数. ...
- avr-gcc中关于delay延时函数的应用修改版[ourdev]
在51中我们的延时函数都是自己编写的,无论是在汇编中还是在C言语中.虽然有模板,有时还是有点烦.呵呵.不过在应用avr 单片机的时候我们就有福了.因为avr-gcc 提供给我们很方便的delay 延时 ...
- iar stm32_STM32延时函数的四种方法
关注.星标公众号,不错过精彩内容 单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms().本文基于STM32F207介绍4种不同方式实现的延时函数. ...
最新文章
- oracle中lock和latch的用途
- OC 实例变量(instance var)与属性(@property)的关系 isa指针
- Aroma's Search(暴力)
- CSS开发过程中的20个快速提升技巧
- linux 设置ssh免密登录
- java doget 返回json_HttpClient调用doGet、doPost、JSON传参及获得返回值
- kubernetes1.4新特性:支持两种新的卷插件
- Atitit 财政支出减少之道---------蹭银行与金融机构的补贴之道
- 在Sun Java System Web Server上使用Quercus运行PHP
- IE浏览器9.0与王码五笔不兼容的问题
- 考华为认证需要准备什么
- java 打印request的原始请求数据
- log4j输出日志级别控制
- spring5简单整理
- linux根目录不足,追加空间到根目录
- 用jQuery实现复选框全选、反选与获取选中的复选框的值
- 手机摄像头当电脑摄像头的软件
- 安史之乱后大唐是怎样一步步衰败的
- 秀一款 Python 轻量级搜索工具 -- Whoosh
- 基于 PyTorch 的 cifar-10 图像分类