STM32 自定义延时函数

发布者:清新生活最新更新时间:2022-06-17 来源: eefocus关键字:STM32  自定义  延时函数 手机看文章 扫描二维码
随时随地手机看文章

在stm32调试过程中加入一个延时,有两种方式:一种是纯计数方式,另一种是使用系统计数器的方式。


现使用系统计数器产生中断的方式实现,查阅STM32的编程手册可知,STM32有一个24bit的系统计时器,并有STK_CTRL、STK_LOAD、STK_VAL、STK_CALIB寄存器供读写配置。



而CORTEX_M3有提供了一些函数可以供我们调用来控制这几个寄存器。


在编写延时函数时需要的库函数:



/**

  brief   System Tick Configuration

  details Initializes the System Timer and its interrupt, and starts the System Tick Timer.

           Counter is in free running mode to generate periodic interrupts.

  param [in]  ticks  Number of ticks between two interrupts.

  return          0  Function succeeded.

  return          1  Function failed.

  note    When the variable __Vendor_SysTickConfig is set to 1, then the

           function SysTick_Config is not included. In this case, the file device.h

           must contain a vendor-specific implementation of this function.

 */

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)

{

  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)

  {

    return (1UL);                                                   /* Reload value impossible */

  }

 

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */

  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */

  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */

  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |

                   SysTick_CTRL_TICKINT_Msk   |

                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */

  return (0UL);                                                     /* Function successful */

}

它将延时计数写入LOAD寄存器,设置时钟源为AHB并启动计数器。



如果我们使用的系统时钟为72MHz,那么如果ticks的值设置为72,000,000,则完成一个计数周期为1s,那么如果ticks值为72,000则计数周期为1ms,ticks值为72则计数周期为1us。


在计数器运行的过程中,每次计数都会产生一个系统中断,如果我们在中断中进行计数,就可以得到一个“准确”的延时了。


源码如下:


volatile unsigned long time_delay; // 延时时间,注意定义为全局变量,并且要在中断中做自减

 

 


/*********************************************************************************************

函 数 名: delay_ms

实现功能: 延时一定的毫秒数 

输入参数: volatile unsigned long nms: 延时的毫秒数

  

输出参数: 无;

返 回 值: 0 发送成功, 

          其他  发送失败;

说    明: 无;

*********************************************************************************************/

void delay_ms(volatile unsigned long nms)

{

//设置计数器  若失败则返回1

if (SysTick_Config(SYS_FREQ/1000))

{

while (1)

{

printf("delay_ms init errorn");

}

  

}

time_delay=nms;//读取定时时间

while(time_delay);

SysTick->CTRL=0x00; //关闭计数器

    SysTick->VAL =0X00; //清空计数器

}

/*********************************************************************************************

函 数 名: delay_us

实现功能: 延时一定的微秒数 

输入参数: volatile unsigned long nus: 延时的微秒数

  

输出参数: 无;

返 回 值: 0 发送成功, 

          其他  发送失败;

说    明: 无;

*********************************************************************************************/

void delay_us(volatile unsigned long nus)

