完美解决STM32F407ZGT6使用Systic定时器实现延时_stm32f407 标准库使用systick 1ms中断实现us延时

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取


*/

/* Includes ------------------------------------------------------------------*/
#include “Delay.h”

/* Private typedef -----------------------------------------------------------/
/
Private define ------------------------------------------------------------/
/
Private macro -------------------------------------------------------------/
/
Private variables ---------------------------------------------------------*/

u8 per_us; //每1us定时器节拍
u32 per_ms; //每1ms节拍,注意168MHz下值为168000,需要32位,移植自STM32F0,此处谨慎

/* Private function prototypes -----------------------------------------------/
/
Private functions ---------------------------------------------------------*/

/**

  • @brief 延时系统初始化.

  • @param None.

  • @retval None
    /
    void Delay_Init()
    {
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);
    //这里有个问题,本想自动化获取时钟频率的,不料在该函数中有如下声明
    /

    HSE_VALUE is a constant defined in stm32f4xx.h file (default value

  •            25 MHz), user has to ensure that HSE_VALUE is same as the real
    
  •            frequency of the crystal used. Otherwise, this function may
    
  •            have wrong result.
    

    */
    //也就是后来测试时发现延时总是为输入的3倍左右
    //后修改了库文件,可参看对应目录的readme文件获取修改记录
    if(SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000)) //1ms一次中断
    while(1);

    per_ms=SysTick->LOAD; //每1ms节拍,亦即重载值
    per_us=per_ms/1000; //每1us定时器节拍

}

/**

  • @brief 微秒延时.
  • @param 延时的微秒数,约定范围1~390,“禁止其他值”.
  • @note 存在一定误差,主要是函数调用+部分计算.
  • @retval None
    /
    void Delay_Us(u16 us) //微秒延时
    {
    u32 ticks_old=SysTick->VAL; //前一个计数值
    u32 ticks_new; //后一个计数值
    u16 ticks_sum=0; //已经经过的节拍
    u16 ticks_delta=us
    per_us; //需要经过的节拍
    if(us>390) return; //计时不允许超过390us,超过390us请使用Delay_Us_2
    while(1)
    {
    ticks_new=SysTick->VAL;
    if(ticks_new!=ticks_old)
    {
    if(ticks_new<ticks_old)ticks_sum+=ticks_old-ticks_new; //这里注意一下SYSTICK是一个递减的计数器就可以了.
    else ticks_sum+=per_ms-ticks_new+ticks_old;
    ticks_old=ticks_new;
    if(ticks_sum>=ticks_delta)break; //时间超过/等于要延迟的时间,则退出.
    }
    }
    }

/**

  • @brief 毫秒延时.
  • @param 延时的毫秒数,约定范围1~25000,“禁止其他值”.
  • @note 存在一定误差,主要是函数调用+部分计算.
  • @retval None
    /
    void Delay_Ms(u16 ms) //毫秒延时
    {
    u32 ticks_old=SysTick->VAL; //前一个计数值
    u32 ticks_new; //后一个计数值
    u32 ticks_sum=0; //已经经过的节拍
    u32 ticks_delta=ms
    per_ms; //需要经过的节拍
    if(ms>25000) return; //计时不允许超过25000ms,超过25000ms请多次使用
    while(1)
    {
    ticks_new=SysTick->VAL;
    if(ticks_new!=ticks_old)
    {
    if(ticks_new<ticks_old)ticks_sum+=ticks_old-ticks_new; //这里注意一下SYSTICK是一个递减的计数器就可以了.
    else ticks_sum+=per_ms-ticks_new+ticks_old;
    ticks_old=ticks_new;
    if(ticks_sum>=ticks_delta)break; //时间超过/等于要延迟的时间,则退出.
    }
    }
    }

/**

  • @brief 微秒延时,范围更大.
  • @param 延时的微秒数,约定范围1~25000000,“禁止其他值”.
  • @note 存在一定误差,主要是函数调用+部分计算.
  • @retval None
    /
    void Delay_Us_2(u32 us) //微秒延时,范围更大
    {
    u32 ticks_old=SysTick->VAL; //前一个计数值
    u32 ticks_new; //后一个计数值
    u32 ticks_sum=0; //已经经过的节拍
    u32 ticks_delta=us
    per_us; //需要经过的节拍
    if(us>25000000) return; //计时不允许超过25000000us
    while(1)
    {
    ticks_new=SysTick->VAL;
    if(ticks_new!=ticks_old)
    {
    if(ticks_new<ticks_old)ticks_sum+=ticks_old-ticks_new; //这里注意一下SYSTICK是一个递减的计数器就可以了.
    else ticks_sum+=per_ms-ticks_new+ticks_old;
    ticks_old=ticks_new;
    if(ticks_sum>=ticks_delta)break; //时间超过/等于要延迟的时间,则退出.
    }
    }
    }

/**

  • @brief 系统定时器中断.
  • @param None.
  • @note 一般给OS用.
  • @retval None
    */
    void SysTick_Handler(void) //系统定时器中断
    {

}


### Led.c





/**


  • @file Led.c
  • @author 李航兵
  • @version V1.0
  • @date 14-June-2018
  • @brief 这个文档包含了Led功能相关的函数.

  • @brief 这个文件包含以下函数用于操作STM32F407ZGT6开发板的Led灯
  •       + 初始化Led
    
  •       + 开灯
    
  •       + 关灯
    
  • @verbatim
  • ===========================================================================
    ##### How to use this driver #####

    […]
    (#) 初始化Led,调用Led_Init()
    (#) 控制灯的亮灭
    (++) 开灯: Led_On
    (++) 关灯: Led_Off
    @endverbatim

  • @attention
  • © COPYRIGHT 2018 李航兵

*硬件连接:

  • Led1:PC0-VCC
    
  • Led1:PD3-VCC
    

*使用该文件后,PC0和PD3将会被占用
*


*/

/* Includes ------------------------------------------------------------------*/
#include “Led.h”

/* Private typedef -----------------------------------------------------------/
/
Private define ------------------------------------------------------------/
/
Private macro -------------------------------------------------------------/
/
Private variables ---------------------------------------------------------/
/
Private function prototypes -----------------------------------------------/
/
Private functions ---------------------------------------------------------*/

/**

  • @brief Led初始化.

  • @note PC0和PD3将会被占用

  • @note 调用此函数会开启GPIOC和启GPIOD时钟.

  • @param None

  • @retval None
    */
    void Led_Init() //Led初始化
    {
    GPIO_InitTypeDef GPIO_Led;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);

    GPIO_Led.GPIO_Mode=GPIO_Mode_OUT;
    GPIO_Led.GPIO_OType=GPIO_OType_PP;
    GPIO_Led.GPIO_Pin=GPIO_Pin_0;
    GPIO_Led.GPIO_PuPd=GPIO_PuPd_NOPULL;
    GPIO_Led.GPIO_Speed=GPIO_High_Speed;

    GPIO_Init(GPIOC,&GPIO_Led);

    GPIO_Led.GPIO_Pin=GPIO_Pin_3;

    GPIO_Init(GPIOD,&GPIO_Led);

    Led_Off(1);
    Led_Off(2);
    }

/**

  • @brief 开灯.
  • @note
  • @param led:Led的编号,可取1、2
  • @retval None
    */
    void Led_On(u8 led) //开灯
    {
    switch(led)
    {
    case 1:
    GPIO_ResetBits(GPIOC,GPIO_Pin_0);
    break;
    case 2:
    GPIO_ResetBits(GPIOD,GPIO_Pin_3);
    break;
    }
    }

/**

  • @brief 关灯.
  • @note
  • @param led:Led的编号,可取1、2
  • @retval None
    */
    void Led_Off(u8 led) //关灯
    {
    switch(led)
    {
    case 1:
    GPIO_SetBits(GPIOC,GPIO_Pin_0);
    break;
    case 2:
    GPIO_SetBits(GPIOD,GPIO_Pin_3);
    break;
    }
    }

/************************ © COPYRIGHT 李航兵 *END OF FILE/


### Delay\_Test.c



#include “Delay.h”
#include “Led.h”

void main()
{
int i;
Led_Init();
Delay_Init();
while(1)
{
Led_On(1);
for(i=0;i<1000;i++)
Delay_Us(300);
Led_Off(1);
Delay_Ms(1000);
Led_On(2);
Delay_Us_2(1000000);
Led_Off(2);
Delay_Ms(1000);
}
}

//void main()
//{
// int i;
// Led_Init();
// Delay_Init();
// while(1)
// {
// Led_Off(1);
// for(i=0;i<1000;i++)
// {
// Delay_Us(300);
// Delay_Us(300);
// Delay_Us(300);
// Delay_Us(100);
// }
// Led_On(1);
//
// for(i=0;i<1000;i++)
// {
// Delay_Us(300);
// Delay_Us(300);
// Delay_Us(300);
// Delay_Us(100);
// }
// }
//}

//void main()
//{
// int i;
// Led_Init();
// Delay_Init();
// while(1)
// {
// Led_Off(1);
// Delay_Ms(1000);
// Led_On(1);
//
// Delay_Ms(1000);
// }
//}

stm32f4xx.h 
   
    这里修改的地方前面已经说明 

## 结果分析


        经过测试,延时1s的时间基本准确

        
 


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/8c85a17464665ae401a1a2a94c21fa27.png)
![img](https://img-blog.csdnimg.cn/img_convert/c060fd749a5b8f58d838b32f7f59a787.png)

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

2f4xx.h 
   
    这里修改的地方前面已经说明 

## 结果分析


        经过测试,延时1s的时间基本准确

        
 


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
[外链图片转存中...(img-ZHWNLX7Z-1715715615870)]
[外链图片转存中...(img-rq0l1tPD-1715715615870)]

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值