STM32实现精准us级延时

这篇具有很好参考价值的文章主要介绍了STM32实现精准us级延时。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在上一篇文章已经讲了使用通用定时器的方式实现ms和s级别的延时,为什么没有us级别的呢,因为在示波器测量时,没有计算好程序执行的时间。这次找到了方法,测试出通用定时器延时的精准性。
同时,也查找了网上常用的使用系统定时器非中断的方式进行us级延时的方式进行对比,可以在下面测试数据查看精准度。

程序逻辑

  1. 与上一章的使用通用定时器实现ms级延时执行逻辑相同,根据公式((arr+1)*(psc+1))/Tclk,计算定时器的定时时间,当Tclk为72MHz,arr=71,psc=0时,定时时间刚好是1us。
  2. 但是这个1us到底准不准,需要考虑:
    ①因为电平转换代码执行需要时间,延时函数执行也需要时间,定时器服务程序中的子程序执行也需要时间。花了很长时间测试了,电平转换代码和延时函数的执行时间搞定了,但是定时器服务子程序的执行时间没法算出来。而这些时间会影响us的测试结果。
    ②于是才想出了新的办法。测试1us的延时时间和2us的延时时间,用2us延时程序执行时间-1us延时程序执行时间就能得出延时的时间是否准确。

测试数据

  1. 延时2us函数程序执行时间
    stm32 us延时,STM32,stm32,单片机,嵌入式硬件

  2. 延时1us函数程序执行时间
    stm32 us延时,STM32,stm32,单片机,嵌入式硬件

  3. 经过测试,延时1us时,一个电平周期执行时间16.08us,延时2us时,一个电平的执行周期是18.08us,因为一个电平周期里延时两次,(18.08-16.08)/2=1us。所以通过示波器实测,us级的延时是相当准确的。

  4. 为了作对比,查找了在网上常用的,使用系统定时器非中断的方式进行us级延时的程序作对比。
    通过示波器测试,延时1us时,一个电平周期执行时间16.08us,延时2us时,一个电平的执行周期是18.00us,
    因为一个电平周期里延时两次,(18.00-16.08)/2=0.96us,所以结果也相对准确。

  5. 同时为了测试波形的稳定性和误差,分别对 通用定时器中断服务程序计数延时的方式系统定时器非中断延时方式 采集了三组数据。
    ①通用定时器中断服务程序计数延时
    stm32 us延时,STM32,stm32,单片机,嵌入式硬件
    ②系统定时器非中断延时
    stm32 us延时,STM32,stm32,单片机,嵌入式硬件
    这样对比起来通用定时器中断服务程序计数延时的方式会更加稳定一些,不过视不同的使用场景还需要综合考虑。文章来源地址https://www.toymoban.com/news/detail-708858.html

代码示例

  1. 通用定时器中断服务程序计数延时方式
#include "stm32f10x.h"

uint32_t TimingDelay;	//定义进入中断服务程序次数

/*初始化LED灯*/
void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	//开启外设时钟
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_15);	//先熄灭LED
}

/*LED灯状态转换*/
void LED1_Turn(void)
{
	if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_15) == 0)
	{
		GPIO_SetBits(GPIOB, GPIO_Pin_15);
	}
	else
	{
		GPIO_ResetBits(GPIOB, GPIO_Pin_15);
	}
}

//延时函数
void Delay(uint32_t nTime)
{ 
	//也就是延时时间=进入定时器的次数*定时器每次进入中断的时间
	TimingDelay = nTime;
	while(TimingDelay != 0);
}

//通用定时器3配置
void TIM3_Init(u16 arr,u16 psc)
{
	//结构体初始化
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure; 
	
	//分配时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	//初始化定时器的相关配置
	TIM_TimeBaseStructure.TIM_Period = arr;		//重装载的值
	TIM_TimeBaseStructure.TIM_Prescaler = psc;	//分频系数
	
	//TIM_ClockDivision 是设置与进行输入捕获相关的分频
	//设置这个值不会影响定时器的时钟频率,我们一般设置为TIM_CKD_DIV1,也就是不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	  													
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;	  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;	
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	//设置 TIM3_DIER  允许更新中断
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

	//打开定时器
	TIM_Cmd(TIM3,ENABLE);
}

//定时器时间到了之后自动跳转到中断函数当中
void TIM3_IRQHandler(void)
{
	if ( TIM_GetITStatus(TIM3 , TIM_IT_Update) != RESET ) 
	{
		TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);    
		//这里的TimingDelay相当于计时次数,计算进入定时器的次数
		if(TimingDelay!=0x00){TimingDelay--;}
	}		 	
}



int main(void)
{
	/*这里定时器进入中断的时间是1us*/
	TIM3_Init(71,0);	//初始化定时器 
	LED_Init();
	
	while(1){
		LED1_Turn();
		Delay(1);			//延时1us
	}
}
  1. 系统定时器非中断延时方式
//仿原子延时,不进入systic中断
void delay_us(u32 nus)
{
 u32 temp;
 SysTick->LOAD = 9*nus;
 SysTick->VAL=0X00;//清空计数器
 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
 do
 {
  temp=SysTick->CTRL;//读取当前倒计数值
 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
     SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}
void delay_ms(u16 nms)
{
 u32 temp;
 SysTick->LOAD = 9000*nms;
 SysTick->VAL=0X00;//清空计数器
 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
 do
 {
  temp=SysTick->CTRL;//读取当前倒计数值
 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
    SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}

到了这里,关于STM32实现精准us级延时的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stm32毕设分享 stm32实现车牌识别系统 -物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(60)
  • STM32单片机实现固件在线升级(IAP)

    单片机的固件升级方式有很多种, 1、ICP:In Circuit Programing,简单说就是在单片机开发时使用烧录器升级程序,比如使用J-Link烧录单片机程序。 2、ISP:In System Programing,在单片机内部实现了基于通信接口(如串口、I2C、SPI等等)的FLASH引导程序,配合厂家提供的烧录软件工具

    2024年02月13日
    浏览(52)
  • 【单片机毕设选题】stm32实现车牌识别系统 -物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(55)
  • STM32单片机LED显示屏驱动原理与实现

    STM32单片机驱动LED显示屏的原理与实现方法与Arduino类似,但涉及到的具体硬件资源和库函数可能会有所不同。下面是一个详细的介绍:   原理: STM32单片机驱动LED显示屏的原理是通过控制GPIO引脚的电平状态来控制LED的亮灭。通过设置引脚的输出电平为高电平(VCC)或低电平

    2024年02月10日
    浏览(49)
  • 单片机项目分享 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月21日
    浏览(90)
  • stm32毕设分享 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月21日
    浏览(84)
  • 毕业设计 单片机心率检测器设计与实现 - stm32

    Hi,大家好,今天向大家介绍一个学长做的单片机项目 基于STM32的心率检测器的设计与实现 大家可用于 课程设计 或 毕业设计 主控:STM32F103C8T6 MAX30102传感器 OLED屏幕:用于显示实时心率波形 未测试时的状态:心率波形显为平稳直线,即0 将手指放上进行心率测试: 还可以把

    2024年02月07日
    浏览(42)
  • 单片机设计基于STM32的心率检测仪设计与实现

      现代科学的发展,导致越来越多人开始重视自己的身体健康,他们往往会想在能力之余使用健身运动等方式来锻炼自身。你会发现,在健身房,健身达人或者是教练都会叮嘱新手去关注自己的心率节奏。一般来说,人的激烈的锻炼会造成心脏血压的上升,心率变化从而加

    2024年02月04日
    浏览(57)
  • 单片机毕设 基于STM32的智能药箱系统设计与实现

    Hi,大家好,今天向大家介绍一个学长做的单片机项目 基于STM32的智能药箱系统设计与实现 大家可用于 课程设计 或 毕业设计 照顾老人, 特别是提醒老人准时吃药已经成为了一个社会关心的问题。长期记录吃药种类、 吃药时间能为分析老人的病理提供有力的依据。 基于目

    2024年02月04日
    浏览(72)
  • 单片机(STM32,GD32,NXP等)中BootLoader的严谨实现详解

    Bootloader( 引导加载程序 )的主要任务是引导加载并运行应用程序,我们的软件升级逻辑也一般在BootLoader中实现。本文将详细介绍BootLoader在单片机中的实现,包括 STM32、GD32、NXP Kinetis 等等的所有单片机,因为无论是什么样的芯片,它实现的逻辑都是一样的。 注意,本篇文章主

    2024年02月02日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包