{

//设置计数器  若失败则返回1

if (SysTick_Config(SYS_FREQ/1000000))

{

while (1)

{

printf("delay_us init errorn");

}

}

time_delay=nus;//读取定时时间

while(time_delay);

SysTick->CTRL=0x00; //关闭计数器

SysTick->VAL =0X00; //清空计数器

 

extern __IO unsigned long time_delay; // 延时时间,注意定义为全局变量,并且要在中断中做自减

void SysTick_Handler(void)

{

if(time_delay > 0)

{

time_delay--;

}

}


需要注意的是,SysTick_Config()函数的使用需要调用core_cm3.h,而单独包含 core_cm3.h则会产生error:#20:identifier"IRQn_Type"isundefined 错误,这是因为数据类型RQn_Type是在stm32f10x.h中声明的,而core_cm3.h并没有进行包含,所以我们应用程序需要在包含core_cm3.h之前包含stm32f10x.h才可以。

关键字:STM32  自定义  延时函数 引用地址:STM32 自定义延时函数

上一篇:stm32的启动文件--startup_stm32f10x_hd.s
下一篇:STM32 HAL库 硬件I2C 从机主机防BUG程序

推荐阅读最新更新时间:2024-11-09 10:55

一文解析STM32启动流程
可执行程序 - cpu执行第一条用户代码 这个流程中着重讲述的是 HEX 文件如何被烧写到 STM32 内部的指定地址处。(烧写到 STM32 中的可执行文件不仅只有 HEX 格式,还有 axf、bin。针对不同格式的可执行文件,用不同的工具进行烧写)。 而本篇文章将要详细地描述一个流程: cpu执行第一条用户代码 - 调用 __main 函数- __rt_entry - main函数 这里需要注意一下,__main 是 c 库中的一个函数,和 main 函数是有区别的!!! 启动文件内容描述 上图中的汇编关键字最好记住,因为比较常用。 在此基础上,我们继续深入一点。 DCD指令 STM32 启动文件中使用 DCD 指令的
[单片机]
一文解析<font color='red'>STM32</font>启动流程
STM32 SysTick中断使用方法
SysTick中断属于核内外设中断器,中断号为-1。想要使用SysTick中断,只需在SysTick查询定时上进行稍微的修改。需要添加开启中断,直接用中断函数对计数标志位进行清零,不再使用查询方式判断计数是否结束去清零。中断函数接口SysTick_Handler在汇编文件中已经给出定义,直接到文件中查找即可。 本来NVIC提供了中断使能的函数,但是要求中断号要大于0(Value cannot be negative.),所以就不能调用NVIC中断使能函数了,直接在操作寄存器开启中断就可以了。 修改如下: #include delay.h #include led.h void Systick_Delayus
[单片机]
<font color='red'>STM32</font> SysTick中断使用方法
玩转STM32(12)代码存储空间的选择
前面了解了CPU怎么样拥有跳动的心脏,那么它拥有了开启自动化执行的生命之路。如果学习过CPU原理之类的硬件,就知道CPU在每一个脉冲信号之下,就向前运行一步,像168MHz频率的CPU,运行一步是很短的时间。不过CPU运行的原理是很简单的,可以设想纸带上有一些图案,比如圆、三角形、四边形,当这张纸带经过一个机器时,碰到圆就加一,碰到三角形就减一,碰到四边形就输出当前计数,这样简单的机器就是一个计算机所做的事情了。同理,前面CPU运行频率,就是让纸带经过机器的速度,如果频率越高,纸带的速度就快,CPU处理的事情就越多。从这里可以看到,CPU要工作起来,刚刚有运行部件还不行,还得有纸带,纸带上面还得有符号。那么在STM32里,什么是纸
[单片机]
玩转<font color='red'>STM32</font>(12)代码存储空间的选择
STC12C5A60S2使用NRF24L01和stm32通信
/******************************************/ // // 该程序工作的主频是12MHz,单片机使用STC12C5A60S2 // /******************************************/ #include STC12C5A60S2.H #define uchar unsigned char #define uint unsigned int /********** NRF24L01寄存器操作命令 ***********/ #define READ_REG 0x00 //读配置寄存器,低5位为寄存器地址 #define WRITE_REG
[单片机]
STM32串口通信过程详解
按照数据传送方向分类: 单工:数据传输只支持数据在一个方向上传输; 半双工:允许数据在两个方向上传输。但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;它不需要独立的接收端和发送端,两者可以合并一起使用一个端口; 全双工:允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,需要独立的接收端和发送端。 分别如下图中的a、b、c所示: 按照通信方式分类: 同步通信:带时钟同步信号传输。比如:SPI,IIC通信接口; 异步通信:不带时钟同步信号。比如:UART(通用异步收发器),单总线; 在同步通讯中,收发设备上方会使用一根信号线传输信号,在时钟信号的驱动下双方进行协调,同步数
[单片机]
<font color='red'>STM32</font>串口通信过程详解
STM32入门-时钟篇
STM32中使用任何一个外设都必须打开相应的时钟。在STM32中有5个时钟源可供用户选择: 1.HSI高速内部时钟,RC震荡器,频率为8MHz。 2.HSE高速外部时钟,右英/陶瓷谐振器,或着外部时钟源,4MHz-16MHz. 3.LSI内部低速时钟,RC震荡器频率为40Hz。 4.LSE外部低速时钟,接频率为32.768KHz的石英晶体。 5.PLL锁相环频输出,时钟源可选为HIS/2、HSE或HSE/2。倍频可选2-16倍,但其输出频率最大不能超过72MHz。 系统时钟SYSCLK,它是供STM32中绝大部分器件工作的时钟源,系统时钟可选择为PLL输出、HSI或者HSE。系统时钟的做大频率为72MHz,它通过AHB分频器分频后
[单片机]
STM32系列MCU,写寄存器Or利用固件库
写在开头的话: 最近心血来潮,打算重新捡起老本行,结果发现很多都忘记了。干脆重新开始学习,并做个从零开始的笔记了。 STM32系列MCU STM32系列芯片包括F0/F1/F2/F3/F4/F7/L0/L1/L4/H7等系列芯片芯片。不同系列的芯片适用于不同的应用场景。F0/L0基于ARM Cortex®-M0,F1/F2/L1系列基于ARM Cortex®-M3,F3/F4/L4系列基于ARM Cortex®-M4,F7/H7基于ARM Cortex®-M7。L系列表示超低功耗,H表示超高性能(对应就是高功耗了),F就是个折中方案了,性能不错,功耗也不高。 其他的先不管,F1系列芯片主要分类如下: ·超值型STM32F100
[单片机]
<font color='red'>STM32</font>系列MCU,写寄存器Or利用固件库
STM32驱动FLASH(W25Q128)
1、W25Q128 是华邦公司推出的一款 SPI 接口的 NOR Flash 芯片,其存储空间为 128Mbit,相当于 16M 字节。 W25Q128 可以支持 SPI 的模式 0 和模式 3,也就是 CPOL=0/CPHA=0 和CPOL=1/CPHA=1 这两种模式。 2、写入数据时,需要注意以下两个重要问题: ①、Flash 写入数据时和 EEPROM 类似,不能跨页写入,一次最多写入一页,W25Q128的一页是 256 字节。 写入数据一旦跨页,必须在写满上一页的时候,等待 Flash 将数据从缓存搬移到非易失区,重新再次往里写。 ②、Flash 有一个特点,就是可以将 1 写成 0,但是不能将 0 写成 1,要想将 0
[单片机]
<font color='red'>STM32</font>驱动FLASH(W25Q128)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved